@sonordev/site-kit 7.0.2 → 7.1.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 (125) hide show
  1. package/CHANGELOG.md +67 -0
  2. package/agent-manifest.json +11 -5
  3. package/dist/{AnalyticsProvider-XXWTFKJH.js → AnalyticsProvider-ZMQUV33M.js} +4 -4
  4. package/dist/{ArticleViewTracker-V4KZB6QN.js → ArticleViewTracker-V7NUXYBY.js} +3 -3
  5. package/dist/{BlocksPopup-JHGHB6XW.js → BlocksPopup-52EU7OUY.js} +4 -4
  6. package/dist/{ChatWidget-CG32POI3.js → ChatWidget-5BHMNR57.js} +5 -5
  7. package/dist/{EngageWidget-LQMR4LEX.js → EngageWidget-PCGLX7SO.js} +4 -4
  8. package/dist/{FileField-KUG3CKXG.js → FileField-TSFGNAMY.js} +3 -3
  9. package/dist/{FormSpotlight-FVNPOCU3.js → FormSpotlight-XLBWEOTE.js} +1 -1
  10. package/dist/{FormStage-C7VKRURJ.js → FormStage-IJQ5Q2X6.js} +1 -1
  11. package/dist/{ManagedForm-VLNJKV65.js → ManagedForm-Z3PKOPIZ.js} +6 -6
  12. package/dist/{ManagedNewsletterForm-KJEU23BV.js → ManagedNewsletterForm-QAO3POLC.js} +4 -4
  13. package/dist/{SignalCore-K2O46QG7.js → SignalCore-RBA3VDBL.js} +3 -3
  14. package/dist/{SiteDesignReporter-D7MD66GI.js → SiteDesignReporter-C4LR5X2V.js} +5 -5
  15. package/dist/SitemapSync-XVMGKCF3.js +8 -0
  16. package/dist/_client/booking-widget.js +5 -5
  17. package/dist/affiliates/index.js +3 -3
  18. package/dist/analytics/index.js +4 -4
  19. package/dist/articles/index.js +1 -1
  20. package/dist/articles/server-ui.js +1 -1
  21. package/dist/chat/index.js +5 -5
  22. package/dist/{chunk-GYY6ETGB.js → chunk-3G2SE2J4.js} +1 -1
  23. package/dist/{chunk-GGD4P7UW.js → chunk-3J2ERO3I.js} +1 -1
  24. package/dist/{chunk-KXPBMCFL.js → chunk-3QI26673.js} +3 -1
  25. package/dist/{chunk-7JIKGKWD.js → chunk-3XPJKZ6D.js} +30 -7
  26. package/dist/{chunk-B6RZ2NRH.js → chunk-4JQQDCMO.js} +1 -1
  27. package/dist/{chunk-6HDT4G4A.js → chunk-4YTYGG2C.js} +2 -2
  28. package/dist/{chunk-N2UVOR3X.js → chunk-662ILEZ6.js} +2 -0
  29. package/dist/chunk-6G43IRWR.js +4 -0
  30. package/dist/{chunk-LVESVYCE.js → chunk-7MHHWZKC.js} +11 -117
  31. package/dist/{chunk-5FBY2ZIH.js → chunk-7QTMMHUO.js} +1 -1
  32. package/dist/{chunk-KPAZG65P.js → chunk-CGWUXUYZ.js} +138 -46
  33. package/dist/{chunk-LJZ3SUET.js → chunk-DUAO4Q75.js} +2 -2
  34. package/dist/{chunk-P72ZJRSX.js → chunk-EIULXXUJ.js} +3 -3
  35. package/dist/{chunk-OIETJKIL.js → chunk-EVFZ7KEW.js} +1 -1
  36. package/dist/{chunk-BEL7YFMC.js → chunk-F42R35NV.js} +1 -1
  37. package/dist/{chunk-42OXY4JV.js → chunk-FLR3EMK6.js} +1 -1
  38. package/dist/{chunk-ZRE4ZYEG.js → chunk-GIAOPEN6.js} +1 -1
  39. package/dist/{chunk-O52CH273.js → chunk-GWUKQ26F.js} +1 -1
  40. package/dist/{chunk-TT63HHIT.js → chunk-HAG4YIZY.js} +1 -1
  41. package/dist/{chunk-SAUTJMK6.js → chunk-HVH37YPX.js} +1 -1
  42. package/dist/{chunk-SSUQKA7L.js → chunk-J4D6ZXRW.js} +1 -1
  43. package/dist/{chunk-56JNI463.js → chunk-L2DJD5Y4.js} +1 -1
  44. package/dist/{chunk-BS7FWUOY.js → chunk-LFXVE32I.js} +1 -1
  45. package/dist/chunk-LPH5FANE.js +169 -0
  46. package/dist/{chunk-P2GIIQH5.js → chunk-PLUP2KN5.js} +1 -1
  47. package/dist/chunk-RYVDGXC2.js +19 -0
  48. package/dist/{chunk-RU2RMTGT.js → chunk-U35H2JIQ.js} +2 -2
  49. package/dist/chunk-VCJYLYJV.js +49 -0
  50. package/dist/{chunk-DKTSGYLM.js → chunk-W2CL2DB3.js} +2 -2
  51. package/dist/{chunk-ZSLRAMCK.js → chunk-XD3ZQET6.js} +1 -1
  52. package/dist/{chunk-K5WZX776.js → chunk-XNVSCQ2O.js} +2 -2
  53. package/dist/{chunk-SWP36NCB.js → chunk-YLSEB32F.js} +1 -1
  54. package/dist/chunk-ZETJTCMV.js +118 -0
  55. package/dist/{chunk-T4SY3FMN.js → chunk-ZIMFQWGJ.js} +3 -3
  56. package/dist/client/index.js +3 -3
  57. package/dist/cms/CmsPage.d.ts +1 -0
  58. package/dist/cms/CmsPreview.d.ts +1 -0
  59. package/dist/cms/CmsSection.d.ts +1 -0
  60. package/dist/cms/index.d.ts +6 -0
  61. package/dist/cms/server-api.d.ts +3 -0
  62. package/dist/commerce/index.js +4 -4
  63. package/dist/config/index.js +1 -1
  64. package/dist/contracts/entries.d.ts +1 -1
  65. package/dist/contracts/site-cache.d.ts +55 -0
  66. package/dist/contracts/site-edit-param.d.ts +7 -0
  67. package/dist/contracts/site-edit.d.ts +77 -0
  68. package/dist/contracts/slot-content.d.ts +111 -0
  69. package/dist/contracts/slots.d.ts +39 -25
  70. package/dist/engage/index.js +6 -6
  71. package/dist/fleet/index.js +4 -4
  72. package/dist/forms/index.js +8 -8
  73. package/dist/forms/server.js +2 -2
  74. package/dist/images/index.js +4 -4
  75. package/dist/index.js +1 -1
  76. package/dist/layout/client.js +8 -7
  77. package/dist/layout/index.js +9 -8
  78. package/dist/llms/index.js +4 -2
  79. package/dist/llms/seo-revalidate.d.ts +8 -1
  80. package/dist/maps/index.js +3 -3
  81. package/dist/mcp/sonor.js +6 -6
  82. package/dist/overlay-RXV6U6QC.js +353 -0
  83. package/dist/proxy/index.js +2 -2
  84. package/dist/proxy/securityHeaders.d.ts +4 -0
  85. package/dist/revalidate/index.d.ts +44 -0
  86. package/dist/revalidate/index.js +27 -0
  87. package/dist/seo/ManagedContent.d.ts +2 -0
  88. package/dist/seo/client.js +4 -4
  89. package/dist/seo/index.js +9 -8
  90. package/dist/seo/llms.js +4 -2
  91. package/dist/seo/register-sitemap-cli.js +1 -1
  92. package/dist/seo/server.js +3 -2
  93. package/dist/seo/sitemap.js +2 -2
  94. package/dist/server/index.js +2 -2
  95. package/dist/{server-api-GJJQZVG7.js → server-api-BVCBLJKL.js} +2 -1
  96. package/dist/shared/build-entries.d.ts +1 -0
  97. package/dist/shared/edit-bridge.d.ts +8 -0
  98. package/dist/shared/version.d.ts +1 -1
  99. package/dist/signal/index.js +2 -2
  100. package/dist/sitemap/index.js +2 -2
  101. package/dist/slots/ManagedLink.d.ts +31 -0
  102. package/dist/slots/ManagedList.d.ts +30 -0
  103. package/dist/slots/ManagedRichText.d.ts +31 -0
  104. package/dist/slots/contract.js +2 -1
  105. package/dist/slots/edit/locate.d.ts +30 -0
  106. package/dist/slots/edit/overlay.d.ts +18 -0
  107. package/dist/slots/index.d.ts +12 -4
  108. package/dist/slots/index.js +4 -2
  109. package/dist/slots/revalidate.d.ts +8 -3
  110. package/dist/slots/rich.d.ts +7 -0
  111. package/dist/slots/server-api.d.ts +6 -2
  112. package/dist/sync/index.js +5 -5
  113. package/dist/website/images.js +4 -4
  114. package/dist/website/index.js +5 -5
  115. package/dist/website/popups.js +4 -4
  116. package/dist/website/slots/contract.js +2 -1
  117. package/dist/website/slots.js +4 -2
  118. package/dist/{writeLLMsTxt-UMHKGNRR.js → writeLLMsTxt-QR23OQUE.js} +1 -1
  119. package/docs.json +2 -0
  120. package/package.json +6 -1
  121. package/src/revalidate/README.md +82 -0
  122. package/src/seo/README.md +4 -17
  123. package/src/slots/README.md +168 -0
  124. package/dist/SitemapSync-NMXGMPCQ.js +0 -8
  125. package/dist/chunk-SS636UDN.js +0 -35
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Edit on page: the messages between a site and the Sonor dashboard.
3
+ *
4
+ * The dashboard frames the live site with `?sonor_edit=1`. site-kit sees that
5
+ * it's framed by Sonor, finds the managed copy on the page and outlines it;
6
+ * a click selects a slot, and the dashboard edits it with the person's own
7
+ * Sonor session. Nothing on the site writes anything: it reports what's where
8
+ * and shows a draft in place, and the dashboard does the rest. So the site
9
+ * needs no login, no secret and no cookie.
10
+ *
11
+ * site-kit's overlay (`slots/edit`) and the dashboard's visual editor both
12
+ * read this file. Pure: no DOM, no network.
13
+ */
14
+ import { type SlotContentType, type SlotValue } from './slot-content';
15
+ export { SITE_EDIT_PARAM } from './site-edit-param';
16
+ /** Protocol version, sent in `ready` so the dashboard can tell an old overlay. */
17
+ export declare const SITE_EDIT_VERSION = 1;
18
+ /** The dashboard's production origin. */
19
+ export declare const SONOR_APP_ORIGIN = "https://app.sonor.io";
20
+ /**
21
+ * Origins allowed to drive the overlay: the dashboard, and localhost for
22
+ * development. A localhost frame is the person's own machine; the overlay
23
+ * never exposes anything the framed page doesn't already show.
24
+ */
25
+ export declare function isSonorAppOrigin(origin: string): boolean;
26
+ /** What the dashboard asks the overlay to find: a slot as it's live now. */
27
+ export interface EditableSlot {
28
+ /** The slot's row id in Sonor. */
29
+ key: string;
30
+ /** The slot id in code, e.g. `home-hero-headline`. */
31
+ id: string;
32
+ type: SlotContentType;
33
+ /** What the page shows now: the published content, else the site's fallback. */
34
+ content: string | null;
35
+ value?: SlotValue | null;
36
+ }
37
+ /** Dashboard → site. */
38
+ export type SonorToSiteMessage = {
39
+ type: 'sonor-edit:slots';
40
+ slots: EditableSlot[];
41
+ } | {
42
+ type: 'sonor-edit:select';
43
+ key: string | null;
44
+ } | {
45
+ type: 'sonor-edit:preview';
46
+ key: string;
47
+ content?: string | null;
48
+ value?: SlotValue | null;
49
+ } | {
50
+ type: 'sonor-edit:reload';
51
+ };
52
+ /** Site → dashboard. */
53
+ export type SiteToSonorMessage = {
54
+ type: 'sonor-edit:ready';
55
+ version: number;
56
+ path: string;
57
+ title: string;
58
+ } | {
59
+ type: 'sonor-edit:found';
60
+ path: string;
61
+ found: string[];
62
+ } | {
63
+ type: 'sonor-edit:select';
64
+ key: string;
65
+ };
66
+ /** A message from the dashboard, or null for anything else (other scripts post messages too). */
67
+ export declare function parseSonorToSiteMessage(data: unknown): SonorToSiteMessage | null;
68
+ /** A message from the site, or null for anything else. */
69
+ export declare function parseSiteToSonorMessage(data: unknown): SiteToSonorMessage | null;
70
+ /** Collapse whitespace the way a browser lays text out. */
71
+ export declare function normalizeEditText(text: string): string;
72
+ /**
73
+ * The visible text the overlay looks for to find a slot on the page: the
74
+ * text itself, the first paragraph of rich text, a link's label, a list's
75
+ * item titles. Empty strings are dropped.
76
+ */
77
+ export declare function slotNeedles(slot: EditableSlot): string[];
@@ -0,0 +1,111 @@
1
+ /**
2
+ * @sonordev/contracts/slot-content — what a managed slot may contain.
3
+ *
4
+ * The pure half of the slots contract: content types, value validation
5
+ * (normalizeSlotValue), safe links, and the rich-text subset parser. No
6
+ * crypto, so the dashboard can import it in the browser to validate and
7
+ * preview exactly what sonor-api will accept and site-kit will render.
8
+ * `@sonordev/contracts/slots` re-exports all of it next to the signing.
9
+ */
10
+ /**
11
+ * - `text`: plain text, rendered escaped.
12
+ * - `rich`: the restricted markdown subset parseSlotRichText understands,
13
+ * rendered to elements, never HTML.
14
+ * - `link`: `{ label, href }`.
15
+ * - `list`: `{ items: [{ title?, body?, href?, image? }] }`.
16
+ */
17
+ export type SlotContentType = 'text' | 'rich' | 'link' | 'list';
18
+ export declare const SLOT_CONTENT_TYPES: readonly SlotContentType[];
19
+ /** What a v1 client can render. */
20
+ export declare const SLOT_V1_CONTENT_TYPES: readonly SlotContentType[];
21
+ /** Hard cap on managed content length; longer payloads are rejected → fallback. */
22
+ export declare const SLOT_CONTENT_MAX_LENGTH = 10000;
23
+ /** Caps for structured values. */
24
+ export declare const SLOT_LIST_MAX_ITEMS = 50;
25
+ export declare const SLOT_FIELD_MAX_LENGTH = 2000;
26
+ export declare const SLOT_HREF_MAX_LENGTH = 2048;
27
+ /** Slot ids: lowercase, page-scoped by convention, e.g. "home-hero-headline". */
28
+ export declare const SLOT_ID_PATTERN: RegExp;
29
+ export interface SlotLinkValue {
30
+ label: string;
31
+ href: string;
32
+ }
33
+ export interface SlotListImage {
34
+ /** https only. */
35
+ src: string;
36
+ alt: string;
37
+ width?: number;
38
+ height?: number;
39
+ }
40
+ export interface SlotListItem {
41
+ title?: string;
42
+ /** Plain text. */
43
+ body?: string;
44
+ href?: string;
45
+ image?: SlotListImage;
46
+ }
47
+ export interface SlotListValue {
48
+ items: SlotListItem[];
49
+ }
50
+ /** The structured value for `link` and `list`; `text` and `rich` carry none. */
51
+ export type SlotValue = SlotLinkValue | SlotListValue;
52
+ export declare function isValidSlotId(id: string): boolean;
53
+ export declare function isSlotContentType(type: unknown): type is SlotContentType;
54
+ /** Links a slot may carry: https, http, mailto, tel, #anchor, or a root-relative path. */
55
+ export declare function isSafeSlotHref(href: unknown): href is string;
56
+ /** Images a list item may carry: https only. */
57
+ export declare function isSafeSlotImageSrc(src: unknown): src is string;
58
+ export type SlotValueResult = {
59
+ ok: true;
60
+ content: string;
61
+ value: SlotValue | null;
62
+ } | {
63
+ ok: false;
64
+ error: string;
65
+ };
66
+ /**
67
+ * Validate and normalize what an editor (or Signal) submits for a slot of
68
+ * `type`, returning the canonical `content` + `value` to store and sign.
69
+ * The single rule for "what a valid slot of this type is": sonor-api runs it
70
+ * on every write and verifySlotContent re-runs it on every read.
71
+ */
72
+ export declare function normalizeSlotValue(type: SlotContentType, input: {
73
+ content?: unknown;
74
+ value?: unknown;
75
+ }): SlotValueResult;
76
+ /** The plain-text rendering of a list: its titles (or bodies, or alts), one per line. */
77
+ export declare function slotListPlainText(items: SlotListItem[]): string;
78
+ export type SlotRichInline = {
79
+ t: 'text';
80
+ v: string;
81
+ } | {
82
+ t: 'strong';
83
+ c: SlotRichInline[];
84
+ } | {
85
+ t: 'em';
86
+ c: SlotRichInline[];
87
+ } | {
88
+ t: 'link';
89
+ href: string;
90
+ c: SlotRichInline[];
91
+ } | {
92
+ t: 'br';
93
+ };
94
+ export type SlotRichBlock = {
95
+ t: 'p';
96
+ c: SlotRichInline[];
97
+ } | {
98
+ t: 'ul';
99
+ items: SlotRichInline[][];
100
+ } | {
101
+ t: 'ol';
102
+ items: SlotRichInline[][];
103
+ };
104
+ /**
105
+ * Parse the rich-text subset into a tiny AST: paragraphs (blank-line
106
+ * separated; single newlines become line breaks), `-`/`*` and `1.` lists,
107
+ * `**bold**`, `*italic*` / `_italic_`, and `[text](href)` with a safe href.
108
+ * Anything else is literal text. No HTML, ever: a renderer maps these nodes
109
+ * to elements, so there's nothing to sanitize.
110
+ */
111
+ export declare function parseSlotRichText(markdown: string): SlotRichBlock[];
@@ -1,33 +1,37 @@
1
1
  /**
2
- * @sonordev/contracts/slots — Managed Slots wire contract (v1)
2
+ * @sonordev/contracts/slots — Managed Slots wire contract (v2)
3
3
  *
4
- * Single source of truth for the slot payload shape and content signing,
5
- * shared by site-kit (verify side) and sonor-api (sign side). Node only: it
6
- * signs with `crypto`.
4
+ * Single source of truth for the slot payload shape, value validation, the
5
+ * rich-text subset, and content signing, shared by site-kit (verify + render),
6
+ * sonor-api (validate + sign) and the dashboard (preview). Node only: it signs
7
+ * with `crypto`.
7
8
  *
8
9
  * Security model: every SlotContent is HMAC-signed with the project API key.
9
10
  * site-kit verifies before rendering and falls back to the developer's static
10
11
  * content on any mismatch, so platform-originated content carries provenance
11
- * end to end. See docs/SITE-KIT-3.0-SPEC-SLOTS.md.
12
- */
13
- /** Bump on breaking payload changes. */
14
- export declare const SLOTS_CONTRACT_VERSION = 1;
15
- /**
16
- * v1 supports plain text only — rendered as React text (escaped), never
17
- * dangerouslySetInnerHTML. 'markdown' / 'rich' are reserved for a future
18
- * contract version behind a real sanitizer decision.
12
+ * end to end. See docs/SITE-KIT-3.0-SPEC-SLOTS.md and docs/WEBSITE-CMS.md.
13
+ *
14
+ * v1 (site-kit ≤ 7.0) is plain text only. v2 adds rich text, links and lists,
15
+ * and signs the structured value too. sonor-api serves both: a v1 request gets
16
+ * text slots signed the v1 way and null for everything else.
19
17
  */
