@sonordev/site-kit 8.6.0 → 8.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (161) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/agent-manifest.json +1 -1
  3. package/dist/{AnalyticsProvider-GVJYL6XY.js → AnalyticsProvider-7SBJ27SI.js} +6 -6
  4. package/dist/{ArticleViewTracker-AOJXEBYM.js → ArticleViewTracker-PV2RD3P6.js} +5 -5
  5. package/dist/{BlocksPopup-AJ3CKVQG.js → BlocksPopup-NEEFV2L3.js} +9 -8
  6. package/dist/{ChatWidget-EYBVB5SZ.js → ChatWidget-V46UBDOM.js} +5 -5
  7. package/dist/{FileField-UEQYIFRO.js → FileField-MJ3RCNFJ.js} +3 -3
  8. package/dist/{FormSpotlight-H73ZZ66T.js → FormSpotlight-NQPQFZS7.js} +1 -1
  9. package/dist/{FormStage-2PLWWYBW.js → FormStage-4T5PJR5K.js} +1 -1
  10. package/dist/{ManagedForm-ZQOFXEWS.js → ManagedForm-DDDVMKLJ.js} +6 -6
  11. package/dist/{ManagedNewsletterForm-5TE47YZD.js → ManagedNewsletterForm-TUYGN6O3.js} +9 -9
  12. package/dist/{SignalCore-FEFNMNYN.js → SignalCore-OW3YIH6M.js} +5 -5
  13. package/dist/SiteChat-XMKHBSEK.js +6 -0
  14. package/dist/SiteDesignReporter-BRH7ORQS.js +13 -0
  15. package/dist/{SitePopups-C44YTQ3Q.js → SitePopups-VU2C3Z6B.js} +6 -6
  16. package/dist/SitemapSync-C4H3HF3L.js +9 -0
  17. package/dist/_client/booking-widget.js +5 -5
  18. package/dist/admin-auth/index.d.ts +2 -2
  19. package/dist/admin-auth/session.d.ts +2 -2
  20. package/dist/affiliates/index.js +3 -3
  21. package/dist/analytics/content-text.d.ts +17 -0
  22. package/dist/analytics/index.js +6 -6
  23. package/dist/{article-styles-VASFBYA3.js → article-styles-D7VCDXMG.js} +2 -1
  24. package/dist/article-tables-W45BE353.js +3 -0
  25. package/dist/articles/index.js +7 -20
  26. package/dist/articles/server-ui.js +29 -55
  27. package/dist/articles/server.js +6 -5
  28. package/dist/chat/index.js +8 -8
  29. package/dist/{chunk-3RDJKIYO.js → chunk-2WDWQI7K.js} +1 -1
  30. package/dist/{chunk-KTMHRXDT.js → chunk-2WM4TNDF.js} +1 -1
  31. package/dist/chunk-3MJNBOUO.js +8 -0
  32. package/dist/{chunk-BF7TZYC3.js → chunk-52KO4LKD.js} +1 -1
  33. package/dist/chunk-64XODP7M.js +7 -0
  34. package/dist/{chunk-DSD3XZQQ.js → chunk-6BFQI3ZE.js} +3 -3
  35. package/dist/{chunk-QNOJSSQT.js → chunk-6DXQHNZK.js} +1 -1
  36. package/dist/{chunk-5D7ZISUP.js → chunk-7DYMM6SS.js} +11 -6
  37. package/dist/{chunk-QQT2T6JQ.js → chunk-7HW4TZB5.js} +1 -1
  38. package/dist/{chunk-E4PTMORJ.js → chunk-AL5UCWLI.js} +23 -8
  39. package/dist/chunk-AYQEIMGS.js +390 -0
  40. package/dist/{chunk-L6QTERSH.js → chunk-DYROJGI2.js} +1 -1
  41. package/dist/{chunk-XA7Q2VQA.js → chunk-EK7P62DT.js} +1 -1
  42. package/dist/{chunk-BUE3Z32O.js → chunk-F6WLHVMQ.js} +1 -1
  43. package/dist/{chunk-IYCSDFPN.js → chunk-FLOJUMFR.js} +2 -2
  44. package/dist/{chunk-7R2STOVD.js → chunk-G7BRCSV6.js} +3 -3
  45. package/dist/{chunk-NI6ZTP3D.js → chunk-GQN4BGK6.js} +1 -1
  46. package/dist/{chunk-GFY3E7EQ.js → chunk-GXWM5KNS.js} +15 -7
  47. package/dist/{chunk-U34O6I7W.js → chunk-HN7GVGWC.js} +3 -3
  48. package/dist/{chunk-6KU7STM3.js → chunk-HY7ZEU2C.js} +3 -1
  49. package/dist/chunk-IBHBEUZV.js +27 -0
  50. package/dist/{chunk-ZZSAWXWD.js → chunk-IDC5CVBR.js} +1 -1
  51. package/dist/{chunk-HMTPRBYJ.js → chunk-IWNJCRXW.js} +1 -1
  52. package/dist/chunk-JESLPEST.js +14 -0
  53. package/dist/{chunk-BC7JMY4Z.js → chunk-JG53YJLM.js} +58 -1
  54. package/dist/{chunk-RI2N2EBI.js → chunk-JYITKUUB.js} +13 -5
  55. package/dist/{chunk-V67OD7RW.js → chunk-KG5IEV7I.js} +113 -93
  56. package/dist/chunk-KIYACQW3.js +1 -0
  57. package/dist/{chunk-JSW42BHL.js → chunk-M5JIHQ42.js} +1 -1
  58. package/dist/{chunk-YJH6WE76.js → chunk-NFGAXWCN.js} +9 -9
  59. package/dist/{chunk-Y35BWW2C.js → chunk-ODOV76VW.js} +1 -1
  60. package/dist/{chunk-VA6IJ55K.js → chunk-OPUY4RS6.js} +1 -1
  61. package/dist/{chunk-6NXFA7HE.js → chunk-OWZWRP7Y.js} +2 -2
  62. package/dist/{chunk-JJ4JS3LD.js → chunk-PAYCK7FC.js} +1 -1
  63. package/dist/{chunk-72F44HKL.js → chunk-PSS6M4CG.js} +1 -1
  64. package/dist/{chunk-O3Z5HHFP.js → chunk-SBPUFTMP.js} +2 -2
  65. package/dist/{chunk-OFSV5TZY.js → chunk-SHAUX2MQ.js} +1 -1
  66. package/dist/{chunk-OWO3RFEX.js → chunk-SLFYTELD.js} +1 -1
  67. package/dist/{chunk-CMUD37WV.js → chunk-SVHPILS3.js} +1 -1
  68. package/dist/{chunk-YNBRVVTX.js → chunk-THXELZTQ.js} +1 -1
  69. package/dist/{chunk-IGAIQ2B3.js → chunk-TP32MRXV.js} +2 -2
  70. package/dist/{chunk-NUXXFCIT.js → chunk-URLTBVRX.js} +4 -4
  71. package/dist/chunk-XAZC2TUD.js +1119 -0
  72. package/dist/{chunk-URJN75ZG.js → chunk-XIDWNXZN.js} +3 -3
  73. package/dist/chunk-XLAHRN4B.js +1 -0
  74. package/dist/chunk-XS2ORMUG.js +32 -0
  75. package/dist/{chunk-6AWIUO2Z.js → chunk-Y6SHFILE.js} +1 -1
  76. package/dist/{chunk-FTSEP7Q3.js → chunk-YEX5RAEU.js} +3 -3
  77. package/dist/{chunk-AJG74ZZV.js → chunk-YRQS7VAH.js} +1 -1
  78. package/dist/{chunk-DLM4FFNH.js → chunk-ZQSCMYZO.js} +1 -1
  79. package/dist/client/index.js +4 -4
  80. package/dist/contracts/campaign-normalize.d.ts +2 -0
  81. package/dist/contracts/entries.d.ts +1 -1
  82. package/dist/contracts/frame-ready.d.ts +23 -0
  83. package/dist/contracts/funnels.d.ts +576 -0
  84. package/dist/contracts/inbox.d.ts +42 -0
  85. package/dist/contracts/llms.d.ts +200 -0
  86. package/dist/contracts/portfolio.d.ts +361 -8
  87. package/dist/contracts/publication-branding.d.ts +10 -2
  88. package/dist/contracts/site-cache.d.ts +2 -0
  89. package/dist/fleet/index.js +6 -6
  90. package/dist/forms/index.js +9 -9
  91. package/dist/forms/server.js +2 -2
  92. package/dist/images/index.js +4 -4
  93. package/dist/index.js +1 -1
  94. package/dist/landing/contract.d.ts +2 -13
  95. package/dist/landing/contract.js +2 -0
  96. package/dist/landing/index.js +4 -2
  97. package/dist/landing/managed-server.d.ts +21 -0
  98. package/dist/landing/managed.d.ts +11 -0
  99. package/dist/landing/metadata.js +2 -0
  100. package/dist/landing/server.d.ts +5 -0
  101. package/dist/landing/server.js +20 -2
  102. package/dist/layout/client.js +9 -9
  103. package/dist/layout/index.js +10 -10
  104. package/dist/llms/contract.js +2 -1
  105. package/dist/llms/index.js +9 -7
  106. package/dist/llms/merge.d.ts +29 -0
  107. package/dist/maps/index.js +3 -3
  108. package/dist/mcp/sonor.js +9 -8
  109. package/dist/og/pages.d.ts +3 -3
  110. package/dist/portfolio/contract.js +705 -1
  111. package/dist/press-kit/articles/article-body.d.ts +12 -0
  112. package/dist/press-kit/articles/article-heading-ids.d.ts +7 -0
  113. package/dist/press-kit/articles/article-headings.d.ts +61 -0
  114. package/dist/press-kit/articles/html-tags.d.ts +46 -0
  115. package/dist/press-kit/articles/types.d.ts +2 -0
  116. package/dist/revalidate/index.js +3 -3
  117. package/dist/runtime/index.js +3 -3
  118. package/dist/seo/client.js +6 -6
  119. package/dist/seo/index.js +14 -13
  120. package/dist/seo/llms/contract.js +2 -1
  121. package/dist/seo/llms.js +9 -7
  122. package/dist/seo/meta/contract.js +2 -1
  123. package/dist/seo/register-sitemap-cli.js +1 -1
  124. package/dist/seo/server.js +5 -4
  125. package/dist/seo/sitemap.js +7 -5
  126. package/dist/seo-meta/contract.js +2 -1
  127. package/dist/server/index.js +3 -3
  128. package/dist/{server-api-EGOKC7Q3.js → server-api-XIKDWSNO.js} +2 -2
  129. package/dist/shared/build-entries.d.ts +3 -1
  130. package/dist/shared/frame.d.ts +1 -1
  131. package/dist/shared/markdown.d.ts +7 -6
  132. package/dist/shared/source-graph.d.ts +5 -5
  133. package/dist/shared/version.d.ts +1 -1
  134. package/dist/signal/index.js +2 -2
  135. package/dist/sitemap/index.js +7 -5
  136. package/dist/sitemap/shared.d.ts +1 -2
  137. package/dist/slots/index.js +2 -2
  138. package/dist/sync/index.js +5 -5
  139. package/dist/website/contract.js +2 -1
  140. package/dist/website/images.js +4 -4
  141. package/dist/website/index.js +10 -9
  142. package/dist/website/landing/server.js +20 -2
  143. package/dist/website/landing.js +4 -2
  144. package/dist/website/popups.js +9 -8
  145. package/dist/website/slots.js +2 -2
  146. package/dist/{writeLLMsTxt-KHVHNSDM.js → writeLLMsTxt-4HHUAOA6.js} +6 -4
  147. package/docs.json +5 -0
  148. package/package.json +1 -1
  149. package/src/analytics/README.md +1 -1
  150. package/src/landing/README.md +64 -0
  151. package/src/llms/README.md +52 -20
  152. package/dist/SiteChat-3MKYL2XM.js +0 -6
  153. package/dist/SiteDesignReporter-AJDIBNHI.js +0 -12
  154. package/dist/SitemapSync-UJA6JVPW.js +0 -9
  155. package/dist/article-tables-6XHVULPU.js +0 -2
  156. package/dist/chunk-EKBEOXTH.js +0 -114
  157. package/dist/chunk-NZ4RXN3G.js +0 -145
  158. package/dist/chunk-OSYCOC3K.js +0 -21
  159. /package/dist/{chunk-7ZWO5HDQ.js → chunk-BTHEQDN4.js} +0 -0
  160. /package/dist/{chunk-BQR4IPBW.js → chunk-ISRBSTB7.js} +0 -0
  161. /package/dist/{chunk-IHG36STL.js → chunk-XHYE24HU.js} +0 -0
