@sonordev/site-kit 4.2.2 → 4.2.3

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 (213) hide show
  1. package/agent-manifest.json +1 -1
  2. package/dist/AnalyticsProvider-NW3UZYL5.mjs +10 -0
  3. package/dist/{AnalyticsProvider-EQSG7FGL.mjs.map → AnalyticsProvider-NW3UZYL5.mjs.map} +1 -1
  4. package/dist/AnalyticsProvider-VSTTYP4W.js +31 -0
  5. package/dist/{AnalyticsProvider-4BQIFRWP.js.map → AnalyticsProvider-VSTTYP4W.js.map} +1 -1
  6. package/dist/ChatWidget-BJOE2OSI.js +20 -0
  7. package/dist/{ChatWidget-EXJD6YVW.js.map → ChatWidget-BJOE2OSI.js.map} +1 -1
  8. package/dist/ChatWidget-EWQ7LRD4.mjs +11 -0
  9. package/dist/{ChatWidget-ZTKWIKXR.mjs.map → ChatWidget-EWQ7LRD4.mjs.map} +1 -1
  10. package/dist/EngageWidget-CZMNLFWI.js +18 -0
  11. package/dist/{EngageWidget-HY523XM4.js.map → EngageWidget-CZMNLFWI.js.map} +1 -1
  12. package/dist/EngageWidget-F427CI6Y.mjs +9 -0
  13. package/dist/{EngageWidget-BJLSXG2V.mjs.map → EngageWidget-F427CI6Y.mjs.map} +1 -1
  14. package/dist/{FileField-5U4FYTLN.mjs → FileField-5RVBU3Z4.mjs} +5 -5
  15. package/dist/{FileField-5U4FYTLN.mjs.map → FileField-5RVBU3Z4.mjs.map} +1 -1
  16. package/dist/{FileField-FV46FKRM.js → FileField-Y4ZA7DST.js} +6 -6
  17. package/dist/{FileField-FV46FKRM.js.map → FileField-Y4ZA7DST.js.map} +1 -1
  18. package/dist/{FormSpotlight-W6BNVKNN.mjs → FormSpotlight-CJPI2MRJ.mjs} +3 -3
  19. package/dist/{FormSpotlight-W6BNVKNN.mjs.map → FormSpotlight-CJPI2MRJ.mjs.map} +1 -1
  20. package/dist/{FormSpotlight-TUHLSY3O.js → FormSpotlight-MAEV6SZK.js} +15 -15
  21. package/dist/{FormSpotlight-TUHLSY3O.js.map → FormSpotlight-MAEV6SZK.js.map} +1 -1
  22. package/dist/{FormStage-MNXNKSPP.js → FormStage-D42NAHSN.js} +13 -13
  23. package/dist/{FormStage-MNXNKSPP.js.map → FormStage-D42NAHSN.js.map} +1 -1
  24. package/dist/{FormStage-NKWP3C2S.mjs → FormStage-Z7WW3DNA.mjs} +3 -3
  25. package/dist/{FormStage-NKWP3C2S.mjs.map → FormStage-Z7WW3DNA.mjs.map} +1 -1
  26. package/dist/ManagedForm-A7BROQIN.mjs +14 -0
  27. package/dist/{ManagedForm-M3XW66FH.mjs.map → ManagedForm-A7BROQIN.mjs.map} +1 -1
  28. package/dist/ManagedForm-Z3Z5Z6OL.js +23 -0
  29. package/dist/{ManagedForm-K4UHRVYV.js.map → ManagedForm-Z3Z5Z6OL.js.map} +1 -1
  30. package/dist/{SignalCore-S6PCGTHS.mjs → SignalCore-77UH6PZ4.mjs} +5 -5
  31. package/dist/{SignalCore-S6PCGTHS.mjs.map → SignalCore-77UH6PZ4.mjs.map} +1 -1
  32. package/dist/{SignalCore-7PVCUG2S.js → SignalCore-NA6TJFVE.js} +11 -11
  33. package/dist/{SignalCore-7PVCUG2S.js.map → SignalCore-NA6TJFVE.js.map} +1 -1
  34. package/dist/SitemapSync-62F6HVAW.js +17 -0
  35. package/dist/{SitemapSync-66HQ4SG2.js.map → SitemapSync-62F6HVAW.js.map} +1 -1
  36. package/dist/SitemapSync-EY33A6P4.mjs +8 -0
  37. package/dist/{SitemapSync-2HLGUZES.mjs.map → SitemapSync-EY33A6P4.mjs.map} +1 -1
  38. package/dist/analytics/index.js +9 -9
  39. package/dist/analytics/index.mjs +4 -4
  40. package/dist/api-N5OLQXYN.js +202 -0
  41. package/dist/api-N5OLQXYN.js.map +1 -0
  42. package/dist/api-NTHZ6PAW.mjs +184 -0
  43. package/dist/api-NTHZ6PAW.mjs.map +1 -0
  44. package/dist/{chunk-F46DCSUI.js → chunk-2XRGCDDG.js} +9 -9
  45. package/dist/{chunk-F46DCSUI.js.map → chunk-2XRGCDDG.js.map} +1 -1
  46. package/dist/{chunk-UF33ENG6.js → chunk-3DSGMX7P.js} +3 -3
  47. package/dist/{chunk-UF33ENG6.js.map → chunk-3DSGMX7P.js.map} +1 -1
  48. package/dist/{chunk-SED7E3P5.mjs → chunk-3P4HJAZA.mjs} +4 -4
  49. package/dist/{chunk-SED7E3P5.mjs.map → chunk-3P4HJAZA.mjs.map} +1 -1
  50. package/dist/{chunk-W3QLA5MI.mjs → chunk-535HXGDU.mjs} +3 -3
  51. package/dist/{chunk-W3QLA5MI.mjs.map → chunk-535HXGDU.mjs.map} +1 -1
  52. package/dist/{chunk-CM5QUX2T.mjs → chunk-6D3HZKTZ.mjs} +3 -3
  53. package/dist/{chunk-CM5QUX2T.mjs.map → chunk-6D3HZKTZ.mjs.map} +1 -1
  54. package/dist/{chunk-XMZQUC2J.js → chunk-7BVZLSUJ.js} +8 -8
  55. package/dist/{chunk-XMZQUC2J.js.map → chunk-7BVZLSUJ.js.map} +1 -1
  56. package/dist/{chunk-645TOMKQ.js → chunk-BN4AL7XB.js} +4 -4
  57. package/dist/{chunk-645TOMKQ.js.map → chunk-BN4AL7XB.js.map} +1 -1
  58. package/dist/{chunk-YV2TG7JR.mjs → chunk-DZUOLOYS.mjs} +3 -3
  59. package/dist/{chunk-YV2TG7JR.mjs.map → chunk-DZUOLOYS.mjs.map} +1 -1
  60. package/dist/{chunk-SS5S43I4.mjs → chunk-EHNUPEFY.mjs} +7 -7
  61. package/dist/{chunk-SS5S43I4.mjs.map → chunk-EHNUPEFY.mjs.map} +1 -1
  62. package/dist/{chunk-L4ZLL6TE.mjs → chunk-FZAAQE4Y.mjs} +4 -4
  63. package/dist/{chunk-L4ZLL6TE.mjs.map → chunk-FZAAQE4Y.mjs.map} +1 -1
  64. package/dist/{chunk-2LU7BV5K.js → chunk-GDMOAGVS.js} +18 -18
  65. package/dist/{chunk-2LU7BV5K.js.map → chunk-GDMOAGVS.js.map} +1 -1
  66. package/dist/{chunk-LSW5QBW2.js → chunk-GJKO2TZN.js} +4 -4
  67. package/dist/{chunk-LSW5QBW2.js.map → chunk-GJKO2TZN.js.map} +1 -1
  68. package/dist/{chunk-DQO4UKFE.mjs → chunk-HTLWSCUQ.mjs} +76 -4
  69. package/dist/chunk-HTLWSCUQ.mjs.map +1 -0
  70. package/dist/{chunk-TWPLJ27S.js → chunk-HVDKAR77.js} +7 -7
  71. package/dist/{chunk-TWPLJ27S.js.map → chunk-HVDKAR77.js.map} +1 -1
  72. package/dist/{chunk-D6CPHVMV.mjs → chunk-I7ORAWYT.mjs} +3 -3
  73. package/dist/{chunk-D6CPHVMV.mjs.map → chunk-I7ORAWYT.mjs.map} +1 -1
  74. package/dist/{chunk-MOKM6STG.mjs → chunk-INA4NW3Y.mjs} +3 -3
  75. package/dist/{chunk-MOKM6STG.mjs.map → chunk-INA4NW3Y.mjs.map} +1 -1
  76. package/dist/{chunk-4E7NFYL5.mjs → chunk-J6HWSJT7.mjs} +3 -3
  77. package/dist/{chunk-4E7NFYL5.mjs.map → chunk-J6HWSJT7.mjs.map} +1 -1
  78. package/dist/{chunk-PLY5AP72.js → chunk-JJDY5XXG.js} +3 -3
  79. package/dist/{chunk-PLY5AP72.js.map → chunk-JJDY5XXG.js.map} +1 -1
  80. package/dist/{chunk-ZXVMP6SY.mjs → chunk-KL4MV6HK.mjs} +3 -3
  81. package/dist/{chunk-ZXVMP6SY.mjs.map → chunk-KL4MV6HK.mjs.map} +1 -1
  82. package/dist/{chunk-THBZCEA7.js → chunk-M2SEYO5J.js} +5 -5
  83. package/dist/{chunk-THBZCEA7.js.map → chunk-M2SEYO5J.js.map} +1 -1
  84. package/dist/{chunk-XBKNPBRB.js → chunk-MF6XLEX5.js} +15 -15
  85. package/dist/{chunk-XBKNPBRB.js.map → chunk-MF6XLEX5.js.map} +1 -1
  86. package/dist/{chunk-UEOGMRTL.js → chunk-MP7ZYKMM.js} +8 -8
  87. package/dist/{chunk-UEOGMRTL.js.map → chunk-MP7ZYKMM.js.map} +1 -1
  88. package/dist/{chunk-55FJN7VQ.js → chunk-N5RTJNMN.js} +6 -6
  89. package/dist/{chunk-55FJN7VQ.js.map → chunk-N5RTJNMN.js.map} +1 -1
  90. package/dist/{chunk-DEPDYVUH.js → chunk-NEIUWAAL.js} +5 -5
  91. package/dist/{chunk-DEPDYVUH.js.map → chunk-NEIUWAAL.js.map} +1 -1
  92. package/dist/{chunk-HYRKVST7.js → chunk-OHA43BNK.js} +14 -14
  93. package/dist/{chunk-HYRKVST7.js.map → chunk-OHA43BNK.js.map} +1 -1
  94. package/dist/{chunk-P37FFMOZ.mjs → chunk-PTZB4ES3.mjs} +8 -8
  95. package/dist/{chunk-P37FFMOZ.mjs.map → chunk-PTZB4ES3.mjs.map} +1 -1
  96. package/dist/{chunk-OB6DNGYK.js → chunk-QJK2X3UK.js} +12 -12
  97. package/dist/{chunk-OB6DNGYK.js.map → chunk-QJK2X3UK.js.map} +1 -1
  98. package/dist/{chunk-XFVI3SNM.mjs → chunk-RCRDDMUO.mjs} +3 -3
  99. package/dist/{chunk-XFVI3SNM.mjs.map → chunk-RCRDDMUO.mjs.map} +1 -1
  100. package/dist/{chunk-4MBD6PPV.js → chunk-RDISSFEH.js} +15 -15
  101. package/dist/{chunk-4MBD6PPV.js.map → chunk-RDISSFEH.js.map} +1 -1
  102. package/dist/{chunk-K7XOPTOE.mjs → chunk-RRR6Y6Y5.mjs} +4 -4
  103. package/dist/{chunk-K7XOPTOE.mjs.map → chunk-RRR6Y6Y5.mjs.map} +1 -1
  104. package/dist/chunk-S5L73KZQ.js +8 -0
  105. package/dist/{chunk-UUBW2NJZ.js.map → chunk-S5L73KZQ.js.map} +1 -1
  106. package/dist/{chunk-BUZSBUYJ.js → chunk-S5UATBC7.js} +14 -14
  107. package/dist/{chunk-BUZSBUYJ.js.map → chunk-S5UATBC7.js.map} +1 -1
  108. package/dist/{chunk-524SIFK7.js → chunk-SAR473OC.js} +12 -12
  109. package/dist/{chunk-524SIFK7.js.map → chunk-SAR473OC.js.map} +1 -1
  110. package/dist/{chunk-7723NZQW.mjs → chunk-SL6ZGJVN.mjs} +4 -4
  111. package/dist/{chunk-7723NZQW.mjs.map → chunk-SL6ZGJVN.mjs.map} +1 -1
  112. package/dist/{chunk-WARTV6ZP.mjs → chunk-T3HGONNE.mjs} +4 -4
  113. package/dist/{chunk-WARTV6ZP.mjs.map → chunk-T3HGONNE.mjs.map} +1 -1
  114. package/dist/{chunk-BEHHWRZM.mjs → chunk-T6T5IQMN.mjs} +3 -3
  115. package/dist/{chunk-BEHHWRZM.mjs.map → chunk-T6T5IQMN.mjs.map} +1 -1
  116. package/dist/{chunk-YN5WYGHK.mjs → chunk-TFAYDIWM.mjs} +3 -3
  117. package/dist/{chunk-YN5WYGHK.mjs.map → chunk-TFAYDIWM.mjs.map} +1 -1
  118. package/dist/{chunk-WHHBOYAW.mjs → chunk-TKVADZFD.mjs} +4 -4
  119. package/dist/{chunk-WHHBOYAW.mjs.map → chunk-TKVADZFD.mjs.map} +1 -1
  120. package/dist/{chunk-KJSYSRMD.mjs → chunk-UDNXM6RB.mjs} +3 -3
  121. package/dist/{chunk-KJSYSRMD.mjs.map → chunk-UDNXM6RB.mjs.map} +1 -1
  122. package/dist/{chunk-7YVFFQWH.js → chunk-WCTOQFAN.js} +14 -14
  123. package/dist/{chunk-7YVFFQWH.js.map → chunk-WCTOQFAN.js.map} +1 -1
  124. package/dist/{chunk-QQFWEHYU.js → chunk-XA7RBHKT.js} +4 -4
  125. package/dist/{chunk-QQFWEHYU.js.map → chunk-XA7RBHKT.js.map} +1 -1
  126. package/dist/chunk-XCFCG46K.mjs +6 -0
  127. package/dist/{chunk-NPCWPOCE.mjs.map → chunk-XCFCG46K.mjs.map} +1 -1
  128. package/dist/{chunk-3BXQP54K.js → chunk-XOJYGBYF.js} +3 -3
  129. package/dist/{chunk-3BXQP54K.js.map → chunk-XOJYGBYF.js.map} +1 -1
  130. package/dist/{chunk-WNK2OK5G.mjs → chunk-XR3MDDQT.mjs} +3 -3
  131. package/dist/{chunk-WNK2OK5G.mjs.map → chunk-XR3MDDQT.mjs.map} +1 -1
  132. package/dist/{chunk-4SJITKBL.mjs → chunk-XWFUQMU6.mjs} +3 -3
  133. package/dist/{chunk-4SJITKBL.mjs.map → chunk-XWFUQMU6.mjs.map} +1 -1
  134. package/dist/{chunk-UIKGLLTU.js → chunk-YWXZ4YLU.js} +4 -4
  135. package/dist/{chunk-UIKGLLTU.js.map → chunk-YWXZ4YLU.js.map} +1 -1
  136. package/dist/{chunk-2GUDSTNH.mjs → chunk-ZASFY4NR.mjs} +4 -4
  137. package/dist/{chunk-2GUDSTNH.mjs.map → chunk-ZASFY4NR.mjs.map} +1 -1
  138. package/dist/{chunk-6TAXXKMX.js → chunk-ZAVNGZJZ.js} +77 -3
  139. package/dist/chunk-ZAVNGZJZ.js.map +1 -0
  140. package/dist/cli/agent/checks.d.ts.map +1 -1
  141. package/dist/cli/commands/og.d.ts +46 -11
  142. package/dist/cli/commands/og.d.ts.map +1 -1
  143. package/dist/cli/index.js +516 -174
  144. package/dist/cli/index.js.map +1 -1
  145. package/dist/cli/index.mjs +514 -172
  146. package/dist/cli/index.mjs.map +1 -1
  147. package/dist/client/index.js +4 -4
  148. package/dist/client/index.mjs +3 -3
  149. package/dist/commerce/index.js +56 -56
  150. package/dist/commerce/index.mjs +5 -5
  151. package/dist/engage/index.js +10 -10
  152. package/dist/engage/index.mjs +7 -7
  153. package/dist/fleet/index.js +8 -8
  154. package/dist/fleet/index.mjs +4 -4
  155. package/dist/forms/index.js +16 -16
  156. package/dist/forms/index.mjs +9 -9
  157. package/dist/forms/server.js +10 -10
  158. package/dist/forms/server.mjs +8 -8
  159. package/dist/forms/static.js +7 -7
  160. package/dist/forms/static.mjs +6 -6
  161. package/dist/images/index.js +11 -11
  162. package/dist/images/index.mjs +4 -4
  163. package/dist/index.js +63 -63
  164. package/dist/index.mjs +9 -9
  165. package/dist/layout/client.js +8 -8
  166. package/dist/layout/client.mjs +7 -7
  167. package/dist/layout/index.js +10 -10
  168. package/dist/layout/index.mjs +8 -8
  169. package/dist/maps/index.js +5 -5
  170. package/dist/maps/index.mjs +3 -3
  171. package/dist/og/config.d.ts +36 -0
  172. package/dist/og/config.d.ts.map +1 -1
  173. package/dist/og/index.js +5 -5
  174. package/dist/og/index.mjs +1 -1
  175. package/dist/og/pages.d.ts +56 -0
  176. package/dist/og/pages.d.ts.map +1 -0
  177. package/dist/og/pages.test.d.ts +2 -0
  178. package/dist/og/pages.test.d.ts.map +1 -0
  179. package/dist/og/template.d.ts.map +1 -1
  180. package/dist/og/wiring.d.ts +56 -0
  181. package/dist/og/wiring.d.ts.map +1 -0
  182. package/dist/og/wiring.test.d.ts +2 -0
  183. package/dist/og/wiring.test.d.ts.map +1 -0
  184. package/dist/search/index.js +4 -4
  185. package/dist/search/index.mjs +3 -3
  186. package/dist/seo/client.js +5 -5
  187. package/dist/seo/client.mjs +4 -4
  188. package/dist/seo/index.js +5 -5
  189. package/dist/seo/index.mjs +4 -4
  190. package/dist/seo/register-sitemap-cli.js +1 -1
  191. package/dist/seo/register-sitemap-cli.mjs +1 -1
  192. package/dist/server/index.js +3 -3
  193. package/dist/server/index.mjs +2 -2
  194. package/dist/shared/version.d.ts +1 -1
  195. package/dist/signal/index.js +11 -11
  196. package/dist/signal/index.mjs +2 -2
  197. package/dist/sync/index.js +16 -16
  198. package/dist/sync/index.mjs +4 -4
  199. package/package.json +1 -1
  200. package/dist/AnalyticsProvider-4BQIFRWP.js +0 -31
  201. package/dist/AnalyticsProvider-EQSG7FGL.mjs +0 -10
  202. package/dist/ChatWidget-EXJD6YVW.js +0 -20
  203. package/dist/ChatWidget-ZTKWIKXR.mjs +0 -11
  204. package/dist/EngageWidget-BJLSXG2V.mjs +0 -9
  205. package/dist/EngageWidget-HY523XM4.js +0 -18
  206. package/dist/ManagedForm-K4UHRVYV.js +0 -23
  207. package/dist/ManagedForm-M3XW66FH.mjs +0 -14
  208. package/dist/SitemapSync-2HLGUZES.mjs +0 -8
  209. package/dist/SitemapSync-66HQ4SG2.js +0 -17
  210. package/dist/chunk-6TAXXKMX.js.map +0 -1
  211. package/dist/chunk-DQO4UKFE.mjs.map +0 -1
  212. package/dist/chunk-NPCWPOCE.mjs +0 -6
  213. package/dist/chunk-UUBW2NJZ.js +0 -8