20
- export type SlotContentType = 'text';
21
- export declare const SLOT_CONTENT_TYPES: readonly SlotContentType[];
22
- /** Hard cap on managed content length; longer payloads are rejected → fallback. */
23
- export declare const SLOT_CONTENT_MAX_LENGTH = 10000;
24
- /** Slot ids: lowercase, page-scoped by convention, e.g. "home-hero-headline". */
25
- export declare const SLOT_ID_PATTERN: RegExp;
18
+ import { type SlotContentType, type SlotValue } from './slot-content';
19
+ export * from './slot-content';
20
+ /** The version this package speaks. Bump on breaking payload changes. */
21
+ export declare const SLOTS_CONTRACT_VERSION = 2;
22
+ /** Versions sonor-api still serves. */
23
+ export declare const SUPPORTED_SLOTS_CONTRACT_VERSIONS: readonly number[];
26
24
  export interface SlotContent {
27
25
  slot_id: string;
28
26
  type: SlotContentType;
29
- /** The managed text. Rendered escaped — never as HTML. */
27
+ /**
28
+ * Always a non-empty plain-text rendering: the text (text), the markdown
29
+ * (rich), the label (link), the item titles (list). Rendered escaped for
30
+ * `text`; the Copy Evidence Loop and Signal read it for every type.
31
+ */
30
32
  content: string;
33
+ /** Structured value for `link` / `list` (v2). */
34
+ value?: SlotValue | null;
31
35
  /** Forward-compat: experiment/personalization variant that produced this content. */
32
36
  variant_id?: string | null;
33
37
  experiment_id?: string | null;
@@ -38,6 +42,8 @@ export interface SlotContent {
38
42
  }
39
43
  export interface SlotResolveRequestEntry {
40
44
  id: string;
45
+ /** v2: what the site renders this slot as. Absent = 'text' (v1). */
46
+ type?: SlotContentType;
41
47
  /**
42
48
  * The developer's current static text for this slot (when statically
43
49
  * extractable). Stored as `fallback_text` on registration so the dashboard
@@ -45,6 +51,8 @@ export interface SlotResolveRequestEntry {
45
51
  * the API anywhere — display + drafting context only.
46
52
  */
47
53
  fallback?: string;
54
+ /** v2: the structured fallback (a link or list the site ships), for the editor. */
55
+ fallback_value?: SlotValue;
48
56
  /**
49
57
  * The route this slot renders on (e.g. "/" or "/pricing"). A static literal,
50
58
  * never derived from the request — it feeds the Copy Evidence Loop's
@@ -62,20 +70,26 @@ export interface SlotsResolveResponse {
62
70
  contract_version: number;
63
71
  slots: Record<string, SlotContent | null>;
64
72
  }
65
- export declare function isValidSlotId(id: string): boolean;
73
+ /** JSON with object keys sorted at every level, so both sides sign the same bytes. */
74
+ export declare function canonicalJson(value: unknown): string;
75
+ type Signable = Pick<SlotContent, 'slot_id' | 'type' | 'content'> & {
76
+ value?: SlotValue | null;
77
+ };
66
78
  /**
67
79
  * Canonical string both sides sign/verify. Exported separately from the HMAC
68
80
  * helpers so an edge-runtime resolver can reproduce it with WebCrypto.
81
+ * `version` 1 is the pre-v2 text-only form, kept byte-for-byte so sites on
82
+ * older site-kit keep verifying.
69
83
  */
70
- export declare function slotSigningPayload(content: Pick<SlotContent, 'slot_id' | 'type' | 'content'>): string;
84
+ export declare function slotSigningPayload(content: Signable, version?: number): string;
71
85
  /**
72
86
  * Sign slot content with the project API key (sonor-api side).
73
87
  * Returns the hex HMAC-SHA256 signature.
74
88
  */
75
- export declare function signSlotContent(content: Pick<SlotContent, 'slot_id' | 'type' | 'content'>, apiKey: string): string;
89
+ export declare function signSlotContent(content: Signable, apiKey: string, version?: number): string;
76
90
  /**
77
91
  * Verify a slot payload's shape + signature (site-kit side).
78
- * Returns true only when the payload is well-formed, within limits, and the
79
- * signature matches the project API key. Constant-time comparison.
92
+ * Returns true only when the payload is well-formed for its type, within
93
+ * limits, and the signature matches the project API key. Constant-time.
80
94
  */
81
- export declare function verifySlotContent(content: unknown, apiKey: string): content is SlotContent;
95
+ export declare function verifySlotContent(content: unknown, apiKey: string, version?: number): content is SlotContent;
@@ -1,10 +1,10 @@
1
1
  'use client';
2
- export { ChatWidget } from '../chunk-LJZ3SUET.js';
2
+ export { ChatWidget } from '../chunk-DUAO4Q75.js';
3
3
  import '../chunk-JE4A5S4F.js';
4
- export { DesignRenderer, EngageWidget } from '../chunk-T4SY3FMN.js';
4
+ export { DesignRenderer, EngageWidget } from '../chunk-ZIMFQWGJ.js';
5
5
  import '../chunk-NDF4A5JM.js';
6
6
  import '../chunk-6T6CQVNL.js';
7
- import '../chunk-ZSLRAMCK.js';
7
+ import '../chunk-XD3ZQET6.js';
8
8
  import '../chunk-AQSNPZY4.js';
9
9
  import '../chunk-5SQK3D53.js';
10
10
  import '../chunk-NJCTQH2P.js';
@@ -14,9 +14,9 @@ import '../chunk-L2V5PUFN.js';
14
14
  import '../chunk-GJWI74ZZ.js';
15
15
  import '../chunk-43OCZ3JA.js';
16
16
  import '../chunk-EKBEOXTH.js';
17
- import '../chunk-RU2RMTGT.js';
18
- import '../chunk-OIETJKIL.js';
19
- import '../chunk-B6RZ2NRH.js';
17
+ import '../chunk-U35H2JIQ.js';
18
+ import '../chunk-EVFZ7KEW.js';
19
+ import '../chunk-4JQQDCMO.js';
20
20
  import '../chunk-PKBMQBKP.js';
21
21
 
22
22
  // src/engage/echo-config.ts
@@ -1,10 +1,10 @@
1
1
  'use client';
2
- export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat } from '../chunk-K5WZX776.js';
2
+ export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat } from '../chunk-XNVSCQ2O.js';
3
3
  export { FLEET_CONTRACT_VERSION, FLEET_MODULES, FLEET_MODULES_MAX, FLEET_SITE_MAX_LENGTH, FLEET_VERSION_MAX_LENGTH, FLEET_VERSION_PATTERN, buildFleetHeartbeatPayload, isFleetModule, normalizeFleetModules, normalizeFleetSite, sanitizeFleetVersion } from '../chunk-ZTZQPYP6.js';