@@ -1,5 +1,5 @@
1
1
  import { freshFetch } from './chunk-UAYAJPEP.js';
2
- import { LLM_GEO_CONTRACT_VERSION } from './chunk-NZ4RXN3G.js';
2
+ import { LLM_GEO_CONTRACT_VERSION } from './chunk-XAZC2TUD.js';
3
3
  import { withSiteParam } from './chunk-MJP63SSS.js';
4
4
  import { getClientApiConfig } from './chunk-W7OPEMGJ.js';
5
5
  import { cache } from 'react';
@@ -1,4 +1,4 @@
1
1
  // src/shared/version.ts
2
- var SITE_KIT_VERSION = "8.6.0";
2
+ var SITE_KIT_VERSION = "8.8.0";
3
3
 
4
4
  export { SITE_KIT_VERSION };
@@ -1,5 +1,5 @@
1
- import { isTokenMode, getFreshCredential, isSiteToken, refreshSiteToken, currentCredential, credentialBreakerId } from './chunk-QQT2T6JQ.js';
2
- import { SITE_KIT_VERSION } from './chunk-BUE3Z32O.js';
1
+ import { isTokenMode, getFreshCredential, isSiteToken, refreshSiteToken, currentCredential, credentialBreakerId } from './chunk-7HW4TZB5.js';
2
+ import { SITE_KIT_VERSION } from './chunk-F6WLHVMQ.js';
3
3
 