@@ -1,9 +1,10 @@
1
1
  #!/usr/bin/env node
2
2
  import { traverse, isJSXIdentifier, isJSXAttribute, isFunctionDeclaration, isVariableDeclarator, isIdentifier, isStringLiteral, isJSXMemberExpression, isJSXExpressionContainer, isTemplateLiteral, isArrayExpression, isObjectExpression, isJSXText } from '../chunk-JOYMIGR2.mjs';
3
3
  import { parse } from '../chunk-5YA6SI4Z.mjs';
4
- import { buildOgHtml } from '../chunk-DQO4UKFE.mjs';
4
+ import { buildOgHtml, TITLE_MAX_PX, OG_REPORT_ATTR } from '../chunk-HTLWSCUQ.mjs';
5
5
  import { require_main } from '../chunk-NNZDWY3L.mjs';
6
- import { SITE_KIT_VERSION } from '../chunk-NPCWPOCE.mjs';
6
+ import { findAppDirForDiscovery, discoverNextJsRoutes } from '../chunk-XIJ4F6IE.mjs';
7
+ import { SITE_KIT_VERSION } from '../chunk-XCFCG46K.mjs';
7
8
  import { __commonJS, __require, __toESM, __export, __privateAdd, __publicField, __privateGet, __privateMethod, __privateSet, __privateWrapper } from '../chunk-BEXTDHO4.mjs';