4
4
  import '../chunk-YC7ELZS3.js';
5
5
  import '../chunk-43OCZ3JA.js';
6
6
  import '../chunk-EKBEOXTH.js';
7
- import '../chunk-RU2RMTGT.js';
8
- import '../chunk-OIETJKIL.js';
9
- import '../chunk-B6RZ2NRH.js';
7
+ import '../chunk-U35H2JIQ.js';
8
+ import '../chunk-EVFZ7KEW.js';
9
+ import '../chunk-4JQQDCMO.js';
10
10
  import '../chunk-PKBMQBKP.js';
@@ -1,21 +1,21 @@
1
1
  'use client';
2
- export { FormClient, ManagedForm } from '../chunk-P72ZJRSX.js';
3
- import '../chunk-SWP36NCB.js';
4
- export { DatePicker } from '../chunk-SOD2F6C2.js';
5
2
  export { FormCelebration } from '../chunk-YGGDU6C3.js';
6
- export { FormEnhancer } from '../chunk-42OXY4JV.js';
3
+ export { FormClient, ManagedForm } from '../chunk-EIULXXUJ.js';
4
+ import '../chunk-YLSEB32F.js';
5
+ export { DatePicker } from '../chunk-SOD2F6C2.js';
6
+ export { FormEnhancer } from '../chunk-FLR3EMK6.js';
7
7
  import '../chunk-YC7ELZS3.js';
