@sonordev/site-kit 8.1.0 → 8.3.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 (194) hide show
  1. package/AGENTS.md +13 -1
  2. package/CHANGELOG.md +11 -0
  3. package/README.md +9 -5
  4. package/agent-manifest.json +47 -8
  5. package/dist/{AnalyticsProvider-UWTCE5UO.js → AnalyticsProvider-QXO33JUF.js} +6 -6
  6. package/dist/{ArticleFaqSection-3Q26DP7P.js → ArticleFaqSection-DEWE5B4Q.js} +1 -1
  7. package/dist/{ArticleViewTracker-MYD6SGNH.js → ArticleViewTracker-KN6ENIRS.js} +17 -6
  8. package/dist/{BlocksPopup-OY5G3EFH.js → BlocksPopup-3RPN6YVJ.js} +6 -6
  9. package/dist/{ChatWidget-BTR5VERC.js → ChatWidget-D2X445PO.js} +6 -6
  10. package/dist/{FileField-DEHVYXAO.js → FileField-UNGSNGJ5.js} +4 -4
  11. package/dist/{FormSpotlight-VGC4CZL4.js → FormSpotlight-JFH2ENKQ.js} +1 -1
  12. package/dist/{FormStage-CJUSCSAL.js → FormStage-RC3WHHXP.js} +1 -1
  13. package/dist/{ManagedForm-JCI2KPMO.js → ManagedForm-FOQZ2IYG.js} +7 -7
  14. package/dist/{ManagedNewsletterForm-DTE4KKXV.js → ManagedNewsletterForm-NFNF33V3.js} +16 -7
  15. package/dist/{SignalCore-LGCBQDEH.js → SignalCore-5KABGX5C.js} +4 -4
  16. package/dist/SiteChat-JQ46ZIJ4.js +6 -0
  17. package/dist/SiteDesignReporter-N7L6DR4J.js +12 -0
  18. package/dist/{SitePopups-T6YPHAVY.js → SitePopups-WZBKX5Q3.js} +6 -6
  19. package/dist/SitemapSync-GY6UADRI.js +9 -0
  20. package/dist/_client/booking-widget.js +6 -6
  21. package/dist/_client/testimonial-section.js +3 -3
  22. package/dist/affiliates/index.js +4 -4
  23. package/dist/analytics/index.js +6 -6
  24. package/dist/{article-styles-GGZOQG5X.js → article-styles-7QONZJR5.js} +3 -3
  25. package/dist/article-tables-6XHVULPU.js +2 -0
  26. package/dist/articles/Article.d.ts +2 -89
  27. package/dist/articles/ArticleFAQ.d.ts +2 -41
  28. package/dist/articles/ArticleFaqSection.d.ts +2 -2
  29. package/dist/articles/ArticleList.d.ts +2 -79
  30. package/dist/articles/ArticleViewTracker.d.ts +2 -15
  31. package/dist/articles/AuthorCard.d.ts +2 -10
  32. package/dist/articles/AuthorPage.d.ts +2 -8
  33. package/dist/articles/ClusterLandingPage.d.ts +2 -40
  34. package/dist/articles/ClusterNavigation.d.ts +2 -37
  35. package/dist/articles/ManagedNewsletterForm.d.ts +3 -12
  36. package/dist/articles/NewsletterShell.d.ts +2 -17
  37. package/dist/articles/NewsletterWidget.d.ts +2 -30
  38. package/dist/articles/PublicationLayout.d.ts +2 -67
  39. package/dist/articles/PublicationSidebar.d.ts +2 -36
  40. package/dist/articles/RelatedPosts.d.ts +2 -22
  41. package/dist/articles/ServiceCallout.d.ts +2 -56
  42. package/dist/articles/TableOfContents.d.ts +2 -6
  43. package/dist/articles/article-photos.d.ts +2 -9
  44. package/dist/articles/article-styles.d.ts +2 -21
  45. package/dist/articles/article-tables.d.ts +2 -12
  46. package/dist/articles/artwork.d.ts +2 -13
  47. package/dist/articles/author-schema.d.ts +2 -72
  48. package/dist/articles/author-social.d.ts +2 -14
  49. package/dist/articles/excerpt.d.ts +2 -17
  50. package/dist/articles/index.d.ts +2 -79
  51. package/dist/articles/index.js +16 -11
  52. package/dist/articles/news-sitemap.d.ts +2 -46
  53. package/dist/articles/processArticleHtml.d.ts +2 -34
  54. package/dist/articles/public-reads.d.ts +2 -26
  55. package/dist/articles/reading-time.d.ts +2 -9
  56. package/dist/articles/routes.d.ts +2 -52
  57. package/dist/articles/server-core.d.ts +2 -461
  58. package/dist/articles/server-ui.d.ts +2 -30
  59. package/dist/articles/server-ui.js +26 -17
  60. package/dist/articles/server.d.ts +2 -461
  61. package/dist/articles/server.js +14 -5
  62. package/dist/articles/types.d.ts +2 -315
  63. package/dist/articles/widget-styles.d.ts +2 -8
  64. package/dist/chat/index.js +8 -8
  65. package/dist/{chunk-AIDIEVPZ.js → chunk-2JMCBJM5.js} +1 -1
  66. package/dist/chunk-34ZYJTQR.js +1 -0
  67. package/dist/{chunk-ADI6IYFH.js → chunk-3OY52UFM.js} +1 -1
  68. package/dist/{chunk-WMVK77ND.js → chunk-4K735O3J.js} +1 -1
  69. package/dist/{chunk-55GHBRCN.js → chunk-4PVMUPC6.js} +2 -2
  70. package/dist/{chunk-L5UOHS6E.js → chunk-5D7ZISUP.js} +1 -1
  71. package/dist/{chunk-JT52KYHQ.js → chunk-5RYSTKVU.js} +1 -1
  72. package/dist/{chunk-6CJGZFOU.js → chunk-A4MPHIVP.js} +1 -1
  73. package/dist/chunk-B7T2SFUF.js +1 -0
  74. package/dist/{chunk-FV2VD7WM.js → chunk-BC7JMY4Z.js} +3 -3
  75. package/dist/{chunk-255NCCPB.js → chunk-BOCYBDKV.js} +1 -1
  76. package/dist/{chunk-NFRJTOTB.js → chunk-BSQP6PRA.js} +1 -1
  77. package/dist/{chunk-GKGSXUVQ.js → chunk-BVB5FBAA.js} +1 -1
  78. package/dist/{chunk-NWVB75ER.js → chunk-C2UROFGZ.js} +1 -1
  79. package/dist/{chunk-F2VYN3QL.js → chunk-C4AFNZT2.js} +1 -1
  80. package/dist/{chunk-GC2QWXJ3.js → chunk-D6ZIQMHB.js} +3 -3
  81. package/dist/{chunk-GYF2ULVO.js → chunk-DJAYFHVF.js} +1 -1
  82. package/dist/{chunk-XUCU3LX4.js → chunk-DPSNMOMZ.js} +1 -1
  83. package/dist/{chunk-A3EU6HB5.js → chunk-E3UR37RX.js} +2 -2
  84. package/dist/{chunk-Y3INC4QJ.js → chunk-E4PTMORJ.js} +1 -1
  85. package/dist/{chunk-TAO6BVA2.js → chunk-EA6FZMYA.js} +2 -2
  86. package/dist/{chunk-V56RZH7J.js → chunk-FHUTOXS7.js} +1 -1
  87. package/dist/{chunk-LLW5HKEE.js → chunk-GKJVSZ7H.js} +3 -3
  88. package/dist/chunk-H72ZFO3F.js +1 -0
  89. package/dist/{chunk-CSTC6HZO.js → chunk-HND6BDXC.js} +3 -3
  90. package/dist/chunk-IEGDPRQB.js +14 -0
  91. package/dist/{chunk-CAH4Y4PY.js → chunk-JO76F5WP.js} +1 -1
  92. package/dist/{chunk-4Z3DI2EL.js → chunk-KJVUOJMW.js} +58 -58
  93. package/dist/{chunk-SC4MZGWZ.js → chunk-LBDWAXAO.js} +1 -1
  94. package/dist/{chunk-RSBMQFZW.js → chunk-LPKKSYKX.js} +3 -3
  95. package/dist/{chunk-2UO4HPGE.js → chunk-M5SF7NCC.js} +73 -51
  96. package/dist/{chunk-S6IGQYHW.js → chunk-MQ4REMTH.js} +2 -2
  97. package/dist/{chunk-O4DETQJI.js → chunk-NA4Z4CQG.js} +1 -1
  98. package/dist/{chunk-WPOFTCKL.js → chunk-OIWFXUVD.js} +2 -2
  99. package/dist/{chunk-G2HCCWZQ.js → chunk-QBCWVT2S.js} +2 -2
  100. package/dist/{chunk-DZV3KPVF.js → chunk-QCZHYO5M.js} +1 -1
  101. package/dist/{chunk-DOMBP3FW.js → chunk-QDILCQBL.js} +9 -9
  102. package/dist/{chunk-IAYGTQJD.js → chunk-SCTVADDL.js} +2 -2
  103. package/dist/{chunk-QXMIKDOL.js → chunk-SNRE3ZVZ.js} +3 -3
  104. package/dist/{chunk-DSNCU2E3.js → chunk-TT4JZDKM.js} +3 -3
  105. package/dist/{chunk-6VHDCJIZ.js → chunk-U7Y3QG3A.js} +1 -1
  106. package/dist/{chunk-3G7YABRA.js → chunk-W7OPEMGJ.js} +4 -1
  107. package/dist/{chunk-2JEUDTL6.js → chunk-WBUG7XRL.js} +2 -2
  108. package/dist/{chunk-47VB5INH.js → chunk-WSOZ3FQN.js} +1 -1
  109. package/dist/chunk-X4IJS7LV.js +319 -0
  110. package/dist/{chunk-JIH32RH2.js → chunk-XA7Q2VQA.js} +1 -1
  111. package/dist/{chunk-5L467Z5Q.js → chunk-XLAXYPTK.js} +3 -3
  112. package/dist/client/index.js +4 -16
  113. package/dist/contracts/editorial-media.d.ts +39 -0
  114. package/dist/contracts/entries.d.ts +1 -1
  115. package/dist/fleet/index.js +6 -6
  116. package/dist/forms/index.js +9 -325
  117. package/dist/forms/server.js +2 -2
  118. package/dist/images/index.js +4 -4
  119. package/dist/index.js +1 -1
  120. package/dist/layout/client.js +9 -9
  121. package/dist/layout/index.js +10 -10
  122. package/dist/llms/index.js +8 -8
  123. package/dist/maps/index.js +4 -4
  124. package/dist/mcp/sonor.d.ts +42 -3
  125. package/dist/mcp/sonor.js +25 -20
  126. package/dist/mcp/transport.d.ts +1 -1
  127. package/dist/press-kit/articles/Article.d.ts +89 -0
  128. package/dist/press-kit/articles/ArticleFAQ.d.ts +41 -0
  129. package/dist/press-kit/articles/ArticleFaqSection.d.ts +2 -0
  130. package/dist/press-kit/articles/ArticleList.d.ts +79 -0
  131. package/dist/press-kit/articles/ArticleViewTracker.d.ts +15 -0
  132. package/dist/press-kit/articles/AuthorCard.d.ts +10 -0
  133. package/dist/press-kit/articles/AuthorPage.d.ts +8 -0
  134. package/dist/press-kit/articles/ClusterLandingPage.d.ts +40 -0
  135. package/dist/press-kit/articles/ClusterNavigation.d.ts +37 -0
  136. package/dist/press-kit/articles/ManagedNewsletterForm.d.ts +12 -0
  137. package/dist/press-kit/articles/NewsletterShell.d.ts +17 -0
  138. package/dist/press-kit/articles/NewsletterWidget.d.ts +30 -0
  139. package/dist/press-kit/articles/PublicationLayout.d.ts +67 -0
  140. package/dist/press-kit/articles/PublicationSidebar.d.ts +36 -0
  141. package/dist/press-kit/articles/RelatedPosts.d.ts +22 -0
  142. package/dist/press-kit/articles/ServiceCallout.d.ts +56 -0
  143. package/dist/press-kit/articles/TableOfContents.d.ts +6 -0
  144. package/dist/press-kit/articles/article-photos.d.ts +9 -0
  145. package/dist/press-kit/articles/article-styles.d.ts +21 -0
  146. package/dist/press-kit/articles/article-tables.d.ts +12 -0
  147. package/dist/press-kit/articles/artwork.d.ts +13 -0
  148. package/dist/press-kit/articles/author-schema.d.ts +72 -0
  149. package/dist/press-kit/articles/author-social.d.ts +14 -0
  150. package/dist/press-kit/articles/excerpt.d.ts +17 -0
  151. package/dist/press-kit/articles/index.d.ts +79 -0
  152. package/dist/press-kit/articles/news-sitemap.d.ts +46 -0
  153. package/dist/press-kit/articles/processArticleHtml.d.ts +34 -0
  154. package/dist/press-kit/articles/public-reads.d.ts +26 -0
  155. package/dist/press-kit/articles/reading-time.d.ts +9 -0
  156. package/dist/press-kit/articles/routes.d.ts +52 -0
  157. package/dist/press-kit/articles/server-core.d.ts +461 -0
  158. package/dist/press-kit/articles/server-ui.d.ts +31 -0
  159. package/dist/press-kit/articles/types.d.ts +316 -0
  160. package/dist/press-kit/articles/widget-styles.d.ts +8 -0
  161. package/dist/reputation/index.js +3 -3
  162. package/dist/reputation/server.js +2 -2
  163. package/dist/revalidate/index.js +2 -2
  164. package/dist/runtime/index.js +5 -4
  165. package/dist/seo/client.js +6 -6
  166. package/dist/seo/index.js +7 -7
  167. package/dist/seo/llms.js +8 -8
  168. package/dist/seo/register-sitemap-cli.js +1 -1
  169. package/dist/seo/sitemap.js +6 -6
  170. package/dist/server/index.js +3 -2
  171. package/dist/shared/build-entries.d.ts +2 -1
  172. package/dist/shared/clientApiConfig.d.ts +2 -0
  173. package/dist/shared/import-specifiers.d.ts +1 -1
  174. package/dist/shared/index.d.ts +6 -0
  175. package/dist/shared/index.js +8 -0
  176. package/dist/shared/version.d.ts +1 -1
  177. package/dist/signal/index.js +2 -2
  178. package/dist/sitemap/index.js +6 -6
  179. package/dist/sync/index.js +6 -6
  180. package/dist/website/images.js +4 -4
  181. package/dist/website/index.js +7 -7
  182. package/dist/website/popups.js +6 -6
  183. package/dist/{writeLLMsTxt-OS2WBSLM.js → writeLLMsTxt-VKHCM5IS.js} +5 -5
  184. package/docs/MIGRATING-TO-PRESS-KIT.md +83 -0
  185. package/docs.json +145 -29
  186. package/package.json +15 -5
  187. package/src/articles/README.md +5 -360
  188. package/src/mcp/README.md +16 -0
  189. package/src/og/README.md +1 -1
  190. package/src/runtime/README.md +4 -0
  191. package/dist/SiteChat-6SF7PVUT.js +0 -6
  192. package/dist/SiteDesignReporter-VISQZ5NQ.js +0 -12
  193. package/dist/SitemapSync-VKMVRPZL.js +0 -9
  194. package/dist/article-tables-AXSZOGNW.js +0 -2