8
9
  import { EventEmitter } from 'events';
9
10
  import childProcess, { execFile as execFile$1, execSync, spawnSync, spawn } from 'child_process';
@@ -6201,10 +6202,10 @@ var require_lib2 = __commonJS({
6201
6202
  exports.analyse = analyse;
6202
6203
  var detectFile = (filepath, opts = {}) => new Promise((resolve, reject) => {
6203
6204
  let fd;
6204
- const fs26 = (0, node_1.default)();
6205
+ const fs27 = (0, node_1.default)();
6205
6206
  const handler = (err, buffer) => {
6206
6207
  if (fd) {
6207
- fs26.closeSync(fd);
6208
+ fs27.closeSync(fd);
6208
6209
  }
6209
6210
  if (err) {
6210
6211
  reject(err);
@@ -6216,9 +6217,9 @@ var require_lib2 = __commonJS({
6216
6217
  };
6217
6218
  const sampleSize = (opts === null || opts === void 0 ? void 0 : opts.sampleSize) || 0;
6218
6219
  if (sampleSize > 0) {
6219
- fd = fs26.openSync(filepath, "r");
6220
+ fd = fs27.openSync(filepath, "r");
6220
6221
  let sample = Buffer.allocUnsafe(sampleSize);
6221
- fs26.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
6222
+ fs27.read(fd, sample, 0, sampleSize, opts.offset, (err, bytesRead) => {
6222
6223
  if (err) {
6223
6224
  handler(err, null);
6224
6225
  } else {
@@ -6230,22 +6231,22 @@ var require_lib2 = __commonJS({
6230
6231
  });
6231
6232
  return;
6232
6233
  }
6233
- fs26.readFile(filepath, handler);
6234
+ fs27.readFile(filepath, handler);
6234
6235
  });
6235
6236
  exports.detectFile = detectFile;
6236
6237
  var detectFileSync = (filepath, opts = {}) => {
6237
- const fs26 = (0, node_1.default)();
6238
+ const fs27 = (0, node_1.default)();
6238
6239
  if (opts && opts.sampleSize) {
6239
- const fd = fs26.openSync(filepath, "r");
6240
+ const fd = fs27.openSync(filepath, "r");
6240
6241
  let sample = Buffer.allocUnsafe(opts.sampleSize);
6241
- const bytesRead = fs26.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
6242
+ const bytesRead = fs27.readSync(fd, sample, 0, opts.sampleSize, opts.offset);
6242
6243
  if (bytesRead < opts.sampleSize) {
6243
6244
  sample = sample.subarray(0, bytesRead);
6244
6245
  }
6245
- fs26.closeSync(fd);
6246
+ fs27.closeSync(fd);
6246
6247
  return (0, exports.detect)(sample);
6247
6248
  }
6248
- return (0, exports.detect)(fs26.readFileSync(filepath));
6249
+ return (0, exports.detect)(fs27.readFileSync(filepath));
6249
6250
  };
6250
6251
  exports.detectFileSync = detectFileSync;
6251
6252
  exports.default = {
@@ -13235,9 +13236,9 @@ Expecting one of '${allowedValues.join("', '")}'`);
13235
13236
  * @param {string} [path]
13236
13237
  * @return {(string|null|Command)}
13237
13238
  */
13238
- executableDir(path26) {
13239
- if (path26 === void 0) return this._executableDir;
13240
- this._executableDir = path26;
13239
+ executableDir(path27) {
13240
+ if (path27 === void 0) return this._executableDir;
13241
+ this._executableDir = path27;
13241
13242
  return this;
13242
13243
  }
13243
13244
  /**
@@ -20344,9 +20345,9 @@ function observableToAsyncIterable(source) {
20344
20345
 
20345
20346
  // node_modules/.pnpm/inquirer@14.0.2_@types+node@26.2.0/node_modules/inquirer/dist/ui/prompt.js
20346
20347
  var _ = {
20347
- set: (obj, path26 = "", value) => {
20348
+ set: (obj, path27 = "", value) => {
20348
20349
  let pointer = obj;
20349
- path26.split(".").forEach((key, index, arr) => {
20350
+ path27.split(".").forEach((key, index, arr) => {
20350
20351
  if (key === "__proto__" || key === "constructor")
20351
20352
  return;
20352
20353
  if (index === arr.length - 1) {
@@ -20357,8 +20358,8 @@ var _ = {
20357
20358
  pointer = pointer[key];
20358
20359
  });
20359
20360
  },
20360
- get: (obj, path26 = "", defaultValue) => {
20361
- const travel = (regexp) => String.prototype.split.call(path26, regexp).filter(Boolean).reduce(
20361
+ get: (obj, path27 = "", defaultValue) => {
20362
+ const travel = (regexp) => String.prototype.split.call(path27, regexp).filter(Boolean).reduce(
20362
20363
  // @ts-expect-error implicit any on res[key]
20363
20364
  (res, key) => res == null ? res : res[key],
20364
20365
  obj
@@ -20715,18 +20716,18 @@ function scanForForms(ast, content, filePath) {
20715
20716
  const forms = [];
20716
20717
  content.split("\n");
20717
20718
  traverse(ast, {
20718
- JSXElement(path26) {
20719
- const opening = path26.node.openingElement;
20719
+ JSXElement(path27) {
20720
+ const opening = path27.node.openingElement;
20720
20721
  if (isJSXIdentifier(opening.name) && opening.name.name === "form") {
20721
- const fields = extractFieldsFromForm(path26);
20722
+ const fields = extractFieldsFromForm(path27);
20722
20723
  const hasOnSubmit = opening.attributes.some(
20723
20724
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "onSubmit"
20724
20725
  );
20725
20726
  if (hasOnSubmit && fields.length > 0) {
20726
- const startLine = path26.node.loc?.start.line || 0;
20727
- const endLine = path26.node.loc?.end.line || 0;
20727
+ const startLine = path27.node.loc?.start.line || 0;
20728
+ const endLine = path27.node.loc?.end.line || 0;
20728
20729
  let componentName = "UnknownForm";
20729
- let current = path26.parentPath;
20730
+ let current = path27.parentPath;
20730
20731
  while (current) {
20731
20732
  if (isFunctionDeclaration(current.node) && current.node.id) {
20732
20733
  componentName = current.node.id.name;
@@ -20759,7 +20760,7 @@ function scanForForms(ast, content, filePath) {
20759
20760
  }
20760
20761
  if (isJSXIdentifier(opening.name) && opening.name.name === "Form") {
20761
20762
  if (content.includes("Formik") || content.includes("formik")) {
20762
- const fields = extractFieldsFromFormik(path26);
20763
+ const fields = extractFieldsFromFormik(path27);
20763
20764
  if (fields.length > 0) {
20764
20765
  forms.push({
20765
20766
  filePath,
@@ -20770,8 +20771,8 @@ function scanForForms(ast, content, filePath) {
20770
20771
  submitsTo: null,
20771
20772
  complexity: "moderate",
20772
20773
  suggestedAction: "assisted",
20773
- startLine: path26.node.loc?.start.line || 0,
20774
- endLine: path26.node.loc?.end.line || 0
20774
+ startLine: path27.node.loc?.start.line || 0,
20775
+ endLine: path27.node.loc?.end.line || 0
20775
20776
  });
20776
20777
  }
20777
20778
  }
@@ -20789,8 +20790,8 @@ function extractFieldsFromForm(formPath) {
20789
20790
  const radioGroups = /* @__PURE__ */ new Map();
20790
20791
  const checkboxGroups = /* @__PURE__ */ new Map();
20791
20792
  formPath.traverse({
20792
- JSXElement(path26) {
20793
- const opening = path26.node.openingElement;
20793
+ JSXElement(path27) {
20794
+ const opening = path27.node.openingElement;
20794
20795
  const tagName = isJSXIdentifier(opening.name) ? opening.name.name : null;
20795
20796
  if (["input", "textarea", "select"].includes(tagName || "")) {
20796
20797
  const attrs = opening.attributes;
@@ -20837,7 +20838,7 @@ function extractFieldsFromForm(formPath) {
20837
20838
  }
20838
20839
  if (tagName === "select") {
20839
20840
  const selectOptions = [];
20840
- path26.traverse({
20841
+ path27.traverse({
20841
20842
  JSXElement(optionPath) {
20842
20843
  const optOpening = optionPath.node.openingElement;
20843
20844
  const optTagName = isJSXIdentifier(optOpening.name) ? optOpening.name.name : null;
@@ -20912,8 +20913,8 @@ function extractFieldsFromForm(formPath) {
20912
20913
  function extractFieldsFromFormik(formPath, content) {
20913
20914
  const fields = [];
20914
20915
  formPath.traverse({
20915
- JSXElement(path26) {
20916
- const opening = path26.node.openingElement;
20916
+ JSXElement(path27) {
20917
+ const opening = path27.node.openingElement;
20917
20918
  const tagName = isJSXIdentifier(opening.name) ? opening.name.name : null;
20918
20919
  if (tagName === "Field" || tagName === "FastField") {
20919
20920
  const attrs = opening.attributes;
@@ -21032,11 +21033,11 @@ function scanForMetadata(ast, content, filePath) {
21032
21033
  }
21033
21034
  let hasHeadComponent = false;
21034
21035
  traverse(ast, {
21035
- JSXElement(path26) {
21036
- const opening = path26.node.openingElement;
21036
+ JSXElement(path27) {
21037
+ const opening = path27.node.openingElement;
21037
21038
  if (isJSXIdentifier(opening.name) && opening.name.name === "Head") {
21038
21039
  hasHeadComponent = true;
21039
- path26.stop();
21040
+ path27.stop();
21040
21041
  }
21041
21042
  }
21042
21043
  });
@@ -21071,8 +21072,8 @@ function scanForWidgets(ast, content, filePath) {
21071
21072
  for (const { pattern, type } of widgetPatterns) {
21072
21073
  if (pattern.test(content)) {
21073
21074
  traverse(ast, {
21074
- JSXElement(path26) {
21075
- const opening = path26.node.openingElement;
21075
+ JSXElement(path27) {
21076
+ const opening = path27.node.openingElement;
21076
21077
  if (isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
21077
21078
  const srcAttr = opening.attributes.find(
21078
21079
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "src"
@@ -21087,8 +21088,8 @@ function scanForWidgets(ast, content, filePath) {
21087
21088
  filePath,
21088
21089
  widgetType: type,
21089
21090
  scriptTag: src,
21090
- startLine: path26.node.loc?.start.line || 0,
21091
- endLine: path26.node.loc?.end.line || 0
21091
+ startLine: path27.node.loc?.start.line || 0,
21092
+ endLine: path27.node.loc?.end.line || 0
21092
21093
  });
21093
21094
  }
21094
21095
  }
@@ -21227,8 +21228,8 @@ function scanForSchemas(ast, content, filePath) {
21227
21228
  return schemas;
21228
21229
  }
21229
21230
  traverse(ast, {
21230
- JSXElement(path26) {
21231
- const opening = path26.node.openingElement;
21231
+ JSXElement(path27) {
21232
+ const opening = path27.node.openingElement;
21232
21233
  if (isJSXIdentifier(opening.name) && (opening.name.name === "script" || opening.name.name === "Script")) {
21233
21234
  const typeAttr = opening.attributes.find(
21234
21235
  (attr) => isJSXAttribute(attr) && isJSXIdentifier(attr.name) && attr.name.name === "type"
@@ -21255,8 +21256,8 @@ function scanForSchemas(ast, content, filePath) {
21255
21256
  filePath,
21256
21257
  type: detectedType,
21257
21258
  schemaType,
21258
- startLine: path26.node.loc?.start.line || 0,
21259
- endLine: path26.node.loc?.end.line || 0
21259
+ startLine: path27.node.loc?.start.line || 0,
21260
+ endLine: path27.node.loc?.end.line || 0
21260
21261
  });
21261
21262
  }
21262
21263
  }
@@ -21289,8 +21290,8 @@ function scanForFAQs(ast, content, filePath) {
21289
21290
  /questions?\s*(?:and|&)?\s*answers?/i
21290
21291
  ];
21291
21292
  traverse(ast, {
21292
- JSXElement(path26) {
21293
- const opening = path26.node.openingElement;
21293
+ JSXElement(path27) {
21294
+ const opening = path27.node.openingElement;
21294
21295
  let tagName = "";
21295
21296
  if (isJSXIdentifier(opening.name)) {
21296
21297
  tagName = opening.name.name;
@@ -21303,8 +21304,8 @@ function scanForFAQs(ast, content, filePath) {
21303
21304
  faqs.push({
21304
21305
  filePath,
21305
21306
  type: "details-summary",
21306
- startLine: path26.node.loc?.start.line || 0,
21307
- endLine: path26.node.loc?.end.line || 0,
21307
+ startLine: path27.node.loc?.start.line || 0,
21308
+ endLine: path27.node.loc?.end.line || 0,
21308
21309
  hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
21309
21310
  });
21310
21311
  return;
@@ -21312,7 +21313,7 @@ function scanForFAQs(ast, content, filePath) {
21312
21313
  for (const pattern of faqPatterns) {
21313
21314
  if (pattern.test(tagName)) {
21314
21315
  let itemCount = 0;
21315
- path26.traverse({
21316
+ path27.traverse({
21316
21317
  JSXElement(itemPath) {
21317
21318
  const itemOpening = itemPath.node.openingElement;
21318
21319
  if (isJSXIdentifier(itemOpening.name)) {
@@ -21328,8 +21329,8 @@ function scanForFAQs(ast, content, filePath) {
21328
21329
  type: "accordion",
21329
21330
  componentName: tagName,
21330
21331
  itemCount: itemCount || void 0,
21331
- startLine: path26.node.loc?.start.line || 0,
21332
- endLine: path26.node.loc?.end.line || 0,
21332
+ startLine: path27.node.loc?.start.line || 0,
21333
+ endLine: path27.node.loc?.end.line || 0,
21333
21334
  hasSchema: content.includes("FAQPage") || content.includes("application/ld+json")
21334
21335
  });
21335
21336
  return;
@@ -21452,8 +21453,8 @@ function scanForImages(ast, content, filePath) {
21452
21453
  return images;
21453
21454
  }
21454
21455
  traverse(ast, {
21455
- JSXElement(path26) {
21456
- const opening = path26.node.openingElement;
21456
+ JSXElement(path27) {
21457
+ const opening = path27.node.openingElement;
21457
21458
  if (!isJSXIdentifier(opening.name)) return;
21458
21459
  const tagName = opening.name.name;
21459
21460
  if (tagName === "img" || tagName === "Image") {
@@ -21481,8 +21482,8 @@ function scanForImages(ast, content, filePath) {
21481
21482
  src: src || void 0,
21482
21483
  alt: alt || void 0,
21483
21484
  isLocal,
21484
- startLine: path26.node.loc?.start.line || 0,
21485
- endLine: path26.node.loc?.end.line || 0
21485
+ startLine: path27.node.loc?.start.line || 0,
21486
+ endLine: path27.node.loc?.end.line || 0
21486
21487
  });
21487
21488
  }
21488
21489
  }
@@ -22396,18 +22397,18 @@ async function migrateFile(filePath, options) {
22396
22397
  let componentName = "Form";
22397
22398
  const traverse2 = (await import('../lib-RSDMEKDQ.mjs')).default;
22398
22399
  traverse2(ast, {
22399
- ExportNamedDeclaration(path26) {
22400
- const decl = path26.node.declaration;
22400
+ ExportNamedDeclaration(path27) {
22401
+ const decl = path27.node.declaration;
22401
22402
  if (decl && decl.type === "FunctionDeclaration" && decl.id) {
22402
22403
  componentName = decl.id.name;
22403
- path26.stop();
22404
+ path27.stop();
22404
22405
  }
22405
22406
  },
22406
- ExportDefaultDeclaration(path26) {
22407
- const decl = path26.node.declaration;
22407
+ ExportDefaultDeclaration(path27) {
22408
+ const decl = path27.node.declaration;
22408
22409
  if (decl && decl.type === "FunctionDeclaration" && decl.id) {
22409
22410
  componentName = decl.id.name;
22410
- path26.stop();
22411
+ path27.stop();
22411
22412
  }
22412
22413
  }
22413
22414
  });
@@ -22734,15 +22735,15 @@ var wslDefaultBrowser = async () => {
22734
22735
  const { stdout } = await executePowerShell(command, { powerShellPath: psPath });
22735
22736
  return stdout.trim();
22736
22737
  };
22737
- var convertWslPathToWindows = async (path26) => {
22738
- if (/^[a-z]+:\/\//i.test(path26)) {
22739
- return path26;
22738
+ var convertWslPathToWindows = async (path27) => {
22739
+ if (/^[a-z]+:\/\//i.test(path27)) {
22740
+ return path27;
22740
22741
  }
22741
22742
  try {
22742
- const { stdout } = await execFile2("wslpath", ["-aw", path26], { encoding: "utf8" });
22743
+ const { stdout } = await execFile2("wslpath", ["-aw", path27], { encoding: "utf8" });
22743
22744
  return stdout.trim();
22744
22745
  } catch {
22745
- return path26;
22746
+ return path27;
22746
22747
  }
22747
22748
  };
22748
22749
 
@@ -25161,8 +25162,8 @@ async function templateCommand(sourcePath, options, config2) {
25161
25162
  const slots = [];
25162
25163
  const componentNames = [];
25163
25164
  traverse(ast, {
25164
- JSXElement(path26) {
25165
- const openingElement = path26.node.openingElement;
25165
+ JSXElement(path27) {
25166
+ const openingElement = path27.node.openingElement;
25166
25167
  if (isJSXIdentifier(openingElement.name)) {
25167
25168
  const componentName = openingElement.name.name;
25168
25169
  if (componentName[0] === componentName[0].toUpperCase()) {
@@ -26366,6 +26367,98 @@ async function uploadSchemas(pages, globalSchema, config2) {
26366
26367
  }
26367
26368
  }
26368
26369
  }
26370
+ var APP_DIRS = ["app", path10.join("src", "app")];
26371
+ var CARD_FILE = /^(opengraph-image|twitter-image)\b.*\.(png|jpe?g|gif|webp)$/i;
26372
+ function safeExists(p) {
26373
+ try {
26374
+ return fs__default.existsSync(p);
26375
+ } catch {
26376
+ return false;
26377
+ }
26378
+ }
26379
+ function findPageCards(cwd) {
26380
+ const found = [];
26381
+ const walk = (dir) => {
26382
+ let entries;
26383
+ try {
26384
+ entries = fs__default.readdirSync(dir, { withFileTypes: true });
26385
+ } catch {
26386
+ return;
26387
+ }
26388
+ for (const entry of entries) {
26389
+ if (entry.name.startsWith(".") || entry.name === "node_modules") continue;
26390
+ const full = path10.join(dir, entry.name);
26391
+ if (entry.isDirectory()) walk(full);
26392
+ else if (CARD_FILE.test(entry.name)) found.push(full);
26393
+ }
26394
+ };
26395
+ for (const rel of APP_DIRS) walk(path10.join(cwd, rel));
26396
+ return found;
26397
+ }
26398
+ function readOgWiring(cwd) {
26399
+ const siteCard = ["public/og.png", "public/og.jpg", "public/opengraph.png"].some(
26400
+ (rel) => safeExists(path10.join(cwd, rel))
26401
+ );
26402
+ const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((rel) => path10.join(cwd, rel)).find(safeExists);
26403
+ let layout = "";
26404
+ if (layoutPath) {
26405
+ try {
26406
+ layout = fs__default.readFileSync(layoutPath, "utf-8");
26407
+ } catch {
26408
+ }
26409
+ }
26410
+ return {
26411
+ siteCard,
26412
+ pageCards: findPageCards(cwd),
26413
+ layoutDeclaresImages: /images:\s*\[/.test(layout),
26414
+ largeCard: /summary_large_image/.test(layout),
26415
+ referencesImage: /og\.png|opengraph-image|og:image|images:\s*\[/.test(layout),
26416
+ layoutFound: !!layoutPath
26417
+ };
26418
+ }
26419
+ function judgeOgWiring(facts) {
26420
+ const problems = [];
26421
+ if (!facts.layoutFound) {
26422
+ return [{ message: "no app/layout.tsx found to verify metadata", fix: "Run this from the site root." }];
26423
+ }
26424
+ if (!facts.siteCard && !facts.pageCards.length) {
26425
+ return [
26426
+ {
26427
+ message: "no OG card \u2014 shared links render as bare URLs",
26428
+ fix: "Run: sonor-setup og (add og.config.ts for the real brand palette)"
26429
+ }
26430
+ ];
26431
+ }
26432
+ if (facts.pageCards.length) {
26433
+ if (facts.layoutDeclaresImages) {
26434
+ problems.push({
26435
+ message: `openGraph/twitter images are declared in the root layout, which overrides all ${facts.pageCards.length} per-page cards`,
26436
+ fix: "Remove the images arrays from the root layout metadata and let Next serve each route its own opengraph-image file."
26437
+ });
26438
+ }
26439
+ problems.push({
26440
+ message: "seo_pages.managed_og_image (if set in Sonor) overrides per-page cards the same way",
26441
+ fix: "Clear managed_og_image for this project so each page serves its own card."
26442
+ });
26443
+ } else if (!facts.referencesImage) {
26444
+ problems.push({
26445
+ message: "card asset exists but layout metadata never references it",
26446
+ fix: "Add openGraph.images: ['/og.png'] (and twitter.images) to the root layout metadata."
26447
+ });
26448
+ }
26449
+ if (!facts.largeCard) {
26450
+ problems.push({
26451
+ message: "twitter.card is not 'summary_large_image' \u2014 previews render as a small square",
26452
+ fix: "Set twitter: { card: 'summary_large_image' } in the root layout metadata."
26453
+ });
26454
+ }
26455
+ return problems;
26456
+ }
26457
+ function checkOgWiring(cwd) {
26458
+ return judgeOgWiring(readOgWiring(cwd));
26459
+ }
26460
+
26461
+ // src/cli/agent/checks.ts
26369
26462
  var API_URL4 = process.env.SONOR_API_URL || "https://api.sonor.io";
26370
26463
  async function readFileOrNull(p) {
26371
26464
  try {
@@ -27028,58 +27121,19 @@ async function checkImageDimsDrift(cwd) {
27028
27121
  return { id: "images.dims-drift", title: "Image dims vs SVG", level: "ok", message: "Declared dims match SVG viewBoxes" };
27029
27122
  }
27030
27123
  async function checkOgCard(cwd) {
27031
- const staticCard = ["public/og.png", "public/og.jpg", "public/opengraph.png"].some(
27032
- (rel) => existsSyncSafe(path10.join(cwd, rel))
27033
- );
27034
- let fileConvention = false;
27035
- for (const appDir of ["app", "src/app"]) {
27036
- try {
27037
- const entries = await fs3.readdir(path10.join(cwd, appDir));
27038
- if (entries.some((e) => e.startsWith("opengraph-image") || e.startsWith("twitter-image"))) {
27039
- fileConvention = true;
27040
- }
27041
- } catch {
27042
- }
27043
- }
27044
- const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((rel) => path10.join(cwd, rel)).find(existsSyncSafe);
27045
- const layout = layoutPath ? await readFileOrNull(layoutPath) : null;
27046
- const referencesImage = !!layout && /og\.png|opengraph-image|og:image|images:\s*\[/.test(layout);
27047
- const largeCard = !!layout && /summary_large_image/.test(layout);
27048
- if (!staticCard && !fileConvention) {
27049
- return {
27050
- id: "og.card",
27051
- title: "Open Graph card",
27052
- level: "warn",
27053
- message: "No OG card \u2014 shared links render as bare URLs",
27054
- fix: "Run: sonor-setup og (add og.config.ts for the real brand palette)"
27055
- };
27056
- }
27057
- if (!referencesImage) {
27058
- return {
27059
- id: "og.card",
27060
- title: "Open Graph card",
27061
- level: "warn",
27062
- message: "Card asset exists but layout metadata never references it",
27063
- fix: "Add openGraph.images: ['/og.png'] (and twitter.images) to the root layout metadata."
27064
- };
27065
- }
27066
- if (!largeCard) {
27067
- return {
27068
- id: "og.card",
27069
- title: "Open Graph card",
27070
- level: "warn",
27071
- message: "twitter.card is not 'summary_large_image' \u2014 previews render as a small square",
27072
- fix: "Set twitter: { card: 'summary_large_image' } in the root layout metadata."
27073
- };
27074
- }
27075
- return { id: "og.card", title: "Open Graph card", level: "ok", message: "Card present and wired" };
27076
- }
27077
- function existsSyncSafe(p) {
27078
- try {
27079
- return __require("fs").existsSync(p);
27080
- } catch {
27081
- return false;
27124
+ const problems = judgeOgWiring(readOgWiring(cwd));
27125
+ if (!problems.length) {
27126
+ return { id: "og.card", title: "Open Graph card", level: "ok", message: "Cards present and wired" };
27082
27127
  }
27128
+ const [first, ...rest] = problems;
27129
+ return {
27130
+ id: "og.card",
27131
+ title: "Open Graph card",
27132
+ level: "warn",
27133
+ message: first.message,
27134
+ ...rest.length ? { detail: rest.map((p) => `${p.message} \u2014 ${p.fix}`).join("\n") } : {},
27135
+ fix: first.fix
27136
+ };
27083
27137
  }
27084
27138
  async function staticChecks(cwd) {
27085
27139
  return [
@@ -27162,7 +27216,64 @@ async function statusCommand(options) {
27162
27216
  const online = options.offline ? false : true;
27163
27217
  await runCommand(ctx, (c) => run2(c, online), renderChecksHuman("Site-Kit Integration Status"));
27164
27218
  }
27219
+
27220
+ // src/og/pages.ts
27221
+ function stripBrandSuffix(title, brand) {
27222
+ const cleaned = title.replace(/\s*[|–—-]\s*[^|–—-]+$/, "").trim();
27223
+ if (!cleaned) return title.trim();
27224
+ if (brand && cleaned.toLowerCase() === brand.toLowerCase()) return title.trim();
27225
+ return cleaned;
27226
+ }
27227
+ function titleFromPath(path27) {
27228
+ const last = path27.split("/").filter(Boolean).pop();
27229
+ if (!last) return "Home";
27230
+ return last.replace(/[-_]+/g, " ").replace(/\b\w/g, (c) => c.toUpperCase()).trim();
27231
+ }
27232
+ function kickerFromPath(path27, fallback) {
27233
+ const parts = path27.split("/").filter(Boolean);
27234
+ if (parts.length < 2) return fallback;
27235
+ return parts.slice(0, -1).join(" / ").replace(/[-_]+/g, " ");
27236
+ }
27237
+ function clampSubtitle(text, max = 100) {
27238
+ if (!text) return void 0;
27239
+ const flat = text.replace(/\s+/g, " ").trim();
27240
+ if (!flat) return void 0;
27241
+ if (flat.length <= max) return flat;
27242
+ const sentence = flat.slice(0, max + 1).match(/^.*[.!?](?=\s|$)/)?.[0];
27243
+ if (sentence && sentence.length >= 30) return sentence.trim();
27244
+ const cut = flat.slice(0, flat.lastIndexOf(" ", max) || max).trim();
27245
+ return `${cut.replace(/[.,;:!?…]+$/, "")}\u2026`;
27246
+ }
27247
+ function slugForPath(path27) {
27248
+ const trimmed = path27.replace(/^\/+|\/+$/g, "");
27249
+ if (!trimmed) return "home";
27250
+ return trimmed.replace(/[^a-zA-Z0-9]+/g, "-").replace(/^-+|-+$/g, "").toLowerCase();
27251
+ }
27252
+ function pageCardConfig(base, route, brand) {
27253
+ const override = base.cards?.[route.path] ?? base.cards?.[slugForPath(route.path)];
27254
+ const title = route.title ? stripBrandSuffix(route.title, brand) : titleFromPath(route.path);
27255
+ const derived = {
27256
+ ...base,
27257
+ // `cards` is a build-time instruction, not part of a rendered card.
27258
+ cards: void 0,
27259
+ content: {
27260
+ ...base.content,
27261
+ kicker: kickerFromPath(route.path, base.content.kicker),
27262
+ title,
27263
+ subtitle: clampSubtitle(route.description) ?? base.content.subtitle
27264
+ }
27265
+ };
27266
+ if (!override) return derived;
27267
+ return {
27268
+ ...derived,
27269
+ ...override,
27270
+ content: { ...derived.content, ...override.content }
27271
+ };
27272
+ }
27273
+
27274
+ // src/cli/commands/og.ts
27165
27275
  var execFileAsync5 = promisify(execFile$1);
27276
+ var RENDER_CONCURRENCY = 4;
27166
27277
  var CHROME_CANDIDATES = [
27167
27278
  process.env.SONOR_CHROME_PATH,
27168
27279
  "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome",
@@ -27237,32 +27348,139 @@ function inlinePublicPaths(html, cwd) {
27237
27348
  return existsSync(full) ? `src="file://${full}"` : `src="${p}"`;
27238
27349
  });
27239
27350
  }
27240
- async function verifyMetadataWiring(cwd) {
27241
- const problems = [];
27242
- const layoutPath = ["app/layout.tsx", "src/app/layout.tsx"].map((r) => path10.join(cwd, r)).find(existsSync);
27243
- if (!layoutPath) return ["no app/layout.tsx found to verify metadata"];
27244
- const layout = await fs3.readFile(layoutPath, "utf-8");
27245
- if (!/og\.png|opengraph-image|og:image|images:\s*\[/.test(layout)) {
27246
- problems.push("layout metadata never references the card \u2014 add openGraph.images: ['/og.png']");
27351
+ async function renderCard(config2, outPath, cwd, chrome, tmpSuffix) {
27352
+ const tmpHtml = path10.join(cwd, `.sonor-og-${tmpSuffix}.html`);
27353
+ try {
27354
+ await fs3.mkdir(path10.dirname(outPath), { recursive: true });
27355
+ await fs3.writeFile(tmpHtml, inlinePublicPaths(buildOgHtml(config2), cwd));
27356
+ const { stdout } = await execFileAsync5(
27357
+ chrome,
27358
+ [
27359
+ "--headless=new",
27360
+ "--disable-gpu",
27361
+ "--hide-scrollbars",
27362
+ "--window-size=1200,630",
27363
+ "--virtual-time-budget=10000",
27364
+ `--screenshot=${outPath}`,
27365
+ "--dump-dom",
27366
+ `file://${tmpHtml}`
27367
+ ],
27368
+ { maxBuffer: 32 * 1024 * 1024 }
27369
+ );
27370
+ return parseReport(stdout);
27371
+ } finally {
27372
+ await fs3.rm(tmpHtml, { force: true });
27373
+ }
27374
+ }
27375
+ function parseReport(dom) {
27376
+ const raw = dom.match(new RegExp(`${OG_REPORT_ATTR}="([^"]*)"`))?.[1];
27377
+ if (!raw) {
27378
+ return { fits: true, titlePx: TITLE_MAX_PX, issues: ["card rendered but could not be measured (fitter did not run)"] };
27247
27379
  }
27248
- if (!/summary_large_image/.test(layout)) {
27249
- problems.push("twitter.card is not 'summary_large_image' \u2014 previews render as a small square");
27380
+ try {
27381
+ const decoded = raw.replace(/&quot;/g, '"').replace(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">");
27382
+ return JSON.parse(decoded);
27383
+ } catch {
27384
+ return { fits: true, titlePx: TITLE_MAX_PX, issues: ["card rendered but the fit report was unreadable"] };
27250
27385
  }
27251
- const ogTitle = layout.match(/openGraph[\s\S]{0,400}?title:\s*['"`]([^'"`]+)/)?.[1];
27252
- if (ogTitle && ogTitle.length > 60) {
27253
- problems.push(`og:title is ${ogTitle.length} chars \u2014 iMessage/Facebook truncate around 60`);
27386
+ }
27387
+ async function compressCard(pngPath, cwd) {
27388
+ try {
27389
+ const require_ = (await import('module')).createRequire(path10.join(cwd, "package.json"));
27390
+ const sharp = require_("sharp");
27391
+ const jpgPath = pngPath.replace(/\.png$/, ".jpg");
27392
+ await sharp(pngPath).jpeg({ quality: 84, mozjpeg: true }).toFile(jpgPath);
27393
+ await fs3.rm(pngPath, { force: true });
27394
+ return jpgPath;
27395
+ } catch {
27396
+ return pngPath;
27397
+ }
27398
+ }
27399
+ function discoverDynamicSegments(appDir) {
27400
+ const found = [];
27401
+ const walk = (dir, urlSegments) => {
27402
+ for (const entry of readdirSync(dir, { withFileTypes: true })) {
27403
+ if (!entry.isDirectory()) continue;
27404
+ if (entry.name.startsWith("_") || entry.name.startsWith(".")) continue;
27405
+ if (entry.name === "api" || entry.name === "node_modules") continue;
27406
+ const full = path10.join(dir, entry.name);
27407
+ const isGroup = entry.name.startsWith("(") && entry.name.endsWith(")");
27408
+ const isDynamic = entry.name.startsWith("[") && entry.name.endsWith("]");
27409
+ const nextUrl = isGroup || isDynamic ? urlSegments : [...urlSegments, entry.name];
27410
+ if (isDynamic) {
27411
+ const hasPage = ["tsx", "jsx", "ts", "js"].some((ext2) => existsSync(path10.join(full, `page.${ext2}`)));
27412
+ if (hasPage) found.push({ dir: full, urlish: `/${urlSegments.join("/")}` });
27413
+ }
27414
+ walk(full, nextUrl);
27415
+ }
27416
+ };
27417
+ walk(appDir, []);
27418
+ return found;
27419
+ }
27420
+ async function pooled(items, limit, fn) {
27421
+ const results = new Array(items.length);
27422
+ let cursor = 0;
27423
+ const workers = Array.from({ length: Math.min(limit, items.length) }, async () => {
27424
+ while (cursor < items.length) {
27425
+ const i = cursor++;
27426
+ results[i] = await fn(items[i], i);
27427
+ }
27428
+ });
27429
+ await Promise.all(workers);
27430
+ return results;
27431
+ }
27432
+ async function resolveRouteCopy(paths) {
27433
+ let getSEOPageData = null;
27434
+ try {
27435
+ if (process.env.SONOR_API_KEY) {
27436
+ ;
27437
+ ({ getSEOPageData } = await import('../api-NTHZ6PAW.mjs'));
27438
+ }
27439
+ } catch {
27440
+ getSEOPageData = null;
27254
27441
  }
27255
- return problems;
27442
+ if (!getSEOPageData) return paths.map((p) => ({ path: p }));
27443
+ return pooled(paths, RENDER_CONCURRENCY, async (p) => {
27444
+ try {
27445
+ const page = await getSEOPageData("", p);
27446
+ const title = page?.managed_title ?? page?.managed_og_title;
27447
+ const description = page?.managed_meta_description ?? page?.managed_og_description;
27448
+ return { path: p, title: title || void 0, description: description || void 0 };
27449
+ } catch {
27450
+ return { path: p };
27451
+ }
27452
+ });
27453
+ }
27454
+ function reportCard(label, report) {
27455
+ if (report.fits && !report.issues.length) {
27456
+ const shrunk = report.titlePx < TITLE_MAX_PX ? source_default.gray(` (title fitted to ${report.titlePx}px)`) : "";
27457
+ console.log(` ${source_default.green("\u2713")} ${label}${shrunk}`);
27458
+ return true;
27459
+ }
27460
+ console.log(` ${report.fits ? source_default.yellow("!") : source_default.red("\u2717")} ${label}`);
27461
+ for (const issue of report.issues) {
27462
+ console.log(source_default.gray(` ${issue}`));
27463
+ }
27464
+ return report.fits;
27256
27465
  }
27257
27466
  async function ogCommand(options) {
27467
+ const ctx = makeContext("og", options);
27468
+ await runCommand(ctx, () => runOg(options));
27469
+ }
27470
+ async function runOg(options) {
27258
27471
  console.log("");
27259
- console.log(source_default.bold(" Generate Open Graph card"));
27472
+ console.log(source_default.bold(" Generate Open Graph cards"));
27260
27473
  console.log("");
27261
27474
  const cwd = process.cwd();
27475
+ const checks = [];
27262
27476
  const chrome = findChrome();
27263
27477
  if (!chrome) {
27264
27478
  console.log(source_default.red(" \u2717 No Chrome/Chromium found. Set SONOR_CHROME_PATH or install Chrome."));
27265
- process.exit(1);
27479
+ return {
27480
+ exitCode: 1 /* FAILED */,
27481
+ summary: "No Chrome/Chromium found",
27482
+ errors: [{ code: "chrome_missing", message: "No Chrome or Chromium binary found", fix: "Install Chrome, or set SONOR_CHROME_PATH to its path." }]
27483
+ };
27266
27484
  }
27267
27485
  let config2 = await loadConfig4(cwd);
27268
27486
  let seeded = false;
@@ -27272,49 +27490,173 @@ async function ogCommand(options) {
27272
27490
  console.log(source_default.yellow(" ! No og.config.ts \u2014 generating a seed card from Sonor brand data."));
27273
27491
  console.log(source_default.gray(" The site owns its theme: add og.config.ts (defineOgCard) with the real palette."));
27274
27492
  }
27275
- const spinner = ora("Rendering with headless Chrome...").start();
27276
27493
  const outPath = path10.resolve(cwd, options.out || "public/og.png");
27277
- const tmpHtml = path10.join(cwd, ".sonor-og-tmp.html");
27494
+ let clean = true;
27495
+ let pageCardsWritten = 0;
27496
+ let totalCardBytes = 0;
27497
+ const spinner = ora("Rendering the site card...").start();
27278
27498
  try {
27279
- const html = inlinePublicPaths(buildOgHtml(config2), cwd);
27280
- await fs3.writeFile(tmpHtml, html);
27281
- await execFileAsync5(chrome, [
27282
- "--headless=new",
27283
- "--disable-gpu",
27284
- "--hide-scrollbars",
27285
- "--window-size=1200,630",
27286
- "--virtual-time-budget=10000",
27287
- `--screenshot=${outPath}`,
27288
- `file://${tmpHtml}`
27289
- ]);
27290
- spinner.succeed(`Wrote ${path10.relative(cwd, outPath)} (1200x630${seeded ? ", seed card" : ""})`);
27291
- if (options.preview !== false) {
27292
- try {
27293
- const require_ = (await import('module')).createRequire(path10.join(cwd, "package.json"));
27294
- const sharp = require_("sharp");
27295
- const previewPath = path10.join(cwd, "public/og-preview.png");
27296
- await sharp(outPath).resize(300).toFile(previewPath);
27297
- console.log(source_default.gray(` Preview at thumbnail size: ${path10.relative(cwd, previewPath)} \u2014 if text is mush there, fix the card.`));
27298
- } catch {
27299
- console.log(source_default.gray(" (sharp not resolvable \u2014 skipped the 300px preview)"));
27499
+ const report = await renderCard(config2, outPath, cwd, chrome, "site");
27500
+ spinner.stop();
27501
+ console.log(source_default.bold(` Site card${seeded ? source_default.gray(" (seed)") : ""}`));
27502
+ clean = reportCard(`${path10.relative(cwd, outPath)} \u2014 1200x630`, report) && clean;
27503
+ checks.push(cardCheck("site card", path10.relative(cwd, outPath), report));
27504
+ } catch (err) {
27505
+ const message = err instanceof Error ? err.message.split("\n")[0] : String(err);
27506
+ spinner.fail(`Render failed: ${message}`);
27507
+ return {
27508
+ exitCode: 1 /* FAILED */,
27509
+ summary: `Site card render failed: ${message}`,
27510
+ errors: [{ code: "render_failed", message, fix: "Check og.config.ts loads and the referenced assets exist under public/." }]
27511
+ };
27512
+ }
27513
+ if (options.pages !== false) {
27514
+ const appDir = findAppDirForDiscovery(cwd);
27515
+ if (!appDir) {
27516
+ console.log(source_default.yellow(" ! No app/ directory found \u2014 skipped per-page cards."));
27517
+ } else {
27518
+ const routes = [...new Set(discoverNextJsRoutes(appDir).map((r) => r.path))];
27519
+ if (!routes.length) {
27520
+ console.log(source_default.yellow(" ! No static routes discovered \u2014 skipped per-page cards."));
27521
+ } else {
27522
+ console.log("");
27523
+ console.log(source_default.bold(` Page cards`));
27524
+ const copySpinner = ora("Reading managed titles from Sonor...").start();
27525
+ const withCopy = await resolveRouteCopy(routes);
27526
+ const named = withCopy.filter((r) => r.title).length;
27527
+ copySpinner.stop();
27528
+ if (named) {
27529
+ console.log(source_default.gray(` ${named}/${routes.length} titled from Sonor, the rest from the route path`));
27530
+ } else {
27531
+ console.log(source_default.gray(" titled from route paths (no SONOR_API_KEY, or no managed titles yet)"));
27532
+ }
27533
+ const brand = config2.content.title.replace(/\n/g, " ").trim();
27534
+ const copyByPath = new Map(withCopy.map((r) => [r.path, r]));
27535
+ const dynamic = discoverDynamicSegments(appDir).map((seg) => ({
27536
+ ...copyByPath.get(seg.urlish) ?? { path: seg.urlish },
27537
+ path: `${seg.urlish}/*`,
27538
+ dir: seg.dir
27539
+ }));
27540
+ const targets = [...withCopy, ...dynamic];
27541
+ const reports = await pooled(targets, RENDER_CONCURRENCY, async (route, i) => {
27542
+ const pageConfig = pageCardConfig(config2, route, brand);
27543
+ const dir = route.dir ?? routeOutputDir(appDir, route.path);
27544
+ for (const ext2 of ["png", "jpg", "jpeg"]) {
27545
+ await fs3.rm(path10.join(dir, `opengraph-image.${ext2}`), { force: true });
27546
+ }
27547
+ const png = path10.join(dir, "opengraph-image.png");
27548
+ const report = await renderCard(pageConfig, png, cwd, chrome, `page-${i}`);
27549
+ const file = await compressCard(png, cwd);
27550
+ return { route, file, report };
27551
+ });
27552
+ for (const { route, file, report } of reports) {
27553
+ clean = reportCard(`${route.path} ${source_default.gray(path10.relative(cwd, file))}`, report) && clean;
27554
+ checks.push(cardCheck(route.path, path10.relative(cwd, file), report));
27555
+ }
27556
+ pageCardsWritten = reports.length;
27557
+ const bytes = await totalBytes(reports.map((r) => r.file));
27558
+ totalCardBytes = bytes;
27559
+ console.log(source_default.gray(` ${(bytes / 1024 / 1024).toFixed(1)} MB of cards. Next serves these automatically \u2014 no per-page metadata needed.`));
27300
27560
  }
27301
27561
  }
27302
- const problems = await verifyMetadataWiring(cwd);
27303
- if (problems.length) {
27562
+ }
27563
+ if (options.preview !== false) {
27564
+ try {
27565
+ const require_ = (await import('module')).createRequire(path10.join(cwd, "package.json"));
27566
+ const sharp = require_("sharp");
27567
+ const previewPath = path10.join(cwd, ".sonor", "og-preview.png");
27568
+ await fs3.mkdir(path10.dirname(previewPath), { recursive: true });
27569
+ await sharp(outPath).resize(300).toFile(previewPath);
27304
27570
  console.log("");
27305
- console.log(source_default.yellow(" Metadata wiring:"));
27306
- for (const p of problems) console.log(source_default.yellow(` ! ${p}`));
27307
- } else {
27308
- console.log(source_default.green(" \u2713 Metadata wiring looks right (og:image, summary_large_image, title length)"));
27571
+ console.log(source_default.gray(` Thumbnail check: ${path10.relative(cwd, previewPath)} \u2014 if text is mush there, fix the card.`));
27572
+ } catch {
27573
+ console.log(source_default.gray(" (sharp not resolvable \u2014 skipped the 300px preview)"));
27309
27574
  }
27310
- console.log(source_default.gray(" Reminder: Facebook caches cards \u2014 re-scrape at developers.facebook.com/tools/debug/"));
27575
+ }
27576
+ const problems = checkOgWiring(cwd);
27577
+ console.log("");
27578
+ if (problems.length) {
27579
+ console.log(source_default.yellow(" Metadata wiring:"));
27580
+ for (const p of problems) {
27581
+ console.log(source_default.yellow(` ! ${p.message}`));
27582
+ console.log(source_default.gray(` ${p.fix}`));
27583
+ }
27584
+ } else {
27585
+ console.log(source_default.green(" \u2713 Metadata wiring looks right (og:image, summary_large_image, title length)"));
27586
+ }
27587
+ const domain = await siteDomain(cwd);
27588
+ console.log(
27589
+ source_default.gray(
27590
+ ` Facebook caches cards \u2014 re-scrape at https://developers.facebook.com/tools/debug/${domain ? `?q=${encodeURIComponent(domain)}` : ""}`
27591
+ )
27592
+ );
27593
+ console.log("");
27594
+ if (!clean) {
27595
+ console.log(source_default.red(" \u2717 One or more cards do not fit. Fix the copy above and re-run."));
27311
27596
  console.log("");
27312
- } catch (err) {
27313
- spinner.fail(`Render failed: ${err instanceof Error ? err.message.split("\n")[0] : err}`);
27314
- process.exit(1);
27315
- } finally {
27316
- await fs3.rm(tmpHtml, { force: true });
27317
27597
  }
27598
+ for (const problem of problems) {
27599
+ checks.push({
27600
+ id: "og.wiring",
27601
+ title: "Metadata wiring",
27602
+ level: "warn",
27603
+ message: problem.message,
27604
+ fix: problem.fix
27605
+ });
27606
+ }
27607
+ const cards = 1 + pageCardsWritten;
27608
+ return {
27609
+ exitCode: clean ? 0 /* OK */ : 1 /* FAILED */,
27610
+ summary: clean ? `${cards} card${cards === 1 ? "" : "s"} rendered, all fitting` : `${cards} card${cards === 1 ? "" : "s"} rendered, some do not fit`,
27611
+ data: { cards, bytes: totalCardBytes },
27612
+ checks,
27613
+ nextSteps: problems.map((p) => p.fix)
27614
+ };
27615
+ }
27616
+ function cardCheck(label, file, report) {
27617
+ const clean = report.fits && !report.issues.length;
27618
+ return {
27619
+ id: "og.card",
27620
+ title: label,
27621
+ level: clean ? "ok" : report.fits ? "warn" : "error",
27622
+ message: clean ? `${file} (title ${report.titlePx}px)` : report.issues.join("; "),
27623
+ ...clean ? {} : { fix: "Shorten the copy for this card, or give it an override in og.config.ts `cards`." }
27624
+ };
27625
+ }
27626
+ function routeOutputDir(appDir, urlPath) {
27627
+ const segments = urlPath.split("/").filter(Boolean);
27628
+ let dir = appDir;
27629
+ for (const segment of segments) {
27630
+ const direct = path10.join(dir, segment);
27631
+ if (existsSync(direct)) {
27632
+ dir = direct;
27633
+ continue;
27634
+ }
27635
+ const group = existsSync(dir) ? readdirSync(dir, { withFileTypes: true }).find(
27636
+ (e) => e.isDirectory() && e.name.startsWith("(") && e.name.endsWith(")") && existsSync(path10.join(dir, e.name, segment))
27637
+ ) : void 0;
27638
+ dir = group ? path10.join(dir, group.name, segment) : direct;
27639
+ }
27640
+ return dir;
27641
+ }
27642
+ async function totalBytes(files) {
27643
+ let total = 0;
27644
+ for (const f of files) {
27645
+ try {
27646
+ total += (await fs3.stat(f)).size;
27647
+ } catch {
27648
+ }
27649
+ }
27650
+ return total;
27651
+ }
27652
+ async function siteDomain(cwd) {
27653
+ const envFile = path10.join(cwd, ".env.local");
27654
+ if (existsSync(envFile)) {
27655
+ const env3 = await fs3.readFile(envFile, "utf-8").catch(() => "");
27656
+ const url = env3.match(/^NEXT_PUBLIC_SITE_URL=(.+)$/m)?.[1]?.trim();
27657
+ if (url) return url.replace(/\/+$/, "");
27658
+ }
27659
+ return null;
27318
27660
  }
27319
27661
  var execFileAsync6 = promisify(execFile$1);
27320
27662
  async function next16Command() {
@@ -27433,14 +27775,14 @@ var hs = new RegExp(pe, "g");
27433
27775
  var as = /\\\\/g;
27434
27776
  var ls = /\\{/g;
27435
27777
  var cs = /\\}/g;
27436
- var fs19 = /\\,/g;
27778
+ var fs20 = /\\,/g;
27437
27779
  var us = /\\./g;
27438
27780
  var ds = 1e5;
27439
27781
  function Ht(n5) {
27440
27782
  return isNaN(n5) ? n5.charCodeAt(0) : parseInt(n5, 10);
27441
27783
  }
27442
27784
  function ps(n5) {
27443
- return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs19, de).replace(us, pe);
27785
+ return n5.replace(as, fe).replace(ls, ue).replace(cs, qt).replace(fs20, de).replace(us, pe);
27444
27786
  }
27445
27787
  function ms(n5) {
27446
27788
  return n5.replace(is, "\\").replace(rs, "{").replace(ns, "}").replace(os5, ",").replace(hs, ".");
@@ -32034,7 +32376,7 @@ withAgentFlags(
32034
32376
  program2.command("manifest").description("Print the machine-readable agent manifest (modules, env, patterns, failure modes)").option("--section <name>", "Print one section: env | modules | commands | blessedPatterns | failureModes")
32035
32377
  ).action(manifestCommand);
32036
32378
  withAgentFlags(
32037
- program2.command("og").description("Generate the Open Graph card (public/og.png) from og.config.ts via headless Chrome").option("--no-preview", "Skip the 300px thumbnail legibility preview").option("--out <path>", "Output path (default public/og.png)")
32379
+ program2.command("og").description("Generate Open Graph cards \u2014 the site card plus one per page \u2014 via headless Chrome").option("--no-preview", "Skip the 300px thumbnail legibility preview").option("--no-pages", "Only render the site card, skip the per-page cards").option("--out <path>", "Site card output path (default public/og.png)")
32038
32380
  ).action(ogCommand);
32039
32381
  withAgentFlags(
32040
32382
  program2.command("next16").description("Migrate middleware.ts to proxy.ts (official codemod) and verify")