8
8
  import '../chunk-DXO6SBMD.js';
9
9
  export { FormField as FormFieldComponent } from '../chunk-QPEEKFCA.js';
10
- export { useForm, useFormTracking } from '../chunk-ZSLRAMCK.js';
10
+ export { useForm, useFormTracking } from '../chunk-XD3ZQET6.js';
11
11
  import '../chunk-AQSNPZY4.js';
12
12
  export { DEFAULT_FORM_SUCCESS_MESSAGE } from '../chunk-5SQK3D53.js';
13
13
  import '../chunk-NJCTQH2P.js';
14
14
  import '../chunk-L2V5PUFN.js';
15
15
  import '../chunk-GJWI74ZZ.js';
16
- import { sonorFetch } from '../chunk-RU2RMTGT.js';
17
- import '../chunk-OIETJKIL.js';
18
- import '../chunk-B6RZ2NRH.js';
16
+ import { sonorFetch } from '../chunk-U35H2JIQ.js';
17
+ import '../chunk-EVFZ7KEW.js';
18
+ import '../chunk-4JQQDCMO.js';
19
19
  import '../chunk-PKBMQBKP.js';
20
20
 
21
21
  // src/forms/formsApi.ts
@@ -1,5 +1,5 @@
1
- export { ServerForm, getFormConfig } from '../chunk-P2GIIQH5.js';
2
- import '../chunk-42OXY4JV.js';
1
+ export { ServerForm, getFormConfig } from '../chunk-PLUP2KN5.js';
2
+ import '../chunk-FLR3EMK6.js';
3
3
  import '../chunk-YC7ELZS3.js';