@@ -0,0 +1,319 @@
1
+ import { sonorFetch } from './chunk-OIWFXUVD.js';
2
+ import { readPublishedApiConfig } from './chunk-W7OPEMGJ.js';
3
+
4
+ // src/forms/formsApi.ts
5
+ var config = null;
6
+ function configureFormsApi(options) {
7
+ config = options;
8
+ }
9
+ function getConfig() {
10
+ if (config) return config;
11
+ const { apiUrl, apiKey } = readPublishedApiConfig();
12
+ if (apiUrl && apiKey) {
13
+ return { baseUrl: apiUrl, apiKey };
14
+ }
15
+ throw new Error(
16
+ "Forms API not configured. Use SiteKitLayout in your root layout or call configureFormsApi() first."
17
+ );
18
+ }
19
+ async function apiRequest(method, path, body) {
20
+ const { baseUrl, apiKey, getAuthToken } = getConfig();
21
+ const headers = {
22
+ "Content-Type": "application/json"
23
+ };
24
+ if (apiKey) {
25
+ headers["x-api-key"] = apiKey;
26
+ } else if (getAuthToken) {
27
+ const token = await getAuthToken();
28
+ headers["Authorization"] = `Bearer ${token}`;
29
+ }
30
+ const response = await sonorFetch(`${baseUrl}${path}`, {
31
+ method,
32
+ headers,
33
+ body: body ? JSON.stringify(body) : void 0
34
+ }, { retries: 0 });
35
+ if (!response.ok) {
36
+ const error = await response.json().catch(() => ({ message: response.statusText }));
37
+ throw new Error(error.message || `API error: ${response.status}`);
38
+ }
39
+ if (response.status === 204) {
40
+ return void 0;
41
+ }
42
+ return response.json();
43
+ }
44
+ var formsApi = {
45
+ /**
46
+ * List all forms for a project
47
+ */
48
+ async list(options = {}) {
49
+ const params = new URLSearchParams();
50
+ if (options.projectId) params.set("projectId", options.projectId);
51
+ if (options.formType) params.set("formType", options.formType);
52
+ if (options.isActive !== void 0) params.set("isActive", String(options.isActive));
53
+ if (options.search) params.set("search", options.search);
54
+ const query = params.toString();
55
+ const result = await apiRequest("GET", `/forms${query ? `?${query}` : ""}`);
56
+ return result.data;
57
+ },
58
+ /**
59
+ * Get a single form by ID or slug
60
+ */
61
+ async get(idOrSlug) {
62
+ return apiRequest("GET", `/forms/${idOrSlug}`);
63
+ },
64
+ /**
65
+ * Create a new form
66
+ */
67
+ async create(input) {
68
+ return apiRequest("POST", "/forms", input);
69
+ },
70
+ /**
71
+ * Update an existing form
72
+ */
73
+ async update(id, input) {
74
+ return apiRequest("PUT", `/forms/${id}`, input);
75
+ },
76
+ /**
77
+ * Delete a form
78
+ */
79
+ async delete(id) {
80
+ return apiRequest("DELETE", `/forms/${id}`);
81
+ },
82
+ /**
83
+ * Add a field to an existing form
84
+ */
85
+ async addField(formId, field2) {
86
+ const form = await formsApi.get(formId);
87
+ const maxSortOrder = Math.max(0, ...(form.fields || []).map((f) => f.sortOrder || 0));
88
+ return formsApi.update(formId, {
89
+ fields: [
90
+ ...form.fields || [],
91
+ { ...field2, sortOrder: field2.sortOrder ?? maxSortOrder + 1 }
92
+ ]
93
+ });
94
+ },
95
+ /**
96
+ * Update a field in an existing form
97
+ */
98
+ async updateField(formId, fieldSlug, updates) {
99
+ const form = await formsApi.get(formId);
100
+ return formsApi.update(formId, {
101
+ fields: (form.fields || []).map(
102
+ (f) => f.slug === fieldSlug ? { ...f, ...updates } : f
103
+ )
104
+ });
105
+ },
106
+ /**
107
+ * Remove a field from a form
108
+ */
109
+ async removeField(formId, fieldSlug) {
110
+ const form = await formsApi.get(formId);
111
+ return formsApi.update(formId, {
112
+ fields: (form.fields || []).filter((f) => f.slug !== fieldSlug)
113
+ });
114
+ },
115
+ /**
116
+ * Reorder fields in a form
117
+ */
118
+ async reorderFields(formId, fieldSlugs) {
119
+ const form = await formsApi.get(formId);
120
+ const fieldsMap = new Map((form.fields || []).map((f) => [f.slug, f]));
121
+ const orderedFields = fieldSlugs.map((slug, index) => {
122
+ const field2 = fieldsMap.get(slug);
123
+ if (!field2) throw new Error(`Field not found: ${slug}`);
124
+ return { ...field2, sortOrder: index };
125
+ });
126
+ return formsApi.update(formId, { fields: orderedFields });
127
+ },
128
+ /**
129
+ * Clone a form
130
+ */
131
+ async clone(formId, newSlug, newName) {
132
+ const form = await formsApi.get(formId);
133
+ return formsApi.create({
134
+ projectId: form.projectId,
135
+ slug: newSlug,
136
+ name: newName || `${form.name} (Copy)`,
137
+ description: form.description,
138
+ formType: form.formType,
139
+ successMessage: form.successMessage,
140
+ redirectUrl: form.redirectUrl,
141
+ notificationEmails: form.notificationEmails,
142
+ submitButtonText: form.submitButtonText,
143
+ layout: form.layout,
144
+ showProgress: form.showProgress,
145
+ enableSaveDraft: form.enableSaveDraft,
146
+ isActive: false,
147
+ // Clone as inactive
148
+ fields: (form.fields || []).map(({ id, ...field2 }) => field2),
149
+ // Remove IDs
150
+ steps: (form.steps || []).map(({ id, ...step }) => step)
151
+ // Remove IDs
152
+ });
153
+ },
154
+ /**
155
+ * Activate or deactivate a form
156
+ */
157
+ async setActive(formId, isActive) {
158
+ return formsApi.update(formId, { isActive });
159
+ },
160
+ /**
161
+ * Sync a form definition to the backend
162
+ * Creates the form if it doesn't exist, updates if it does
163
+ * Perfect for defining forms in code during development
164
+ *
165
+ * @example
166
+ * ```tsx
167
+ * // In your app initialization or form component
168
+ * await formsApi.sync({
169
+ * slug: 'contact',
170
+ * name: 'Contact Form',
171
+ * formType: 'prospect',
172
+ * fields: [
173
+ * field.text('name', 'Your Name', { isRequired: true }),
174
+ * field.email('email', 'Email Address'),
175
+ * field.phone('phone', 'Phone Number'),
176
+ * field.textarea('message', 'Message'),
177
+ * ]
178
+ * })
179
+ * ```
180
+ */
181
+ async sync(input) {
182
+ return apiRequest(
183
+ "POST",
184
+ "/api/public/forms/sync",
185
+ input
186
+ );
187
+ },
188
+ /**
189
+ * Sync multiple forms at once
190
+ * Useful for initializing all forms in your app
191
+ *
192
+ * Runs sequentially to avoid bursting the API (many hosts throttle concurrent POSTs → 429).
193
+ */
194
+ async syncAll(forms) {
195
+ const results = [];
196
+ for (const form of forms) {
197
+ results.push(await formsApi.sync(form));
198
+ }
199
+ return results;
200
+ }
201
+ };
202
+ var field = {
203
+ text: (slug, label, options) => ({
204
+ slug,
205
+ label,
206
+ fieldType: "text",
207
+ ...options
208
+ }),
209
+ email: (slug, label, options) => ({
210
+ slug,
211
+ label,
212
+ fieldType: "email",
213
+ isRequired: true,
214
+ ...options
215
+ }),
216
+ phone: (slug, label, options) => ({
217
+ slug,
218
+ label,
219
+ fieldType: "phone",
220
+ ...options
221
+ }),
222
+ textarea: (slug, label, options) => ({
223
+ slug,
224
+ label,
225
+ fieldType: "textarea",
226
+ ...options
227
+ }),
228
+ select: (slug, label, choices, options) => ({
229
+ slug,
230
+ label,
231
+ fieldType: "select",
232
+ options: choices,
233
+ ...options
234
+ }),
235
+ radio: (slug, label, choices, options) => ({
236
+ slug,
237
+ label,
238
+ fieldType: "radio",
239
+ options: choices,
240
+ ...options
241
+ }),
242
+ checkbox: (slug, label, options) => ({
243
+ slug,
244
+ label,
245
+ fieldType: "checkbox",
246
+ ...options
247
+ }),
248
+ date: (slug, label, options) => ({
249
+ slug,
250
+ label,
251
+ fieldType: "date",
252
+ ...options
253
+ }),
254
+ number: (slug, label, options) => ({
255
+ slug,
256
+ label,
257
+ fieldType: "number",
258
+ ...options
259
+ }),
260
+ rating: (slug, label, options) => ({
261
+ slug,
262
+ label,
263
+ fieldType: "rating",
264
+ ...options
265
+ }),
266
+ file: (slug, label, options) => ({
267
+ slug,
268
+ label,
269
+ fieldType: "file",
270
+ ...options
271
+ }),
272
+ hidden: (slug, defaultValue) => ({
273
+ slug,
274
+ label: "",
275
+ fieldType: "hidden",
276
+ defaultValue
277
+ }),
278
+ heading: (slug, label) => ({
279
+ slug,
280
+ label,
281
+ fieldType: "heading"
282
+ }),
283
+ paragraph: (slug, label) => ({
284
+ slug,
285
+ label,
286
+ fieldType: "paragraph"
287
+ })
288
+ };
289
+ function defineForm(definition) {
290
+ const fieldsWithOrder = definition.fields.map((f, index) => ({
291
+ ...f,
292
+ sortOrder: f.sortOrder ?? index
293
+ }));
294
+ return {
295
+ ...definition,
296
+ fields: fieldsWithOrder,
297
+ formType: definition.formType || "contact",
298
+ successMessage: definition.successMessage || "Thank you for your submission!",
299
+ submitButtonText: definition.submitButtonText || "Submit",
300
+ layout: definition.layout || "stacked",
301
+ isActive: definition.isActive ?? true
302
+ };
303
+ }
304
+ async function initializeForms(forms) {
305
+ if (typeof window === "undefined") {
306
+ console.log(`[Site-Kit] ${forms.length} form(s) ready to sync: ${forms.map((f) => f.slug).join(", ")}`);
307
+ return;
308
+ }
309
+ try {
310
+ const results = await formsApi.syncAll(forms);
311
+ const created = results.filter((r) => r.created).length;
312
+ const updated = results.filter((r) => r.updated).length;
313
+ console.log(`[Site-Kit] Forms synced: ${created} created, ${updated} updated`);
314
+ } catch (error) {
315
+ console.error("[Site-Kit] Failed to sync forms:", error);
316
+ }
317
+ }
318
+
319
+ export { configureFormsApi, defineForm, field, formsApi, initializeForms };
@@ -1,7 +1,7 @@
1
1
  import { freshFetch } from './chunk-UAYAJPEP.js';