4
4
  // src/shared/fetchWithRetry.ts
5
5
  function backoffDelay(attempt, response) {
@@ -1,6 +1,6 @@
1
1
  'use client';
2
- import { countStageViews, countStageQuestions, useFieldControls } from './chunk-NI6ZTP3D.js';
3
- import { useFormLoadedAt, useFormTracking, submitForm, useRecaptchaWarmup, useForm } from './chunk-HMTPRBYJ.js';
2
+ import { countStageViews, countStageQuestions, useFieldControls } from './chunk-GQN4BGK6.js';
3
+ import { useFormLoadedAt, useFormTracking, submitForm, useRecaptchaWarmup, useForm } from './chunk-IWNJCRXW.js';
4
4
  import { readAgentSubmit, formToolAttributes } from './chunk-Q6E4OPGG.js';
5
5
  import { isFieldVisible, validateField, isFieldComplete, isDisplayOnly, unseenControlValues } from './chunk-C2FZBUSS.js';
6
6
  import { HoneypotField } from './chunk-DXO6SBMD.js';
@@ -63,7 +63,7 @@ function FormClient({
63
63
  return;
64
64
  }
65
65
  let cancelled = false;
66
- const load = resolvedExperience === "stage" ? import('./FormStage-2PLWWYBW.js').then((m) => m.FormStage) : import('./FormSpotlight-H73ZZ66T.js').then((m) => m.FormSpotlight);
66
+ const load = resolvedExperience === "stage" ? import('./FormStage-4T5PJR5K.js').then((m) => m.FormStage) : import('./FormSpotlight-NQPQFZS7.js').then((m) => m.FormSpotlight);
67
67
  load.then((Component) => {
68
68
  if (!cancelled) setExperience(() => Component);
69
69
  }).catch((err) => {
@@ -22,7 +22,7 @@ function useFieldControls(fields) {
22
22
  });
23
23
  }
24
24
  if (needsFile) {
25
- import('./FileField-UEQYIFRO.js').then((m) => {
25
+ import('./FileField-MJ3RCNFJ.js').then((m) => {
26
26
  if (!cancelled) setControls((prev) => ({ ...prev, File: m.FileField }));
27
27
  }).catch(() => {
28
28
  });
@@ -2,8 +2,8 @@
2
2
  import { registerAnalyticsDispatcher } from './chunk-LCDVPAMR.js';
3
3
  import { getOrCreateVisitorId, getOrCreateSessionId } from './chunk-IPQKQEWI.js';
4
4
  import { onPageLeave } from './chunk-L2V5PUFN.js';
5
- import { resolveAnalyticsTarget } from './chunk-DLM4FFNH.js';
6
- import { sonorFetch, sonorBeacon } from './chunk-IYCSDFPN.js';
5
+ import { resolveAnalyticsTarget } from './chunk-ZQSCMYZO.js';
6
+ import { sonorFetch, sonorBeacon } from './chunk-FLOJUMFR.js';
7
7
  import { createContext, useRef, useEffect, useState, useMemo, useCallback, useContext } from 'react';
8
8
  import { usePathname } from 'next/navigation';
9
9
  import { jsxs, jsx } from 'react/jsx-runtime';
@@ -228,6 +228,18 @@ function WebVitals({
228
228
  }, []);
229
229
  return null;
230
230
  }
231
+
232
+ // src/analytics/content-text.ts
233
+ var BLOCK_ELEMENTS = "address, article, aside, blockquote, dd, details, div, dl, dt, fieldset, figcaption, figure, h1, h2, h3, h4, h5, h6, hr, li, ol, p, pre, section, summary, table, td, th, tr, ul";
234
+ var NOT_CONTENT = 'script, style, noscript, template, svg, nav, header, footer, label, button, input, select, textarea, option, [role="navigation"], [role="banner"], [role="contentinfo"], [role="dialog"], [role="alert"]';
235
+ var CONTENT_TEXT_MAX_LENGTH = 1e4;
236
+ function extractContentText(root) {
237
+ const clone = root.cloneNode(true);
238
+ clone.querySelectorAll(NOT_CONTENT).forEach((el) => el.remove());
239
+ clone.querySelectorAll("br").forEach((br) => br.replaceWith(" "));
240
+ clone.querySelectorAll(BLOCK_ELEMENTS).forEach((el) => el.append(" "));
241
+ return (clone.textContent || "").replace(/\s+/g, " ").trim().slice(0, CONTENT_TEXT_MAX_LENGTH);
242
+ }
231
243
  var AnalyticsContext = createContext(null);
232
244
  function scheduleIdleTask(callback, timeout = 2e3) {
233
245
  if (typeof window !== "undefined" && "requestIdleCallback" in window) {
@@ -485,11 +497,7 @@ function getContentPageMetadata() {
485
497
  };
486
498
  const getContentText = () => {
487
499
  const main = document.querySelector('main, article, [role="main"]') || document.body;
488
- const clone = main.cloneNode(true);
489
- clone.querySelectorAll('script, style, nav, header, footer, [role="navigation"], [role="banner"], [role="contentinfo"]').forEach((el) => el.remove());
490
- let text = clone.textContent || "";
491
- text = text.replace(/\s+/g, " ").trim();
492
- text = text.slice(0, 1e4);
500
+ const text = extractContentText(main);
493
501
  let hash = 0;
494
502
  for (let i = 0; i < text.length; i++) {
495
503
  const chr = text.charCodeAt(i);
@@ -1,9 +1,9 @@
1
1
  'use client';
2
2
  import { sanitizeFleetVersion, buildFleetHeartbeatPayload } from './chunk-ZTZQPYP6.js';
3
3
  import { useDeferredActivation } from './chunk-YC7ELZS3.js';
4
- import { resolveAnalyticsTarget } from './chunk-DLM4FFNH.js';
5
- import { sonorFetch } from './chunk-IYCSDFPN.js';
6
- import { SITE_KIT_VERSION } from './chunk-BUE3Z32O.js';
4
+ import { resolveAnalyticsTarget } from './chunk-ZQSCMYZO.js';
5
+ import { sonorFetch } from './chunk-FLOJUMFR.js';
6
+ import { SITE_KIT_VERSION } from './chunk-F6WLHVMQ.js';
7
7
  import { useRef, useEffect } from 'react';
8
8
 
9
9
  // src/fleet/heartbeat.ts
@@ -12,7 +12,9 @@ var SITE_CACHE_TAGS = {
12
12
  /** Portfolio items (agency-site-kit). */
13
13
  portfolio: "portfolio",
14
14
  /** Products, services, events and membership plans (commerce-kit). */
15
- commerce: "commerce"
15
+ commerce: "commerce",
16
+ /** Published managed landing pages. Draft previews never enter this cache. */
17
+ funnels: "sonor-funnels"
16
18
  };
17
19
  function isSiteRevalidatePong(body) {
18
20
  return typeof body === "object" && body !== null && body.ok === true && body.ping === true;
@@ -0,0 +1,27 @@
1
+ // packages/press-kit/src/articles/html-tags.ts
2
+ var blank = "\\t\\n\\f\\r ";
3
+ var tagName = `[a-z][^${blank}/>]*(?![^${blank}/>])`;
4
+ var attributeName = `[^${blank}/>][^${blank}/>=]*(?![^${blank}/>=])`;
5
+ var attributeValue = `"[^"]*"|'[^']*'|[^${blank}>"'][^${blank}>]*(?![^${blank}>])|(?=>)`;
6
+ var attribute = `${attributeName}(?:[${blank}]*=[${blank}]*(?:${attributeValue})|(?![${blank}]*=))`;
7
+ var tagBody = `(?:[${blank}/]|${attribute})*>`;
8
+ var comments = "<!--(?:-?>|[^]*?(?:--!?>|$))|<[!?][^>]*(?:>|$)|<\\/(?:>|[^a-z][^>]*(?:>|$))";
9
+ var tokens = new RegExp(`${comments}|<\\/?${tagName}${tagBody}|<\\/?[a-z][^]*`, "gi");
10
+ var completeTag = new RegExp(`^<\\/?(${tagName})${tagBody}$`, "i");
11
+ function htmlTags() {
12
+ return new RegExp(tokens);
13
+ }
14
+ function htmlTagName(token) {
15
+ return completeTag.exec(token)?.[1].toLowerCase() ?? "";
16
+ }
17
+ function isClosingTag(tag) {
18
+ return tag.startsWith("</");
19
+ }
20
+ function openTagAttributes(tag) {
21
+ return tag.slice(1 + htmlTagName(tag).length, -1);
22
+ }
23
+ function stripHtmlTags(html) {
24
+ return html.replace(htmlTags(), "");
25
+ }
26
+
27
+ export { htmlTagName, htmlTags, isClosingTag, openTagAttributes, stripHtmlTags };
@@ -1,4 +1,4 @@
1
- import { writeLLMsTxtToPublic } from './chunk-V67OD7RW.js';
1
+ import { writeLLMsTxtToPublic } from './chunk-KG5IEV7I.js';
2
2
  import { getSiteConfig } from './chunk-Z22QVHT4.js';
3
3
  import { buildFetch } from './chunk-UAYAJPEP.js';
4
4
  import { findAppDirForDiscovery } from './chunk-ZEGVKVD5.js';
@@ -6,7 +6,7 @@ import { normalizeFormConfig, DEFAULT_FORM_SUCCESS_MESSAGE } from './chunk-TYSIA
6
6
  import { DEFAULT_HONEYPOT_FIELD } from './chunk-NJCTQH2P.js';
7
7
  import { onPageLeave } from './chunk-L2V5PUFN.js';
8
8
  import { uuid } from './chunk-GJWI74ZZ.js';
9
- import { sonorFetch, sonorBeacon } from './chunk-IYCSDFPN.js';
9
+ import { sonorFetch, sonorBeacon } from './chunk-FLOJUMFR.js';
10
10
  import { readPublishedApiConfig, getClientApiConfig } from './chunk-W7OPEMGJ.js';
11
11
  import { useRef, useCallback, useEffect, useState, useMemo } from 'react';
12
12
 
@@ -0,0 +1,14 @@
1
+ // src/landing/metadata.ts
2
+ function landingPageMetadata(meta = {}) {
3
+ const callerRobots = meta.robots && typeof meta.robots === "object" ? meta.robots : void 0;
4
+ return {
5
+ ...meta,
6
+ robots: {
7
+ index: false,
8
+ follow: false,
9
+ ...callerRobots
10
+ }
11
+ };
12
+ }
13
+
14
+ export { landingPageMetadata };
@@ -1,3 +1,4 @@
1
+ import { htmlTags, htmlTagName, isClosingTag, openTagAttributes, stripHtmlTags } from './chunk-IBHBEUZV.js';
1
2
  import { createPublicationRoutes } from './chunk-4K735O3J.js';
2
3
  import { resolveTrailingSlash, applyTrailingSlash } from './chunk-YVKRYQRG.js';
3
4
  import { jsxs, jsx, Fragment } from 'react/jsx-runtime';
@@ -344,4 +345,60 @@ function readingTimeMinutes(post) {
344
345
  return typeof value === "number" && value > 0 ? value : null;
345
346
  }
346
347
 
347
- export { ClusterNavigation, ServiceCallout, ServiceCallouts, getAuthorSocialLinks, readingTimeMinutes };
348
+ // packages/press-kit/src/articles/article-headings.ts
349
+ function openTagAttribute(attributes, name) {
350
+ const wanted = name.toLowerCase();
351
+ const attribute = /([^\s"'<>/=]+)(?:\s*=\s*(?:"([^"]*)"|'([^']*)'|([^\s"'<>=`]+)))?/g;
352
+ let match;
353
+ while (match = attribute.exec(attributes)) {
354
+ if (match[1].toLowerCase() === wanted) return match[2] ?? match[3] ?? match[4] ?? "";
355
+ }
356
+ return null;
357
+ }
358
+ function slugify(text) {
359
+ return text.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, "");
360
+ }
361
+ function scanHeadings(html) {
362
+ const tags = htmlTags();
363
+ const lineBreak = /[\n\r\u2028\u2029]/g;
364
+ const headings = [];
365
+ let waiting = [];
366
+ let nextBreak = -1;
367
+ let token;
368
+ while (token = tags.exec(html)) {
369
+ const level = /^h([2-4])$/.exec(htmlTagName(token[0]))?.[1];
370
+ if (!level) continue;
371
+ if (!isClosingTag(token[0])) {
372
+ waiting.push({ level: Number(level), attributes: openTagAttributes(token[0]), start: token.index, innerStart: tags.lastIndex });
373
+ continue;
374
+ }
375
+ for (const open of waiting) {
376
+ if (nextBreak < open.innerStart) {
377
+ lineBreak.lastIndex = open.innerStart;
378
+ nextBreak = lineBreak.exec(html)?.index ?? Infinity;
379
+ }
380
+ if (nextBreak < token.index) continue;
381
+ headings.push({
382
+ level: open.level,
383
+ attributes: open.attributes,
384
+ inner: html.slice(open.innerStart, token.index),
385
+ start: open.start,
386
+ end: tags.lastIndex
387
+ });
388
+ break;
389
+ }
390
+ waiting = [];
391
+ }
392
+ return headings;
393
+ }
394
+ function ownId(attributes) {
395
+ return openTagAttribute(attributes, "id");
396
+ }
397
+ function generateTableOfContents(html) {
398
+ return scanHeadings(html).map(({ level, attributes, inner }) => {
399
+ const text = stripHtmlTags(inner);
400
+ return { id: ownId(attributes) || slugify(text), text, level };
401
+ });
402
+ }
403
+
404
+ export { ClusterNavigation, ServiceCallout, ServiceCallouts, generateTableOfContents, getAuthorSocialLinks, ownId, readingTimeMinutes, scanHeadings, slugify };
@@ -1,5 +1,6 @@
1
1
  import { insertArticlePhotos } from './chunk-WHPCGQHC.js';
2
2
  import { resolveRepresentativeImage, generateArticleAuthorNode, articleImageSchema, resolveArticleArtwork, withArticleAuthorIdentity } from './chunk-UVYUTBT4.js';
3
+ import { stripHtmlTags } from './chunk-IBHBEUZV.js';
3
4
  import { resolveArticleUrl, createPublicationRoutes, resolvePublicationUrl, articleCategorySlug } from './chunk-4K735O3J.js';
4
5
  import { withoutSchemaPlaceholders } from './chunk-VWWITFWM.js';
5
6
  import { withSiteParam, withSiteBody } from './chunk-MJP63SSS.js';
@@ -208,6 +209,13 @@ function createPublicationPreviewHandler(options) {
208
209
  } });
209
210
  };
210
211
  }
212
+
213
+ // packages/press-kit/src/articles/article-body.ts
214
+ function articleBodyHtml(post) {
215
+ return typeof post.content_html === "string" ? post.content_html : "";
216
+ }
217
+
218
+ // packages/press-kit/src/articles/server-core.ts
211
219
  async function getArticleResult(slug, options) {
212
220
  const config = resolveServerApiConfig();
213
221
  return config ? readArticleBySlug({ ...config, site: options?.site }, slug) : { state: "unavailable" };
@@ -631,7 +639,7 @@ async function getAllArticles(options = {}) {
631
639
  return posts.slice(0, maxPosts);
632
640
  }
633
641
  function stripHtml(html) {
634
- return html.replace(/<[^>]*>/g, "").trim();
642
+ return stripHtmlTags(html).replace(/</g, "&lt;").replace(/>/g, "&gt;").trim();
635
643
  }
636
644
  async function generateRssFeed(options) {
637
645
  const {
@@ -683,7 +691,7 @@ async function generateRssFeed(options) {
683
691
  const postUrl = resolveArticleUrl(post, { ...options, siteUrl });
684
692
  const pubDate = post.published_at ? new Date(post.published_at).toUTCString() : now;
685
693
  const author = typeof post.author === "string" ? post.author : post.author?.name || "Unknown";
686
- const fullContent = insertArticlePhotos(post.content_html || post.content || "", post.editorial_photos);
694
+ const fullContent = insertArticlePhotos(articleBodyHtml(post), post.editorial_photos);
687
695
  const description2 = sanitizeExcerpt(post.excerpt, 300) || stripHtml(fullContent).substring(0, 300) + "...";
688
696
  rss += ` <item>
689
697
  <title>${escapeXml(post.title)}</title>
@@ -707,7 +715,7 @@ async function generateRssFeed(options) {
707
715
  }
708
716
  }
709
717
  if (post.featured_image) {
710
- rss += ` <enclosure url="${post.featured_image}" type="image/jpeg"/>
718
+ rss += ` <enclosure url="${escapeXml(post.featured_image)}" type="image/jpeg"/>
711
719
  `;
712
720
  }
713
721
  rss += ` </item>
@@ -746,7 +754,7 @@ async function generateAtomFeed(options) {
746
754
  const updated = post.updated_at || post.published_at || now;
747
755
  const published = post.published_at || now;
748
756
  const author = typeof post.author === "string" ? post.author : post.author?.name || "Unknown";
749
- const fullContent = insertArticlePhotos(post.content_html || post.content || "", post.editorial_photos);
757
+ const fullContent = insertArticlePhotos(articleBodyHtml(post), post.editorial_photos);
750
758
  atom += ` <entry>
751
759
  <title>${escapeXml(post.title)}</title>
752
760
  <link href="${escapeXml(postUrl)}"/>
@@ -1164,4 +1172,4 @@ function generateAuthorPageMetadata(author, options = {}) {
1164
1172
  };
1165
1173
  }
1166
1174
 
1167
- export { ArticleUnavailableError, FEED_DEFAULT_ITEMS, NEWS_SITEMAP_MAX_URLS, NEWS_SITEMAP_WINDOW_MS, PUBLICATION_PREVIEW_COOKIE, PUBLICATION_PREVIEW_HEADERS, SEO_LIMITS, buildNewsSitemapXml, cdata, createPublicationPreviewHandler, fetchArticleBySlug, fetchArticleCategories, fetchRelatedArticles, generateAllArticleSchemas, generateArticleCategoryMetadata, generateArticleListSchema, generateArticleMetadata, generateArticleSchema, generateArticleSitemap, generateArticleStaticParams, generateAtomFeed, generateAuthorPageMetadata, generateAuthorStaticParams, generateBreadcrumbSchema, generateCategoryStaticParams, generateClusterArticleSchema, generateClusterBreadcrumbSchema, generateClusterItemListSchema, generateClusterLandingSchema, generateClusterPageMetadata, generateFaqSchema, generateHowToSchema, generateNewsSitemap, generatePublicationMetadata, generateRssFeed, getAllArticleSlugs, getAllArticles, getAllAuthorSlugs, getArticle, getArticleCategories, getArticlePreview, getArticleResult, getAuthorBySlug, getAuthorPosts, getClusterNavigation, getPostsByCategory, getPublicationIssue, getPublicationIssues, getRelatedInsights, getTopicCluster, getTopicClusters, recentNewsPosts, requireArticle, sanitizeExcerpt, validateArticleSeo, validateMetaDescription, validateSeoTitle };
1175
+ export { ArticleUnavailableError, FEED_DEFAULT_ITEMS, NEWS_SITEMAP_MAX_URLS, NEWS_SITEMAP_WINDOW_MS, PUBLICATION_PREVIEW_COOKIE, PUBLICATION_PREVIEW_HEADERS, SEO_LIMITS, articleBodyHtml, buildNewsSitemapXml, cdata, createPublicationPreviewHandler, fetchArticleBySlug, fetchArticleCategories, fetchRelatedArticles, generateAllArticleSchemas, generateArticleCategoryMetadata, generateArticleListSchema, generateArticleMetadata, generateArticleSchema, generateArticleSitemap, generateArticleStaticParams, generateAtomFeed, generateAuthorPageMetadata, generateAuthorStaticParams, generateBreadcrumbSchema, generateCategoryStaticParams, generateClusterArticleSchema, generateClusterBreadcrumbSchema, generateClusterItemListSchema, generateClusterLandingSchema, generateClusterPageMetadata, generateFaqSchema, generateHowToSchema, generateNewsSitemap, generatePublicationMetadata, generateRssFeed, getAllArticleSlugs, getAllArticles, getAllAuthorSlugs, getArticle, getArticleCategories, getArticlePreview, getArticleResult, getAuthorBySlug, getAuthorPosts, getClusterNavigation, getPostsByCategory, getPublicationIssue, getPublicationIssues, getRelatedInsights, getTopicCluster, getTopicClusters, recentNewsPosts, requireArticle, sanitizeExcerpt, validateArticleSeo, validateMetaDescription, validateSeoTitle };
@@ -1,8 +1,8 @@
1
- import { getLLMsData, getOptimizedLLMsTxt } from './chunk-XA7Q2VQA.js';
2
- import { linkClassificationHost } from './chunk-5D7ZISUP.js';
1
+ import { getLLMsData, getOptimizedLLMsTxt } from './chunk-EK7P62DT.js';
2
+ import { linkClassificationHost } from './chunk-7DYMM6SS.js';
3
3
  import { resolveArticleUrl } from './chunk-4K735O3J.js';
4
4
  import { freshFetch } from './chunk-UAYAJPEP.js';
5
- import { LLM_GEO_CONTRACT_VERSION, sanitizePrimaryLanguageTag, sanitizeLlmsDisclaimerLine, sanitizeLlmsPublicSummary } from './chunk-NZ4RXN3G.js';
5
+ import { selectLlmsPages, LLM_GEO_CONTRACT_VERSION, sanitizePrimaryLanguageTag, sanitizeLlmsDisclaimerLine, llmsBlockquoteSummary, llmsAbsoluteUrl, llmsContactLines, isLlmsListablePage, groupLlmsPages, llmsPageTitle, llmsPageListNote } from './chunk-XAZC2TUD.js';
6
6
  import { resolveTrailingSlash, applyTrailingSlash } from './chunk-YVKRYQRG.js';
7
7
  import { resolveSiteHost } from './chunk-FESKKJAS.js';
8
8
  import { readFileSync, existsSync, mkdirSync, writeFileSync, renameSync, unlinkSync, readdirSync } from 'fs';
@@ -101,6 +101,47 @@ function humanizeIndustry(industry) {
101
101
  return spaced.charAt(0).toUpperCase() + spaced.slice(1);
102
102
  }
103
103
 
104
+ // src/llms/merge.ts
105
+ function isFilled(value) {
106
+ if (typeof value === "string") return value.trim() !== "";
107
+ return value !== null && value !== void 0;
108
+ }
109
+ function mergeFilledFields(sonor, local) {
110
+ if (!sonor && !local) return void 0;
111
+ if (!sonor) return local ?? void 0;
112
+ if (!local) return sonor;
113
+ const merged = { ...local };
114
+ for (const [key, value] of Object.entries(sonor)) {
115
+ if (isFilled(value) || !isFilled(merged[key])) merged[key] = value;
116
+ }
117
+ return merged;
118
+ }
119
+ var NAP_BUSINESS_FIELDS = ["name", "description"];
120
+ var NAP_CONTACT_FIELDS = ["phone", "address", "city", "state", "postal_code"];
121
+ function lacksNap(data) {
122
+ const business = data.business ?? {};
123
+ const contact = data.contact ?? {};
124
+ return NAP_BUSINESS_FIELDS.some((key) => !isFilled(business[key])) || NAP_CONTACT_FIELDS.some((key) => !isFilled(contact[key]));
125
+ }
126
+ function needsLocalData(data) {
127
+ if (!data) return true;
128
+ if (!data.services?.length || !data.faq?.length || !data.pages?.length) return true;
129
+ return lacksNap(data);
130
+ }
131
+ function mergeLlmsData(sonor, local, mergeMeta) {
132
+ if (!local) return sonor;
133
+ if (!sonor) return local;
134
+ return {
135
+ meta: mergeMeta(local.meta, sonor.meta),
136
+ business: mergeFilledFields(sonor.business, local.business),
137
+ contact: mergeFilledFields(sonor.contact, local.contact),
138
+ services: (sonor.services?.length ? sonor.services : local.services) ?? [],
139
+ faq: (sonor.faq?.length ? sonor.faq : local.faq) ?? [],
140
+ pages: (sonor.pages?.length ? sonor.pages : local.pages) ?? [],
141
+ portfolio: (sonor.portfolio?.length ? sonor.portfolio : local.portfolio) ?? []
142
+ };
143
+ }
144
+
104
145
  // src/llms/links.ts
105
146
  var ABSOLUTE_URL = /https?:\/\/[^\s<>()[\]"'`]+/g;
106
147
  var RELATIVE_LINK_TARGET = /\]\((\/(?!\/)[^)\s]*)/g;
@@ -138,19 +179,6 @@ function resolveBaseUrl(optionBaseUrl, businessWebsite) {
138
179
  const candidate = optionBaseUrl || businessWebsite || process.env.NEXT_PUBLIC_SITE_URL || process.env.SITE_URL || "";
139
180
  return candidate.trim().replace(/\/+$/, "");
140
181
  }
141
- function mergeLLMsData(portal, local) {
142
- if (!local) return portal;
143
- if (!portal) return local;
144
- return {
145
- meta: mergeLlmsMeta(local.meta, portal.meta),
146
- business: portal.business ?? local.business,
147
- contact: portal.contact ?? local.contact,
148
- services: (portal.services?.length ? portal.services : local.services) ?? [],
149
- faq: (portal.faq?.length ? portal.faq : local.faq) ?? [],
150
- pages: (portal.pages?.length ? portal.pages : local.pages) ?? [],
151
- portfolio: (portal.portfolio?.length ? portal.portfolio : local.portfolio) ?? []
152
- };
153
- }
154
182
  async function generateLLMsTxt(options) {
155
183
  const {
156
184
  projectId,
@@ -182,11 +210,10 @@ async function generateLLMsTxt(options) {
182
210
  } = options;
183
211
  const readFetch = fresh ? freshFetch : fetch;
184
212
  let data = await getLLMsData(projectId, site, fresh);
185
- const useLocal = getLocalData && (!data || !data.services?.length);
186
- if (useLocal && getLocalData) {
213
+ if (getLocalData && needsLocalData(data)) {
187
214
  try {
188
215
  const local = await getLocalData();
189
- data = mergeLLMsData(data ?? null, local);
216
+ data = mergeLlmsData(data ?? null, local, mergeLlmsMeta);
190
217
  } catch (err) {
191
218
  console.warn("[site-kit] getLocalData failed:", err);
192
219
  }
@@ -222,11 +249,32 @@ async function generateLLMsTxt(options) {
222
249
  sections.push(about);
223
250
  sectionNames.push("about");
224
251
  }
252
+ if (includeContact) {
253
+ const contact = generateContactSection(data.contact);
254
+ if (contact) {
255
+ sections.push(contact);
256
+ sectionNames.push("contact");
257
+ }
258
+ }
225
259
  if (includeServices && data.services?.length > 0) {
226
- const services = generateServicesSection(data.services);
260
+ const services = generateServicesSection(data.services, baseUrl);
227
261
  sections.push(services);
228
262
  sectionNames.push("services");
229
263
  }
264
+ const renderOptional = optionalPagePaths.length > 0 && Boolean(baseUrl);
265
+ const optionalKeys = renderOptional ? new Set(optionalPagePaths.map(normalizeLlmsPagePath)) : null;
266
+ const listable = listablePages(data.pages ?? []);
267
+ const indexPages = optionalKeys ? listable.filter((p) => !optionalKeys.has(normalizeLlmsPagePath(p.path))) : listable;
268
+ if (includePages && indexPages.length > 0) {
269
+ const pages = generatePagesSection(
270
+ selectLlmsPages(indexPages, maxPages),
271
+ baseUrl,
272
+ pageListNotesFromPublicSummaryOnly,
273
+ data.business?.name
274
+ );
275
+ sections.push(pages);
276
+ sectionNames.push("pages");
277
+ }
230
278
  if (includePortfolio) {
231
279
  let portfolioItems = data.portfolio || [];
232
280
  if (portfolioItems.length === 0) {
@@ -262,41 +310,11 @@ async function generateLLMsTxt(options) {
262
310
  sectionNames.push("portfolio");
263
311
  }
264
312
  }
265
- if (includeContact && data.contact) {
266
- const contact = generateContactSection(data.contact);
267
- sections.push(contact);
268
- sectionNames.push("contact");
269
- }
270
313
  if (includeFAQ && data.faq?.length > 0) {
271
314
  const faq = generateFAQSection(data.faq.slice(0, maxFAQItems));
272
315
  sections.push(faq);
273
316
  sectionNames.push("faq");
274
317
  }
275
- const renderOptional = optionalPagePaths.length > 0 && Boolean(baseUrl);
276
- const optionalKeys = renderOptional ? new Set(optionalPagePaths.map(normalizeLlmsPagePath)) : null;
277
- const indexPages = optionalKeys ? (data.pages ?? []).filter((p) => !optionalKeys.has(normalizeLlmsPagePath(p.path))) : data.pages ?? [];
278
- if (includePages && indexPages.length > 0) {
279
- const pages = generatePagesSection(
280
- indexPages.slice(0, maxPages),
281
- baseUrl,
282
- pageListNotesFromPublicSummaryOnly
283
- );
284
- sections.push(pages);
285
- sectionNames.push("pages");
286
- }
287
- if (renderOptional) {
288
- const opt = generateOptionalPagesSection(
289
- optionalPagePaths,
290
- data.pages || [],
291
- baseUrl,
292
- pageListNotesFromPublicSummaryOnly,
293
- trailingSlash
294
- );
295
- if (opt) {
296
- sections.push(opt);
297
- sectionNames.push("optional");
298
- }
299
- }
300
318
  if (linkToFullLlms && baseUrl) {
301
319
  const fullPath = fullLlmsTxtPath.startsWith("/") ? fullLlmsTxtPath : `/${fullLlmsTxtPath}`;
302
320
  const fullUrl = fullPath.startsWith("http") ? fullPath : `${baseUrl}${fullPath}`;
@@ -312,7 +330,7 @@ async function generateLLMsTxt(options) {
312
330
  if (includeEntities) {
313
331
  attemptedSections.push("knowledge-graph");
314
332
  optionalFetches.push(
315
- import('./server-api-EGOKC7Q3.js').then(async ({ getEntities, getPrimaryEntity }) => {
333
+ import('./server-api-XIKDWSNO.js').then(async ({ getEntities, getPrimaryEntity }) => {
316
334
  const [entities, primaryEntity] = await Promise.all([
317
335
  getEntities().then((e) => e.slice(0, maxEntities)),
318
336
  getPrimaryEntity()
@@ -389,6 +407,20 @@ ${custom.content}`);
389
407
  sections.splice(index, 0, formatAgentAccessSection(baseUrl, agentOptions));
390
408
  sectionNames.splice(index, 0, "agent-access");
391
409
  }
410
+ if (renderOptional) {
411
+ const opt = generateOptionalPagesSection(
412
+ optionalPagePaths,
413
+ data.pages || [],
414
+ baseUrl,
415
+ pageListNotesFromPublicSummaryOnly,
416
+ trailingSlash,
417
+ data.business?.name
418
+ );
419
+ if (opt) {
420
+ sections.push(opt);
421
+ sectionNames.push("optional");
422
+ }
423
+ }
392
424
  return {
393
425
  // Every own-site link (pages, clusters, portfolio, custom sections) takes
394
426
  // the site's trailing-slash shape in one pass.
@@ -442,8 +474,7 @@ function generateHeaderSection(business, meta, resolvedBaseUrl) {
442
474
  const lines = [];
443
475
  lines.push(`# ${business.name}`);
444
476
  lines.push("");
445
- const summary = business.tagline || business.description?.split(".")[0] || business.name;
446
- lines.push(`> ${summary}`);
477
+ lines.push(`> ${llmsBlockquoteSummary(business)}`);
447
478
  if (meta?.last_updated) {
448
479
  lines.push(`> Content index last updated: ${meta.last_updated}`);
449
480
  }
@@ -477,13 +508,13 @@ function generateAboutSection(business) {
477
508
  }
478
509
  return lines.join("\n");
479
510
  }
480
- function generateServicesSection(services) {
511
+ function generateServicesSection(services, baseUrl) {
481
512
  const lines = [];
482
513
  lines.push("## Services");
483
514
  lines.push("");
484
515
  for (const service of services) {
485
516
  if (service.url) {
486
- lines.push(`- **[${service.name}](${service.url})**: ${service.description}`);
517
+ lines.push(`- **[${service.name}](${llmsAbsoluteUrl(baseUrl, service.url)})**: ${service.description}`);
487
518
  } else {
488
519
  lines.push(`- **${service.name}**: ${service.description}`);
489
520
  }
@@ -524,29 +555,8 @@ function generatePortfolioSection(items, baseUrl) {
524
555
  return lines.join("\n").trim();
525
556
  }
526
557
  function generateContactSection(contact) {
527
- const lines = [];
528
- lines.push("## Contact Information");
529
- lines.push("");
530
- if (contact.phone) {
531
- lines.push(`- **Phone:** ${contact.phone}`);
532
- }
533
- if (contact.email) {
534
- lines.push(`- **Email:** ${contact.email}`);
535
- }
536
- if (contact.address || contact.city) {
537
- const addressParts = [
538
- contact.address,
539
- contact.city,
540
- contact.state,
541
- contact.postal_code,
542
- contact.country
543
- ].filter(Boolean);
544
- lines.push(`- **Address:** ${addressParts.join(", ")}`);
545
- }
546
- if (contact.hours) {
547
- lines.push(`- **Hours:** ${contact.hours}`);
548
- }
549
- return lines.join("\n");
558
+ const lines = llmsContactLines(contact);
559
+ return lines.length > 0 ? ["## Contact Information", "", ...lines].join("\n") : null;
550
560
  }
551
561
  function generateFAQSection(faq) {
552
562
  const lines = [];
@@ -560,32 +570,42 @@ function generateFAQSection(faq) {
560
570
  }
561
571
  return lines.join("\n").trim();
562
572
  }
563
- function pageListNote(page, publicSummaryOnly) {
564
- const pub = sanitizeLlmsPublicSummary(page.llms_public_summary);
565
- if (pub) return pub;
566
- if (publicSummaryOnly) return void 0;
567
- if (page.description) return page.description.replace(/[\[\]\r\n]/g, " ").trim();
568
- return void 0;
573
+ function listablePages(pages) {
574
+ const seen = /* @__PURE__ */ new Set();
575
+ return pages.filter((page) => {
576
+ if (!page?.path || !isLlmsListablePage({ path: page.path })) return false;
577
+ const key = normalizeLlmsPagePath(page.path);
578
+ if (seen.has(key)) return false;
579
+ seen.add(key);
580
+ return true;
581
+ });
569
582
  }
570
583
  function normalizeLlmsPagePath(path) {
571
584
  const withLeading = path.startsWith("/") ? path : `/${path}`;
572
585
  return withLeading.replace(/\/$/, "") || "/";
573
586
  }
574
- function formatPageLine(page, baseUrl, publicSummaryOnly) {
587
+ function formatPageLine(page, baseUrl, publicSummaryOnly, homeName) {
575
588
  const url = page.path.startsWith("http") ? page.path : `${baseUrl}${page.path}`;
576
- const note = pageListNote(page, publicSummaryOnly);
577
- return note ? `- [${page.title}](${url}): ${note}` : `- [${page.title}](${url})`;
589
+ const title = llmsPageTitle({ path: page.path, title: page.title }, homeName).replace(/[[\]]/g, "");
590
+ const note = llmsPageListNote(page, publicSummaryOnly);
591
+ return note ? `- [${title}](${url}): ${note}` : `- [${title}](${url})`;
578
592
  }
579
- function generatePagesSection(pages, baseUrl, publicSummaryOnly) {
593
+ function generatePagesSection(pages, baseUrl, publicSummaryOnly, homeName) {
580
594
  const lines = [];
581
595
  lines.push("## Site Pages");
582
596
  lines.push("");
583
- for (const page of pages) {
584
- lines.push(formatPageLine(page, baseUrl, publicSummaryOnly));
585
- }
597
+ groupLlmsPages(pages).forEach((group, i) => {
598
+ if (group.heading) {
599
+ if (i > 0) lines.push("");
600
+ lines.push(`### ${group.heading}`, "");
601
+ }
602
+ for (const page of group.pages) {
603
+ lines.push(formatPageLine(page, baseUrl, publicSummaryOnly, homeName));
604
+ }
605
+ });
586
606
  return lines.join("\n");
587
607
  }
588
- function generateOptionalPagesSection(paths, pages, baseUrl, publicSummaryOnly, trailingSlash) {
608
+ function generateOptionalPagesSection(paths, pages, baseUrl, publicSummaryOnly, trailingSlash, homeName) {
589
609
  const byPath = /* @__PURE__ */ new Map();
590
610
  for (const page of pages) {
591
611
  const key = normalizeLlmsPagePath(page.path);
@@ -599,7 +619,7 @@ function generateOptionalPagesSection(paths, pages, baseUrl, publicSummaryOnly,
599
619
  seen.add(key);
600
620
  const match = byPath.get(key);
601
621
  if (match) {
602
- lines.push(formatPageLine(match, baseUrl, publicSummaryOnly));
622
+ lines.push(formatPageLine(match, baseUrl, publicSummaryOnly, homeName));
603
623
  continue;
604
624
  }
605
625
  const title = key.split("/").filter(Boolean).pop() || key;
@@ -0,0 +1 @@
1
+
@@ -1,7 +1,7 @@
1
1
  import { trackedFreshFetch } from './chunk-UAYAJPEP.js';
2
2
  import { isNextControlFlow } from './chunk-C7TLGL3R.js';
3
3
  import { monotonicMs } from './chunk-MH2DSGC6.js';
4
- import { SITE_KIT_VERSION } from './chunk-BUE3Z32O.js';
4
+ import { SITE_KIT_VERSION } from './chunk-F6WLHVMQ.js';
5
5
  import 'server-only';
6
6
 
7
7
  var MINT_PATH = "/api/public/site-token";