4
4
  export { StaticForm } from '../chunk-OPRBF7VE.js';
5
5
  import '../chunk-DXO6SBMD.js';
@@ -1,6 +1,6 @@
1
- export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from '../chunk-O52CH273.js';
1
+ export { ManagedImage, assignImageToSlot, clearImageSlot, fetchManagedImage, fetchManagedImages, listImageFiles, uploadImage } from '../chunk-GWUKQ26F.js';
2
2
  export { ManagedFavicon, getManagedFaviconUrl } from '../chunk-GW7GSBO7.js';
3
- import '../chunk-RU2RMTGT.js';
4
- import '../chunk-OIETJKIL.js';
5
- import '../chunk-B6RZ2NRH.js';
3
+ import '../chunk-U35H2JIQ.js';
4
+ import '../chunk-EVFZ7KEW.js';
5
+ import '../chunk-4JQQDCMO.js';
6
6
  import '../chunk-PKBMQBKP.js';
package/dist/index.js CHANGED
@@ -1,2 +1,2 @@
1
- export { SITE_KIT_VERSION } from './chunk-B6RZ2NRH.js';
1
+ export { SITE_KIT_VERSION } from './chunk-4JQQDCMO.js';
2
2
  import './chunk-PKBMQBKP.js';
@@ -1,9 +1,10 @@
1
1
  'use client';