2
2
  import { LLM_GEO_CONTRACT_VERSION } from './chunk-NZ4RXN3G.js';
3
3
  import { withSiteParam } from './chunk-MJP63SSS.js';
4
- import { getClientApiConfig } from './chunk-3G7YABRA.js';
4
+ import { getClientApiConfig } from './chunk-W7OPEMGJ.js';
5
5
  import { cache } from 'react';
6
6
 
7
7
  function getApiConfig() {
@@ -1,6 +1,6 @@
1
1
  'use client';
2
- import { countStageViews, countStageQuestions, useFieldControls } from './chunk-XUCU3LX4.js';
3
- import { useFormLoadedAt, useFormTracking, submitForm, useRecaptchaWarmup, useForm } from './chunk-S6IGQYHW.js';
2
+ import { countStageViews, countStageQuestions, useFieldControls } from './chunk-DPSNMOMZ.js';
3
+ import { useFormLoadedAt, useFormTracking, submitForm, useRecaptchaWarmup, useForm } from './chunk-MQ4REMTH.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-CJUSCSAL.js').then((m) => m.FormStage) : import('./FormSpotlight-VGC4CZL4.js').then((m) => m.FormSpotlight);
66
+ const load = resolvedExperience === "stage" ? import('./FormStage-RC3WHHXP.js').then((m) => m.FormStage) : import('./FormSpotlight-JFH2ENKQ.js').then((m) => m.FormSpotlight);
67
67
  load.then((Component) => {
68
68
  if (!cancelled) setExperience(() => Component);
69
69
  }).catch((err) => {
@@ -1,5 +1,6 @@
1
1
  'use client';
2
- import { publishSiteCredential } from '../chunk-6VHDCJIZ.js';
2
+ export { SiteKitCredential } from '../chunk-IEGDPRQB.js';
3
+ import '../chunk-U7Y3QG3A.js';
3
4
  export { VISUAL_VIEWPORT_GAP_PROPERTY, VisualViewportGap, useVisualViewportGap } from '../chunk-6T6CQVNL.js';
4
5
  export { useDeferredActivation } from '../chunk-YC7ELZS3.js';
5
6
  import '../chunk-FESKKJAS.js';
@@ -8,19 +9,6 @@ export { trackConversion, trackEvent } from '../chunk-LCDVPAMR.js';
8
9
  export { getOrCreateSessionId, getOrCreateVisitorId, useSiteKitIdentity } from '../chunk-ZKADJNR2.js';
9
10
  import '../chunk-5TM3WPCI.js';
10
11
  import '../chunk-GJWI74ZZ.js';
11
- import '../chunk-F2VYN3QL.js';
12
- import '../chunk-NWVB75ER.js';
12
+ import '../chunk-C4AFNZT2.js';
13
+ import '../chunk-C2UROFGZ.js';
13
14
  import '../chunk-PKBMQBKP.js';
14
-
15
- // src/client/SiteKitCredential.tsx
16
- function SiteKitCredential({
17
- apiKey,
18
- apiUrl,
19
- site,
20
- debug
21
- }) {
22
- publishSiteCredential({ apiKey, apiUrl, site, debug });
23
- return null;
24
- }
25
-
26
- export { SiteKitCredential };
@@ -0,0 +1,39 @@
1
+ /** Shared article placement and source eligibility rules. Pure, server/client safe. */
2
+ export type EditorialPhotoPlacement = {
3
+ kind: 'after_intro';
4
+ } | {
5
+ kind: 'after_heading';
6
+ heading: string;
7
+ headingId?: string;
8
+ };
9
+ export type ArticlePhotoPlacementStatus = 'placed' | 'missing_heading' | 'ambiguous_heading' | 'no_paragraph' | 'already_present' | 'unassigned';
10
+ export interface EditorialHeadingTarget {
11
+ id: string;
12
+ text: string;
13
+ level: number;
14
+ eligible: boolean;
15
+ }
16
+ export declare function editorialPlainText(value: string): string;
17
+ /** A text identity, never a positional index. Editing the meaning requires a new assignment. */
18
+ export declare function editorialTextId(kind: 'section' | 'takeaway', text: string): string;
19
+ export declare function resolveArticlePhotoPlacements(html: string, photos?: Array<{
20
+ placement?: EditorialPhotoPlacement;
21
+ url?: string;
22
+ }>): {
23
+ headings: {
24
+ id: string;
25
+ text: string;
26
+ level: number;
27
+ eligible: boolean;
28
+ }[];
29
+ placements: {
30
+ index: number;
31
+ status: ArticlePhotoPlacementStatus;
32
+ offset?: number;
33
+ }[];
34
+ };
35
+ export declare const EDITORIAL_PHOTO_MIME_TYPES: readonly ['image/jpeg', 'image/jpg', 'image/png', 'image/webp', 'image/avif'];
36
+ export declare const EDITORIAL_PHOTO_MAX_BYTES: number;
37
+ /** The same generated-art path exclusion is used by the picker and source resolver. */
38
+ export declare const FINISHED_EDITORIAL_ART_PATHS: readonly ['Blog/Cards', 'Blog/Carousel', 'Broadcast/Cards', 'Broadcast/StylePreview', 'Reviews/Broadcast', 'Reviews/Photo', 'Reviews/StylePreview'];
39
+ export declare function isFinishedEditorialArtwork(path: string): boolean;
@@ -4,5 +4,5 @@
4
4
  * tsup config, its package.json check and the boundary test, so a new
5
5
  * contract is added in one place.
6
6
  */
7
- export declare const CONTRACT_ENTRIES: readonly ['forms', 'llms', 'slots', 'slot-content', 'site-cache', 'site-edit', 'website', 'color', 'fleet', 'sites', 'seo-pages', 'seo-meta', 'portfolio', 'voice', 'proposal-sitemap', 'error-page', 'schema-placeholders', 'sentences', 'knowledge'];
7
+ export declare const CONTRACT_ENTRIES: readonly ['forms', 'llms', 'slots', 'slot-content', 'site-cache', 'site-edit', 'website', 'color', 'fleet', 'sites', 'seo-pages', 'seo-meta', 'portfolio', 'voice', 'proposal-sitemap', 'error-page', 'schema-placeholders', 'sentences', 'knowledge', 'editorial-media'];
8
8
  export type ContractEntry = (typeof CONTRACT_ENTRIES)[number];
@@ -1,11 +1,11 @@
1
1
  'use client';
2
- export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat } from '../chunk-RSBMQFZW.js';
2
+ export { FLEET_HEARTBEAT_PATH, FleetHeartbeat, detectNextVersion, sendFleetHeartbeat } from '../chunk-LPKKSYKX.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
- import '../chunk-CAH4Y4PY.js';
5
+ import '../chunk-JO76F5WP.js';
6
6
  import '../chunk-EKBEOXTH.js';
7
- import '../chunk-3G7YABRA.js';
8
- import '../chunk-WPOFTCKL.js';
9
- import '../chunk-F2VYN3QL.js';
10
- import '../chunk-NWVB75ER.js';
7
+ import '../chunk-OIWFXUVD.js';
8
+ import '../chunk-C4AFNZT2.js';
9
+ import '../chunk-W7OPEMGJ.js';
10
+ import '../chunk-C2UROFGZ.js';
11
11
  import '../chunk-PKBMQBKP.js';