@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
@@ -0,0 +1,576 @@
1
+ import { type PublicationColors } from './publication-branding';
2
+ export { normalizeCampaignSlug } from './campaign-normalize';
3
+ export declare const FUNNEL_SCHEMA_VERSION: 1;
4
+ export declare const MANAGED_FUNNEL_PATH_PREFIX: '/f';
5
+ export declare const FUNNEL_TEMPLATES: readonly ['newsletter', 'requested_guide', 'inquiry'];
6
+ export type FunnelTemplate = typeof FUNNEL_TEMPLATES[number];
7
+ export type FunnelLifecycle = 'draft' | 'active' | 'paused';
8
+ export type FunnelHealth = 'healthy' | 'waiting' | 'needs_attention' | 'unknown';
9
+ export type FunnelBodyBlock = {
10
+ type: 'paragraph';
11
+ text: string;
12
+ } | {
13
+ type: 'bullets';
14
+ items: string[];
15
+ };
16
+ export interface FunnelBrandPresentation {
17
+ displayName: string;
18
+ tagline: string;
19
+ fullLogoUrl: string | null;
20
+ squareLogoUrl: string | null;
21
+ colors: Required<PublicationColors>;
22
+ typography: {
23
+ headingFamily: string;
24
+ bodyFamily: string;
25
+ };
26
+ scheme: 'light' | 'dark';
27
+ }
28
+ export interface FunnelBrandOverride {
29
+ displayName?: string | null;
30
+ tagline?: string | null;
31
+ fullLogoAssetId?: string | null;
32
+ squareLogoAssetId?: string | null;
33
+ colors?: {
34
+ [K in keyof PublicationColors]?: string | null;
35
+ };
36
+ typography?: {
37
+ headingFamily?: string | null;
38
+ bodyFamily?: string | null;
39
+ };
40
+ }
41
+ export type FunnelBrandSource = 'project' | 'brand_profile' | 'site_design' | 'publication_branding' | 'platforms.publication' | 'platforms.email' | 'funnel_override' | 'default';
42
+ export interface FunnelBrandSnapshot {
43
+ page: FunnelBrandPresentation;
44
+ email: FunnelBrandPresentation;
45
+ provenance: Record<string, FunnelBrandSource>;
46
+ assetRefs: {
47
+ id: string | null;
48
+ version: string | null;
49
+ }[];
50
+ capturedAt: string;
51
+ fingerprint: string;
52
+ }
53
+ export type FunnelStep = {
54
+ id: string;
55
+ type: 'wait';
56
+ durationSeconds: number;
57
+ } | {
58
+ id: string;
59
+ type: 'send_email';
60
+ templateId: string;
61
+ purpose: 'requested_fulfillment' | 'marketing';
62
+ guideAssetId?: string | null;
63
+ } | {
64
+ id: string;
65
+ type: 'add_tag';
66
+ target: 'subscriber';
67
+ tag: string;
68
+ } | {
69
+ id: string;
70
+ type: 'create_task';
71
+ ownerContactId: string;
72
+ title: string;
73
+ dueAfterSeconds: number;
74
+ };
75
+ export interface FunnelDefinition {
76
+ schemaVersion: 1;
77
+ name: string;
78
+ template: FunnelTemplate;
79
+ site: string;
80
+ entry: {
81
+ formId: string;
82
+ mode: 'future_accepted_form_only';
83
+ };
84
+ goal: {
85
+ type: 'newsletter_confirmed' | 'guide_requested' | 'inquiry_received' | 'booking_confirmed';
86
+ bookingTypeId?: string | null;
87
+ };
88
+ page: {
89
+ mode: 'existing' | 'managed';
90
+ path: string;
91
+ slug?: string | null;
92
+ headline: string;
93
+ body: FunnelBodyBlock[];
94
+ formId: string;
95
+ offerAssetId?: string | null;
96
+ };
97
+ permission: {
98
+ mode: 'requested_only' | 'marketing_opt_in';
99
+ optInFieldSlug?: string | null;
100
+ };
101
+ brandOverride?: FunnelBrandOverride;
102
+ steps: FunnelStep[];
103
+ exits: {
104
+ unsubscribe: true;
105
+ manualStop: true;
106
+ confirmedBooking?: {
107
+ enabled: boolean;
108
+ bookingTypeId: string | null;
109
+ };
110
+ };
111
+ }
112
+ export interface FunnelIssue {
113
+ code: string;
114
+ path: string;
115
+ message: string;
116
+ fixRef?: {
117
+ section: string;
118
+ field?: string;
119
+ resourceId?: string;
120
+ };
121
+ }
122
+ export interface FunnelReadiness {
123
+ definitionRevision: number;
124
+ brandFingerprint: string;
125
+ resourceFingerprint: string;
126
+ ready: boolean;
127
+ blockers: FunnelIssue[];
128
+ warnings: FunnelIssue[];
129
+ capabilities: {
130
+ managedPage: boolean;
131
+ };
132
+ }
133
+ export interface PublishedFunnelPage {
134
+ schemaVersion: 1;
135
+ id: string;
136
+ versionId: string;
137
+ revision: number;
138
+ site: string;
139
+ path: string;
140
+ content: {
141
+ headline: string;
142
+ body: FunnelBodyBlock[];
143
+ offer?: {
144
+ label: string;
145
+ href: string;
146
+ };
147
+ };
148
+ brand: FunnelBrandPresentation;
149
+ conversion: {
150
+ formSlug: string;
151
+ };
152
+ tracking: {
153
+ campaignSlug: string;
154
+ };
155
+ }
156
+ export interface FunnelOperationReceipt {
157
+ operationId: string;
158
+ projectId: string;
159
+ orgId: string;
160
+ funnelId: string;
161
+ operation: 'create' | 'update' | 'launch' | 'pause' | 'resume' | 'retry' | 'rollback';
162
+ idempotencyKey: string;
163
+ requestDigest: string;
164
+ versionId: string | null;
165
+ lifecycle: FunnelLifecycle;
166
+ replayed: boolean;
167
+ armedFutureEntrantsOnly: true;
168
+ enrolledExisting: 0;
169
+ messagesSent: 0;
170
+ pagePublication: 'not_requested' | 'published' | 'revalidation_pending';
171
+ health: FunnelHealth;
172
+ revision: number;
173
+ commandState: 'committed';
174
+ funnel: FunnelDetail | null;
175
+ actor: string;
176
+ armedAt: string | null;
177
+ effectScope: 'configuration_only' | 'safe_retry_armed';
178
+ target: FunnelCommandTarget;
179
+ ledgerProposalId: string;
180
+ }
181
+ export interface FunnelCommandTarget {
182
+ funnelId: string | null;
183
+ enrollmentId: string | null;
184
+ executionId: string | null;
185
+ targetVersionId: string | null;
186
+ }
187
+ export interface FunnelLaunchArgs {
188
+ expectedRevision: number;
189
+ previewId: string;
190
+ idempotencyKey: string;
191
+ confirm: true;
192
+ }
193
+ export interface FunnelLifecycleArgs {
194
+ expectedActiveVersionId: string;
195
+ idempotencyKey: string;
196
+ confirm: true;
197
+ targetVersionId?: string;
198
+ }
199
+ /** Small closed JSON-schema vocabulary shared by the exported schema and its runtime parser. */
200
+ type Shape = {
201
+ type?: 'object' | 'array' | 'string' | 'integer' | 'boolean' | 'null';
202
+ properties?: Record<string, Shape>;
203
+ required?: readonly string[];
204
+ additionalProperties?: false;
205
+ items?: Shape;
206
+ minItems?: number;
207
+ maxItems?: number;
208
+ minLength?: number;
209
+ maxLength?: number;
210
+ pattern?: string;
211
+ minimum?: number;
212
+ maximum?: number;
213
+ enum?: readonly unknown[];
214
+ const?: unknown;
215
+ oneOf?: readonly Shape[];
216
+ };
217
+ export type FunnelDraftStep = Extract<FunnelStep, {
218
+ type: 'wait' | 'add_tag';
219
+ }> | (Omit<Extract<FunnelStep, {
220
+ type: 'send_email';
221
+ }>, 'templateId' | 'guideAssetId'> & {
222
+ templateId: string | null;
223
+ guideAssetId?: string | null;
224
+ }) | (Omit<Extract<FunnelStep, {
225
+ type: 'create_task';
226
+ }>, 'ownerContactId'> & {
227
+ ownerContactId: string | null;
228
+ });
229
+ export interface FunnelDraftDefinition extends Omit<FunnelDefinition, 'site' | 'entry' | 'page' | 'steps'> {
230
+ site: string | null;
231
+ entry: {
232
+ formId: string | null;
233
+ mode: 'future_accepted_form_only';
234
+ };
235
+ page: Omit<FunnelDefinition['page'], 'path' | 'formId'> & {
236
+ path: string | null;
237
+ formId: string | null;
238
+ };
239
+ steps: FunnelDraftStep[];
240
+ }
241
+ export declare const FUNNEL_DRAFT_DEFINITION_JSON_SCHEMA: {
242
+ readonly type?: 'object' | 'array' | 'string' | 'integer' | 'boolean' | 'null';
243
+ readonly properties?: Record<string, Shape>;
244
+ readonly required?: readonly string[];
245
+ readonly additionalProperties?: false;
246
+ readonly items?: Shape;
247
+ readonly minItems?: number;
248
+ readonly maxItems?: number;
249
+ readonly minLength?: number;
250
+ readonly maxLength?: number;
251
+ readonly pattern?: string;
252
+ readonly minimum?: number;
253
+ readonly maximum?: number;
254
+ readonly enum?: readonly unknown[];
255
+ readonly const?: unknown;
256
+ readonly oneOf?: readonly Shape[];
257
+ readonly $schema: 'http://json-schema.org/draft-07/schema#';
258
+ };
259
+ export declare function parseFunnelDraftDefinition(value: unknown): FunnelDraftDefinition;
260
+ export declare function createFunnelDraft(template: FunnelTemplate): FunnelDraftDefinition;
261
+ export declare const FUNNEL_DEFINITION_JSON_SCHEMA: {
262
+ readonly type?: 'object' | 'array' | 'string' | 'integer' | 'boolean' | 'null';
263
+ readonly properties?: Record<string, Shape>;
264
+ readonly required?: readonly string[];
265
+ readonly additionalProperties?: false;
266
+ readonly items?: Shape;
267
+ readonly minItems?: number;
268
+ readonly maxItems?: number;
269
+ readonly minLength?: number;
270
+ readonly maxLength?: number;
271
+ readonly pattern?: string;
272
+ readonly minimum?: number;
273
+ readonly maximum?: number;
274
+ readonly enum?: readonly unknown[];
275
+ readonly const?: unknown;
276
+ readonly oneOf?: readonly Shape[];
277
+ readonly $schema: 'http://json-schema.org/draft-07/schema#';
278
+ };
279
+ export declare const PUBLISHED_FUNNEL_PAGE_JSON_SCHEMA: {
280
+ readonly type?: 'object' | 'array' | 'string' | 'integer' | 'boolean' | 'null';
281
+ readonly properties?: Record<string, Shape>;
282
+ readonly required?: readonly string[];
283
+ readonly additionalProperties?: false;
284
+ readonly items?: Shape;
285
+ readonly minItems?: number;
286
+ readonly maxItems?: number;
287
+ readonly minLength?: number;
288
+ readonly maxLength?: number;
289
+ readonly pattern?: string;
290
+ readonly minimum?: number;
291
+ readonly maximum?: number;
292
+ readonly enum?: readonly unknown[];
293
+ readonly const?: unknown;
294
+ readonly oneOf?: readonly Shape[];
295
+ readonly $schema: 'http://json-schema.org/draft-07/schema#';
296
+ };
297
+ export declare const FUNNEL_LAUNCH_JSON_SCHEMA: Shape;
298
+ export declare const FUNNEL_LIFECYCLE_JSON_SCHEMA: Shape;
299
+ export declare const FUNNEL_ROLLBACK_JSON_SCHEMA: Shape;
300
+ export declare class FunnelValidationError extends Error {
301
+ readonly path: string;
302
+ constructor(path: string, reason: string);
303
+ }
304
+ /** No DNS/network access. Consumers fetching URLs still enforce their connection policy. */
305
+ export declare function isSafeFunnelPublicUrl(value: string): boolean;
306
+ export declare function managedFunnelPath(value: string): string;
307
+ export declare function parseFunnelDefinition(value: unknown): FunnelDefinition;
308
+ export declare function parsePublishedFunnelPage(value: unknown): PublishedFunnelPage;
309
+ export declare function parseFunnelLaunchArgs(value: unknown): FunnelLaunchArgs;
310
+ export declare function parseFunnelLifecycleArgs(value: unknown, operation?: 'pause' | 'resume' | 'rollback'): FunnelLifecycleArgs;
311
+ /** Apply presentation-only overrides to an already resolved canonical brand. Null means inherit. */
312
+ export declare function applyFunnelBrandOverride(inherited: FunnelBrandPresentation, patch?: FunnelBrandOverride, resolvedAssets?: Record<string, {
313
+ url: string;
314
+ version?: string;
315
+ }>): {
316
+ brand: FunnelBrandPresentation;
317
+ overridePaths: string[];
318
+ assetRefs: {
319
+ id: string;
320
+ version: string | null;
321
+ }[];
322
+ };
323
+ export interface FunnelCreateArgs {
324
+ idempotencyKey: string;
325
+ definition: FunnelDraftDefinition;
326
+ }
327
+ export interface FunnelUpdateArgs extends FunnelCreateArgs {
328
+ expectedRevision: number;
329
+ }
330
+ export declare const FUNNEL_CREATE_JSON_SCHEMA: Shape;
331
+ export declare const FUNNEL_UPDATE_JSON_SCHEMA: Shape;
332
+ export declare function parseFunnelCreateArgs(value: unknown): FunnelCreateArgs;
333
+ export declare function parseFunnelUpdateArgs(value: unknown): FunnelUpdateArgs;
334
+ export interface FunnelPreview {
335
+ previewId: string;
336
+ versionId: string;
337
+ expiresAt: string;
338
+ definitionRevision: number;
339
+ brand: FunnelBrandSnapshot;
340
+ readiness: FunnelReadiness;
341
+ page: PublishedFunnelPage | null;
342
+ launchEvidence: FunnelLaunchEvidence;
343
+ emailPreviews: {
344
+ stepId: string;
345
+ ready: boolean;
346
+ subject: string | null;
347
+ contentHtml: string | null;
348
+ issues: FunnelIssue[];
349
+ }[];
350
+ }
351
+ export interface FunnelSummary {
352
+ id: string;
353
+ name: string;
354
+ template: FunnelTemplate;
355
+ site: string | null;
356
+ revision: number;
357
+ activeVersionId: string | null;
358
+ lifecycle: FunnelLifecycle;
359
+ health: FunnelHealth;
360
+ hasDraftChanges: boolean;
361
+ counts: {
362
+ entered: number;
363
+ waiting: number;
364
+ running: number;
365
+ completed: number;
366
+ exited: number;
367
+ needsAttention: number;
368
+ };
369
+ countsBasis: 'all_versions_all_time';
370
+ lastEventAt: string | null;
371
+ }
372
+ export type FunnelDraftArgs = FunnelCreateArgs | FunnelUpdateArgs;
373
+ /** Select create/update explicitly at the HTTP boundary; a missing revision never downgrades an update. */
374
+ export declare function parseFunnelDraftArgs(value: unknown, mode: 'create' | 'update'): FunnelDraftArgs;
375
+ export interface FunnelRevisionArgs {
376
+ expectedRevision: number;
377
+ }
378
+ export interface FunnelRetryArgs {
379
+ expectedAttempt: number;
380
+ idempotencyKey: string;
381
+ confirm: true;
382
+ }
383
+ export declare const FUNNEL_REVISION_JSON_SCHEMA: Shape;
384
+ export declare const FUNNEL_RETRY_JSON_SCHEMA: Shape;
385
+ export declare const FUNNEL_DRAFT_JSON_SCHEMAS: {
386
+ readonly create: Shape;
387
+ readonly update: Shape;
388
+ };
389
+ export declare function parseFunnelRevisionArgs(value: unknown): FunnelRevisionArgs;
390
+ export declare function parseFunnelRetryArgs(value: unknown): FunnelRetryArgs;
391
+ export declare const FUNNEL_READINESS_JSON_SCHEMA: Shape;
392
+ export declare function parseFunnelReadiness(value: unknown): FunnelReadiness;
393
+ export interface FunnelDetail {
394
+ id: string;
395
+ revision: number;
396
+ definition: FunnelDraftDefinition;
397
+ activeVersionId: string | null;
398
+ lifecycle: FunnelLifecycle;
399
+ health: FunnelHealth;
400
+ hasDraftChanges: boolean;
401
+ readiness: FunnelReadiness;
402
+ }
403
+ export declare const FUNNEL_DETAIL_JSON_SCHEMA: Shape;
404
+ export declare function parseFunnelDetail(value: unknown): FunnelDetail;
405
+ export declare const FUNNEL_OPERATION_RECEIPT_JSON_SCHEMA: Shape;
406
+ export declare function parseFunnelOperationReceipt(value: unknown): FunnelOperationReceipt;
407
+ export declare const FUNNEL_BRAND_SNAPSHOT_JSON_SCHEMA: Shape;
408
+ export declare function parseFunnelBrandSnapshot(value: unknown): FunnelBrandSnapshot;
409
+ export interface FunnelCatalogItem {
410
+ id: string;
411
+ label: string;
412
+ }
413
+ export interface FunnelFormChoice extends FunnelCatalogItem {
414
+ slug: string;
415
+ site: string | null;
416
+ formType: string;
417
+ active: boolean;
418
+ newsletterListIds: string[];
419
+ fields: {
420
+ slug: string;
421
+ type: string;
422
+ label: string;
423
+ required: boolean;
424
+ }[];
425
+ }
426
+ export interface FunnelListChoice extends FunnelCatalogItem {
427
+ active: boolean;
428
+ doubleOptIn: boolean;
429
+ }
430
+ export interface FunnelEmailTemplateChoice extends FunnelCatalogItem {
431
+ subject: string;
432
+ updatedAt: string | null;
433
+ }
434
+ export interface FunnelAssetChoice extends FunnelCatalogItem {
435
+ mimeType: string;
436
+ sizeBytes: number;
437
+ visibility: 'public';
438
+ publicUrl: string;
439
+ version: string | null;
440
+ }
441
+ export interface FunnelOwnerChoice extends FunnelCatalogItem {
442
+ active: true;
443
+ }
444
+ export interface FunnelBookingChoice extends FunnelCatalogItem {
445
+ site: string | null;
446
+ active: true;
447
+ requiresConfirmation: boolean;
448
+ }
449
+ export interface FunnelChoicePage<T> {
450
+ items: T[];
451
+ nextCursor: string | null;
452
+ }
453
+ export interface FunnelCatalog {
454
+ templates: {
455
+ id: FunnelTemplate;
456
+ label: string;
457
+ defaults: FunnelDraftDefinition;
458
+ }[];
459
+ sites: {
460
+ host: string;
461
+ label: string;
462
+ }[];
463
+ brand: FunnelBrandSnapshot | null;
464
+ choices: {
465
+ forms?: FunnelChoicePage<FunnelFormChoice>;
466
+ lists?: FunnelChoicePage<FunnelListChoice>;
467
+ emailTemplates?: FunnelChoicePage<FunnelEmailTemplateChoice>;
468
+ assets?: FunnelChoicePage<FunnelAssetChoice>;
469
+ owners?: FunnelChoicePage<FunnelOwnerChoice>;
470
+ bookingTypes?: FunnelChoicePage<FunnelBookingChoice>;
471
+ };
472
+ capabilities: {
473
+ managedPage: boolean;
474
+ };
475
+ }
476
+ export declare const FUNNEL_CATALOG_JSON_SCHEMA: Shape;
477
+ export declare function parseFunnelCatalog(value: unknown): FunnelCatalog;
478
+ export interface FunnelLaunchEvidence {
479
+ projectId: string;
480
+ orgId: string;
481
+ funnelId: string;
482
+ previewId: string;
483
+ versionId: string;
484
+ definitionRevision: number;
485
+ definitionDigest: string;
486
+ brandFingerprint: string;
487
+ resourceFingerprint: string;
488
+ entryDigest: string;
489
+ permissionDigest: string;
490
+ expiresAt: string;
491
+ }
492
+ export interface FunnelRollbackEvidence {
493
+ orgId: string;
494
+ projectId: string;
495
+ funnelId: string;
496
+ targetVersionId: string;
497
+ definitionRevision: number;
498
+ definitionDigest: string;
499
+ brandFingerprint: string;
500
+ resourceFingerprint: string;
501
+ }
502
+ export declare const FUNNEL_LAUNCH_EVIDENCE_JSON_SCHEMA: Shape;
503
+ export declare function parseFunnelLaunchEvidence(value: unknown): FunnelLaunchEvidence;
504
+ export declare const FUNNEL_ROLLBACK_EVIDENCE_JSON_SCHEMA: Shape;
505
+ export declare function parseFunnelRollbackEvidence(value: unknown): FunnelRollbackEvidence;
506
+ export declare const FUNNEL_PREVIEW_JSON_SCHEMA: Shape;
507
+ export declare function parseFunnelPreview(value: unknown): FunnelPreview;
508
+ export type FunnelEnrollmentState = 'waiting' | 'running' | 'completed' | 'exited' | 'needs_attention';
509
+ export interface FunnelEnrollmentSummary {
510
+ id: string;
511
+ versionId: string;
512
+ state: FunnelEnrollmentState;
513
+ effectiveStatus: FunnelEnrollmentState | 'paused';
514
+ source: {
515
+ submissionId: string;
516
+ acceptedAt: string;
517
+ };
518
+ subject: {
519
+ kind: 'subscriber' | 'contact' | 'submission';
520
+ id: string;
521
+ displayLabel: string;
522
+ };
523
+ enteredAt: string;
524
+ nextRunAt: string | null;
525
+ exitCode: string | null;
526
+ stepsCompleted: number;
527
+ stepsTotal: number;
528
+ lastReceiptAt: string | null;
529
+ }
530
+ export interface FunnelTimeline {
531
+ items: {
532
+ executionId: string;
533
+ stepId: string;
534
+ type: FunnelStep['type'];
535
+ state: 'pending' | 'claimed' | 'queued' | 'admitted' | 'succeeded' | 'skipped' | 'uncertain' | 'failed';
536
+ dueAt: string | null;
537
+ occurredAt: string | null;
538
+ attempt: number;
539
+ reasonCode: string | null;
540
+ message: string;
541
+ receipt: {
542
+ domain: 'campaign_send' | 'subscriber_tag' | 'crm_task' | 'wait';
543
+ id: string | null;
544
+ state: string;
545
+ } | null;
546
+ canRetry: boolean;
547
+ }[];
548
+ nextCursor: string | null;
549
+ exit: {
550
+ code: string;
551
+ sourceType: string;
552
+ sourceId: string | null;
553
+ occurredAt: string;
554
+ } | null;
555
+ }
556
+ export declare const FUNNEL_SUMMARY_JSON_SCHEMA: Shape;
557
+ export declare function parseFunnelSummary(value: unknown): FunnelSummary;
558
+ export declare const FUNNEL_ENROLLMENT_JSON_SCHEMA: Shape;
559
+ export declare function parseFunnelEnrollmentSummary(value: unknown): FunnelEnrollmentSummary;
560
+ export declare const FUNNEL_TIMELINE_JSON_SCHEMA: Shape;
561
+ export declare function parseFunnelTimeline(value: unknown): FunnelTimeline;
562
+ export interface FunnelPublishedVersion {
563
+ versionId: string;
564
+ definitionRevision: number;
565
+ publishedAt: string;
566
+ brandFingerprint: string;
567
+ resourceFingerprint: string;
568
+ active: boolean;
569
+ }
570
+ export interface FunnelPublishedVersionDetail extends FunnelPublishedVersion {
571
+ rollbackEvidence: FunnelRollbackEvidence;
572
+ }
573
+ export declare const FUNNEL_VERSION_JSON_SCHEMA: Shape;
574
+ export declare const FUNNEL_VERSION_DETAIL_JSON_SCHEMA: Shape;
575
+ export declare function parseFunnelPublishedVersion(value: unknown): FunnelPublishedVersion;
576
+ export declare function parseFunnelPublishedVersionDetail(value: unknown): FunnelPublishedVersionDetail;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * Which inbox cards are decisions. Single source of truth for the rule the
3
+ * Signal API follows when it writes ("Mark all read" and "Dismiss all" leave a
4
+ * decision alone) and the dashboard follows when it previews that write.
5
+ *
6
+ * A decision is a card still waiting on its person:
7
+ * - an approval (insight type `approval_needed`);
8
+ * - any card carrying a ledger proposal (`data.proposal_id`), which the Inbox
9
+ * turns into Approve / Reject;
10
+ * - the ledger's unconfirmed-action card (`ledger_unconfirmed_action`):
11
+ * Signal started something it never saw finish and won't run again, so a
12
+ * person has to check it. It's raised once per claim, ever, so a bulk
13
+ * dismissal that took it would leave nobody told. It isn't an approval: the
14
+ * claim was approved already, so it has no `proposal_id` and the Inbox
15
+ * offers no Approve / Reject on it.
16
+ *
17
+ * The Signal API states the same rule once more as a database filter. It
18
+ * builds that filter from DECISION_INSIGHT_TYPES, so the list is written here
19
+ * and nowhere else.
20
+ */
21
+ /** The insight type of an approval waiting on a yes. */
22
+ export declare const APPROVAL_NEEDED_INSIGHT_TYPE = "approval_needed";
23
+ /**
24
+ * The insight type of the card a ledger claim nobody can account for raises.
25
+ * The producer writes it, the delivery policy matches it and the decision rule
26
+ * below counts it.
27
+ */
28
+ export declare const LEDGER_UNCONFIRMED_INSIGHT_TYPE = "ledger_unconfirmed_action";
29
+ /** Insight types that are a decision whatever their data. */
30
+ export declare const DECISION_INSIGHT_TYPES: readonly string[];
31
+ /** The card fields the rule reads. A stored row or the dashboard's inbox item both fit. */
32
+ export interface DecisionCardFields {
33
+ insight_type: string;
34
+ data?: Record<string, unknown> | null;
35
+ }
36
+ /**
37
+ * Whether a card is a decision still waiting on its person. `proposal_id` set
38
+ * is what counts, so it's read the way the database reads `data->>proposal_id`:
39
+ * a JSON null, a missing key and a null `data` all mean no proposal; any other
40
+ * value, an empty string included, means one.
41
+ */
42
+ export declare function isDecisionCard(card: DecisionCardFields): boolean;