2
- export { SiteKitClientProviders } from '../chunk-7JIKGKWD.js';
3
- import '../chunk-56JNI463.js';
4
- import '../chunk-K5WZX776.js';
2
+ export { SiteKitClientProviders } from '../chunk-3XPJKZ6D.js';
3
+ import '../chunk-6G43IRWR.js';
4
+ import '../chunk-L2DJD5Y4.js';
5
+ import '../chunk-XNVSCQ2O.js';
5
6
  import '../chunk-ZTZQPYP6.js';
6
- import '../chunk-SAUTJMK6.js';
7
+ import '../chunk-HVH37YPX.js';
7
8
  import '../chunk-YC7ELZS3.js';
8
9
  import '../chunk-FESKKJAS.js';
9
10
  import '../chunk-A4CC4ZG3.js';
@@ -11,7 +12,7 @@ import '../chunk-24QZEO3Q.js';
11
12
  import '../chunk-GJWI74ZZ.js';
12
13
  import '../chunk-43OCZ3JA.js';
13
14
  import '../chunk-EKBEOXTH.js';
14
- import '../chunk-RU2RMTGT.js';
15
- import '../chunk-OIETJKIL.js';
16
- import '../chunk-B6RZ2NRH.js';
15
+ import '../chunk-U35H2JIQ.js';
16
+ import '../chunk-EVFZ7KEW.js';
17
+ import '../chunk-4JQQDCMO.js';
17
18
  import '../chunk-PKBMQBKP.js';
@@ -1,11 +1,12 @@
1
- import { SiteKitClientProviders } from '../chunk-7JIKGKWD.js';
2
- import '../chunk-56JNI463.js';
3
- import '../chunk-K5WZX776.js';
1
+ import { SiteKitClientProviders } from '../chunk-3XPJKZ6D.js';
2
+ import '../chunk-6G43IRWR.js';
3
+ import '../chunk-L2DJD5Y4.js';
4
+ import '../chunk-XNVSCQ2O.js';
4
5
  import '../chunk-ZTZQPYP6.js';
5
6
  import { ManagedFavicon } from '../chunk-GW7GSBO7.js';
6
- import '../chunk-SAUTJMK6.js';
7
+ import '../chunk-HVH37YPX.js';
7
8
  import '../chunk-YC7ELZS3.js';
8
- import { resolveClientCredential } from '../chunk-BEL7YFMC.js';
9
+ import { resolveClientCredential } from '../chunk-F42R35NV.js';
9
10
  import '../chunk-VX5CMNMM.js';
10
11
  import { ManagedScripts } from '../chunk-MVLMXC44.js';
11
12
  import { resolveApiOrigin } from '../chunk-X6F6SO4S.js';
@@ -16,9 +17,9 @@ import '../chunk-24QZEO3Q.js';
16
17
  import '../chunk-GJWI74ZZ.js';
17
18
  import '../chunk-43OCZ3JA.js';
18
19
  import '../chunk-EKBEOXTH.js';
19
- import '../chunk-RU2RMTGT.js';
20
- import '../chunk-OIETJKIL.js';
21
- import '../chunk-B6RZ2NRH.js';
20
+ import '../chunk-U35H2JIQ.js';
21
+ import '../chunk-EVFZ7KEW.js';
22
+ import '../chunk-4JQQDCMO.js';
22
23
  import '../chunk-PKBMQBKP.js';
23
24
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
24
25
 
@@ -1,9 +1,10 @@
1
- export { LEGACY_PUBLICATION_PATH, SEO_REVALIDATION_MAX_BODY_BYTES, SEO_REVALIDATION_MAX_ITEMS, createLLMsFullTxtHandler, createLLMsTxtHandler, createLlmsRevalidateHandler, createSeoRevalidationHandler, formatSourcedFactsSection, llmsResponseHeaders, parseSeoRevalidationPayload } from '../chunk-LVESVYCE.js';
1
+ export { createLLMsFullTxtHandler, createLLMsTxtHandler, formatSourcedFactsSection, llmsResponseHeaders } from '../chunk-ZETJTCMV.js';
2
2
  export { buildAiDiscoveryHeaders, wantsLlmsDiscoveryLink } from '../chunk-PO2TRJPY.js';
3
3
  export { AI_RETRIEVAL_CRAWLERS, AI_TRAINING_CRAWLERS, buildAiCrawlerRules, createRobotsTxtHandler } from '../chunk-QLTDFUJ7.js';
4
+ export { LEGACY_PUBLICATION_PATH, SEO_REVALIDATION_MAX_BODY_BYTES, SEO_REVALIDATION_MAX_ITEMS, createLlmsRevalidateHandler, createSeoRevalidationHandler, parseSeoRevalidationPayload } from '../chunk-7MHHWZKC.js';
4
5
  import '../chunk-XTRZGXB2.js';
5
6
  export { AEOBlock, AEOCitedContent, AEOClaim, AEOComparison, AEODefinition, AEOEntity, AEOProvenanceList, AEOStep, AEOSteps, AEOSummary, DEFAULT_SPEAKABLE_SELECTORS, SpeakableSchema, createSpeakableSchema, getSpeakableSelectorsForPage } from '../chunk-PSAG45YF.js';
6
- export { AGENT_ACCESS_HEADING, appendAgentAccessSection, describesMcp, detectMcpServer, formatAgentAccessSection, generateLLMsFullTxt, generateLLMsTxt, writeLLMsTxtToPublic } from '../chunk-SSUQKA7L.js';
7
+ export { AGENT_ACCESS_HEADING, appendAgentAccessSection, describesMcp, detectMcpServer, formatAgentAccessSection, generateLLMsFullTxt, generateLLMsTxt, writeLLMsTxtToPublic } from '../chunk-J4D6ZXRW.js';
7
8
  export { getBusinessInfo, getFAQItems, getLLMsData, getOptimizedLLMsTxt, getPageSummaries, getServices } from '../chunk-GLHQ3LRO.js';
8
9
  import '../chunk-L5UOHS6E.js';
9
10
  import '../chunk-WMVK77ND.js';
@@ -14,4 +15,5 @@ import '../chunk-MJP63SSS.js';
14
15
  import '../chunk-YVKRYQRG.js';
15
16
  import '../chunk-FESKKJAS.js';
16
17
  import '../chunk-A4CC4ZG3.js';
18
+ import '../chunk-4JQQDCMO.js';
17
19
  import '../chunk-PKBMQBKP.js';
@@ -31,7 +31,13 @@
31
31
  * ```
32
32
  *
33
33
  * Contract (POST, `Authorization: Bearer <SONOR_API_KEY>`, JSON):
34
- * `{ paths?: string[], path?: string, tags?: string[], tag?: string, revalidateAll?: boolean }`
34
+ * `{ paths?: string[], path?: string, tags?: string[], tag?: string, revalidateAll?: boolean, ping?: boolean }`
35
+ * (`SiteRevalidatePayload` in `@sonordev/contracts/site-cache`). `ping: true`
36
+ * regenerates nothing and answers `{ ok: true, ping: true, version }`, so Sonor
37
+ * can tell the route is installed and the key matches.
38
+ *
39
+ * Most sites don't call this directly: `@sonordev/site-kit/revalidate` is this
40
+ * handler preconfigured, so the route file is one line.
35
41
  */
36
42
  /** Largest webhook body accepted, in bytes. Sonor's payloads are a few hundred. */
37
43
  export declare const SEO_REVALIDATION_MAX_BODY_BYTES: number;
@@ -90,6 +96,7 @@ export declare function parseSeoRevalidationPayload(value: unknown): SeoRevalida
90
96
  /**
91
97
  * Create the POST handler for Sonor's SEO revalidation webhook.
92
98
  *
99
+ * - `{ ping: true }` (after the auth check) answers a pong and regenerates nothing.
93
100
  * - 401 unless `Authorization: Bearer <secret>` matches (constant time). The
94
101
  * `?secret=` query form `createLlmsRevalidateHandler` accepts is not
95
102
  * honoured here: keys don't belong in URLs.
@@ -1,8 +1,8 @@
1
1
  'use client';
2
2
  import { monotonicMs } from '../chunk-MH2DSGC6.js';
3
- import { sonorFetch } from '../chunk-RU2RMTGT.js';
4
- import '../chunk-OIETJKIL.js';
5
- import '../chunk-B6RZ2NRH.js';
3
+ import { sonorFetch } from '../chunk-U35H2JIQ.js';
4
+ import '../chunk-EVFZ7KEW.js';
5
+ import '../chunk-4JQQDCMO.js';
6
6
  import '../chunk-PKBMQBKP.js';
7
7
  import { useState, useCallback, useEffect } from 'react';
8
8
  import { APIProvider, Map as Map$1, AdvancedMarker, Pin, InfoWindow } from '@vis.gl/react-google-maps';
package/dist/mcp/sonor.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { toolErrorResult } from '../chunk-FYAB6CXS.js';
2
2
  import { fetchReviews, fetchReviewStats } from '../chunk-EDYHROQ7.js';
3
3
  import { getOfferings } from '../chunk-G3NHWMP5.js';
4
- import { fetchBookingTypes, fetchAvailability } from '../chunk-5FBY2ZIH.js';
4
+ import { fetchBookingTypes, fetchAvailability } from '../chunk-7QTMMHUO.js';
5
5
  import { getLLMsData, getServices, getFAQItems, getPageSummaries } from '../chunk-GLHQ3LRO.js';
6
- import { getFormConfig } from '../chunk-P2GIIQH5.js';
7
- import '../chunk-42OXY4JV.js';
6
+ import { getFormConfig } from '../chunk-PLUP2KN5.js';
7
+ import '../chunk-FLR3EMK6.js';
8
8
  import '../chunk-YC7ELZS3.js';
9
9
  import '../chunk-OPRBF7VE.js';
10
10
  import '../chunk-DXO6SBMD.js';
@@ -22,9 +22,9 @@ import { resolveSiteHost } from '../chunk-FESKKJAS.js';
22
22
  import '../chunk-A4CC4ZG3.js';
23
23
  import '../chunk-5SQK3D53.js';
24
24
  import '../chunk-NJCTQH2P.js';
25
- import '../chunk-RU2RMTGT.js';
26
- import '../chunk-OIETJKIL.js';
27
- import { SITE_KIT_VERSION } from '../chunk-B6RZ2NRH.js';
25
+ import '../chunk-U35H2JIQ.js';
26
+ import '../chunk-EVFZ7KEW.js';
27
+ import { SITE_KIT_VERSION } from '../chunk-4JQQDCMO.js';
28
28
  import '../chunk-PKBMQBKP.js';
29
29
  import 'server-only';
30
30
  import { after } from 'next/server.js';