siteplane 0.1.45 → 0.1.47

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.
@@ -100,13 +100,42 @@ var analyticsProviderImportSchema = z3.object({
100
100
  rows: z3.array(analyticsProviderImportRowSchema).min(1).max(1e3)
101
101
  }).strict();
102
102
 
103
- // ../shared/dist/analytics-events.js
103
+ // ../shared/dist/analytics-config.js
104
104
  import { z as z4 } from "zod";
105
+ var ANALYTICS_CONFIG_LEASE_MS = 6e4;
106
+ var analyticsMeasurementConfigSchema = z4.object({
107
+ version: z4.literal(1),
108
+ installationGeneration: z4.number().int().positive(),
109
+ configRevision: z4.number().int().positive(),
110
+ effectiveSiteMode: z4.enum(["disabled", "session_only", "full_analytics"]),
111
+ measurementEnabled: z4.boolean(),
112
+ issuedAt: z4.string().datetime({ offset: true }),
113
+ expiresAt: z4.string().datetime({ offset: true })
114
+ }).strict().superRefine((config, context) => {
115
+ const lifetime = Date.parse(config.expiresAt) - Date.parse(config.issuedAt);
116
+ if (lifetime <= 0 || lifetime > ANALYTICS_CONFIG_LEASE_MS) {
117
+ context.addIssue({
118
+ code: "custom",
119
+ path: ["expiresAt"],
120
+ message: "Measurement permission must expire within 60 seconds."
121
+ });
122
+ }
123
+ if (config.measurementEnabled !== (config.effectiveSiteMode !== "disabled")) {
124
+ context.addIssue({
125
+ code: "custom",
126
+ path: ["measurementEnabled"],
127
+ message: "Measurement permission must match the effective site mode."
128
+ });
129
+ }
130
+ });
131
+
132
+ // ../shared/dist/analytics-events.js
133
+ import { z as z5 } from "zod";
105
134
  var ANALYTICS_SCHEMA_VERSION = "analytics.v1";
106
135
  var ANALYTICS_KEY_PATTERN = /^(pk|sk)_siteplane_([A-Za-z0-9_-]{16})_[A-Za-z0-9_-]{43}$/;
107
- var analyticsSessionIdSchema = z4.string().regex(/^cpa_s_[a-f0-9]{32}$/u);
108
- var analyticsVisitorIdSchema = z4.string().regex(/^cpa_v_[a-f0-9]{32}$/u);
109
- var analyticsPersistedIdentityHashSchema = z4.string().regex(/^[a-f0-9]{64}$/u);
136
+ var analyticsSessionIdSchema = z5.string().regex(/^cpa_s_[a-f0-9]{32}$/u);
137
+ var analyticsVisitorIdSchema = z5.string().regex(/^cpa_v_[a-f0-9]{32}$/u);
138
+ var analyticsPersistedIdentityHashSchema = z5.string().regex(/^[a-f0-9]{64}$/u);
110
139
  var analyticsEventNames = [
111
140
  "page_view",
112
141
  "section_view",
@@ -186,41 +215,43 @@ var analyticsValidityStatuses = [
186
215
  "rejected",
187
216
  "ignored"
188
217
  ];
189
- var analyticsEventNameSchema = z4.enum(analyticsEventNames);
190
- var serverOnlyAnalyticsEventSchema = z4.enum(serverOnlyAnalyticsEvents);
191
- var analyticsEventSourceSchema = z4.enum(analyticsEventSources);
192
- var analyticsIngestionChannelSchema = z4.enum(analyticsIngestionChannels);
193
- var analyticsTargetTypeSchema = z4.enum(analyticsTargetTypes);
194
- var analyticsDataAttributeEventSchema = z4.enum(analyticsDataAttributeEvents);
195
- var analyticsDeviceTypeSchema = z4.enum(analyticsDeviceTypes);
196
- var analyticsBotClassificationSchema = z4.enum(analyticsBotClassifications);
197
- var analyticsValidityStatusSchema = z4.enum(analyticsValidityStatuses);
198
- var analyticsPropertiesSchema = z4.record(z4.string(), z4.unknown());
199
- var analyticsTimestampSchema = z4.string().datetime({ offset: true });
200
- var analyticsBrowserEventSchema = z4.object({
201
- eventId: z4.string().min(1).max(160),
218
+ var analyticsEventNameSchema = z5.enum(analyticsEventNames);
219
+ var serverOnlyAnalyticsEventSchema = z5.enum(serverOnlyAnalyticsEvents);
220
+ var analyticsEventSourceSchema = z5.enum(analyticsEventSources);
221
+ var analyticsIngestionChannelSchema = z5.enum(analyticsIngestionChannels);
222
+ var analyticsTargetTypeSchema = z5.enum(analyticsTargetTypes);
223
+ var analyticsDataAttributeEventSchema = z5.enum(analyticsDataAttributeEvents);
224
+ var analyticsDeviceTypeSchema = z5.enum(analyticsDeviceTypes);
225
+ var analyticsBotClassificationSchema = z5.enum(analyticsBotClassifications);
226
+ var analyticsValidityStatusSchema = z5.enum(analyticsValidityStatuses);
227
+ var analyticsPropertiesSchema = z5.record(z5.string(), z5.unknown());
228
+ var analyticsTimestampSchema = z5.string().datetime({ offset: true });
229
+ var analyticsBrowserEventSchema = z5.object({
230
+ eventId: z5.string().min(1).max(160),
231
+ installationGeneration: z5.number().int().positive().optional(),
232
+ measurementMode: z5.enum(["session_only", "full_analytics"]).optional(),
202
233
  eventName: analyticsEventNameSchema,
203
234
  eventSource: analyticsEventSourceSchema.optional().default("browser"),
204
- targetId: z4.string().min(1).max(160).optional(),
235
+ targetId: z5.string().min(1).max(160).optional(),
205
236
  targetType: analyticsTargetTypeSchema.optional(),
206
237
  visitorId: analyticsVisitorIdSchema.optional(),
207
238
  sessionId: analyticsSessionIdSchema,
208
- idempotencyKey: z4.string().min(1).max(240).optional(),
239
+ idempotencyKey: z5.string().min(1).max(240).optional(),
209
240
  occurredAt: analyticsTimestampSchema,
210
- pageUrl: z4.string().url().max(2048).optional(),
211
- pagePath: z4.string().min(1).max(1024).optional(),
212
- routeTemplate: z4.string().min(1).max(1024).optional(),
213
- referrer: z4.string().url().max(2048).optional(),
214
- utmSource: z4.string().min(1).max(200).optional(),
215
- utmMedium: z4.string().min(1).max(200).optional(),
216
- utmCampaign: z4.string().min(1).max(200).optional(),
217
- utmContent: z4.string().min(1).max(200).optional(),
218
- utmTerm: z4.string().min(1).max(200).optional(),
241
+ pageUrl: z5.string().url().max(2048).optional(),
242
+ pagePath: z5.string().min(1).max(1024).optional(),
243
+ routeTemplate: z5.string().min(1).max(1024).optional(),
244
+ referrer: z5.string().url().max(2048).optional(),
245
+ utmSource: z5.string().min(1).max(200).optional(),
246
+ utmMedium: z5.string().min(1).max(200).optional(),
247
+ utmCampaign: z5.string().min(1).max(200).optional(),
248
+ utmContent: z5.string().min(1).max(200).optional(),
249
+ utmTerm: z5.string().min(1).max(200).optional(),
219
250
  deviceType: analyticsDeviceTypeSchema.optional(),
220
- browserName: z4.string().min(1).max(120).optional(),
221
- osName: z4.string().min(1).max(120).optional(),
222
- country: z4.string().min(1).max(80).optional(),
223
- region: z4.string().min(1).max(120).optional(),
251
+ browserName: z5.string().min(1).max(120).optional(),
252
+ osName: z5.string().min(1).max(120).optional(),
253
+ country: z5.string().min(1).max(80).optional(),
254
+ region: z5.string().min(1).max(120).optional(),
224
255
  properties: analyticsPropertiesSchema.optional().default({})
225
256
  }).superRefine((event, context) => {
226
257
  if (isServerOnlyAnalyticsEvent(event.eventName)) {
@@ -245,44 +276,44 @@ var analyticsBrowserEventSchema = z4.object({
245
276
  });
246
277
  }
247
278
  });
248
- var analyticsBrowserEventPayloadSchema = z4.object({
249
- siteKey: z4.string().min(1),
250
- schemaVersion: z4.literal(ANALYTICS_SCHEMA_VERSION),
251
- mode: z4.enum(["live", "test"]).optional().default("live"),
252
- events: z4.array(analyticsBrowserEventSchema).min(1).max(50)
279
+ var analyticsBrowserEventPayloadSchema = z5.object({
280
+ siteKey: z5.string().min(1),
281
+ schemaVersion: z5.literal(ANALYTICS_SCHEMA_VERSION),
282
+ mode: z5.enum(["live", "test"]).optional().default("live"),
283
+ events: z5.array(analyticsBrowserEventSchema).min(1).max(50)
253
284
  });
254
- var analyticsNormalizedEventBaseSchema = z4.object({
255
- site_id: z4.string().uuid(),
256
- event_id: z4.string().min(1).max(160),
257
- schema_version: z4.literal(ANALYTICS_SCHEMA_VERSION),
285
+ var analyticsNormalizedEventBaseSchema = z5.object({
286
+ site_id: z5.string().uuid(),
287
+ event_id: z5.string().min(1).max(160),
288
+ schema_version: z5.literal(ANALYTICS_SCHEMA_VERSION),
258
289
  event_name: analyticsEventNameSchema,
259
290
  event_source: analyticsEventSourceSchema,
260
291
  ingestion_channel: analyticsIngestionChannelSchema,
261
- target_id: z4.string().min(1).max(160).nullable().optional(),
292
+ target_id: z5.string().min(1).max(160).nullable().optional(),
262
293
  target_type: analyticsTargetTypeSchema.nullable().optional(),
263
- dedupe_key: z4.string().regex(/^analytics_dedupe_v1_[a-f0-9]{64}$/u).nullable().optional(),
264
- idempotency_key: z4.string().min(1).max(240).nullable().optional(),
294
+ dedupe_key: z5.string().regex(/^analytics_dedupe_v1_[a-f0-9]{64}$/u).nullable().optional(),
295
+ idempotency_key: z5.string().min(1).max(240).nullable().optional(),
265
296
  bot_classification: analyticsBotClassificationSchema,
266
297
  validity_status: analyticsValidityStatusSchema,
267
- rejection_reason: z4.string().min(1).max(240).nullable().optional(),
298
+ rejection_reason: z5.string().min(1).max(240).nullable().optional(),
268
299
  occurred_at: analyticsTimestampSchema,
269
300
  received_at: analyticsTimestampSchema,
270
- page_url: z4.string().url().max(2048).nullable().optional(),
271
- page_path: z4.string().min(1).max(1024).nullable().optional(),
272
- route_template: z4.string().min(1).max(1024).nullable().optional(),
273
- referrer: z4.string().url().max(2048).nullable().optional(),
274
- utm_source: z4.string().min(1).max(200).nullable().optional(),
275
- utm_medium: z4.string().min(1).max(200).nullable().optional(),
276
- utm_campaign: z4.string().min(1).max(200).nullable().optional(),
277
- utm_content: z4.string().min(1).max(200).nullable().optional(),
278
- utm_term: z4.string().min(1).max(200).nullable().optional(),
279
- country: z4.string().min(1).max(80).nullable().optional(),
280
- region: z4.string().min(1).max(120).nullable().optional(),
301
+ page_url: z5.string().url().max(2048).nullable().optional(),
302
+ page_path: z5.string().min(1).max(1024).nullable().optional(),
303
+ route_template: z5.string().min(1).max(1024).nullable().optional(),
304
+ referrer: z5.string().url().max(2048).nullable().optional(),
305
+ utm_source: z5.string().min(1).max(200).nullable().optional(),
306
+ utm_medium: z5.string().min(1).max(200).nullable().optional(),
307
+ utm_campaign: z5.string().min(1).max(200).nullable().optional(),
308
+ utm_content: z5.string().min(1).max(200).nullable().optional(),
309
+ utm_term: z5.string().min(1).max(200).nullable().optional(),
310
+ country: z5.string().min(1).max(80).nullable().optional(),
311
+ region: z5.string().min(1).max(120).nullable().optional(),
281
312
  device_type: analyticsDeviceTypeSchema,
282
- browser_name: z4.string().min(1).max(120).nullable().optional(),
283
- os_name: z4.string().min(1).max(120).nullable().optional(),
284
- provider: z4.string().min(1).max(120).nullable().optional(),
285
- provider_event_id: z4.string().min(1).max(240).nullable().optional(),
313
+ browser_name: z5.string().min(1).max(120).nullable().optional(),
314
+ os_name: z5.string().min(1).max(120).nullable().optional(),
315
+ provider: z5.string().min(1).max(120).nullable().optional(),
316
+ provider_event_id: z5.string().min(1).max(240).nullable().optional(),
286
317
  properties: analyticsPropertiesSchema
287
318
  });
288
319
  var analyticsRawNormalizedEventSchema = analyticsNormalizedEventBaseSchema.extend({
@@ -308,11 +339,11 @@ function expandAnalyticsDataAttributeEvent(event) {
308
339
  }
309
340
 
310
341
  // ../shared/dist/analytics-manifest.js
311
- import { z as z5 } from "zod";
312
- var analyticsTargetIdSchema = z5.string().min(1).max(120).regex(/^[a-zA-Z][a-zA-Z0-9]*(?:[._-][a-zA-Z0-9]+)*$/u, {
342
+ import { z as z6 } from "zod";
343
+ var analyticsTargetIdSchema = z6.string().min(1).max(120).regex(/^[a-zA-Z][a-zA-Z0-9]*(?:[._-][a-zA-Z0-9]+)*$/u, {
313
344
  message: "Analytics target IDs must be stable identifiers without whitespace or visible copy."
314
345
  });
315
- var analyticsManifestRecordSchema = z5.record(z5.string(), z5.unknown());
346
+ var analyticsManifestRecordSchema = z6.record(z6.string(), z6.unknown());
316
347
  var analyticsFormPurposes = [
317
348
  "contact",
318
349
  "lead",
@@ -321,21 +352,21 @@ var analyticsFormPurposes = [
321
352
  "login",
322
353
  "other"
323
354
  ];
324
- var analyticsFormPurposeSchema = z5.enum(analyticsFormPurposes);
325
- var analyticsManifestRouteSchema = z5.object({
326
- path: z5.string().min(1).max(1024),
327
- pageType: z5.string().min(1).max(120).optional(),
328
- label: z5.string().min(1).max(200).optional()
355
+ var analyticsFormPurposeSchema = z6.enum(analyticsFormPurposes);
356
+ var analyticsManifestRouteSchema = z6.object({
357
+ path: z6.string().min(1).max(1024),
358
+ pageType: z6.string().min(1).max(120).optional(),
359
+ label: z6.string().min(1).max(200).optional()
329
360
  }).passthrough();
330
- var analyticsManifestTargetSchema = z5.object({
361
+ var analyticsManifestTargetSchema = z6.object({
331
362
  id: analyticsTargetIdSchema,
332
363
  type: analyticsTargetTypeSchema,
333
364
  event: analyticsEventNameSchema.optional(),
334
- events: z5.array(analyticsEventNameSchema).min(1).max(20).optional(),
335
- route: z5.string().min(1).max(1024).optional(),
336
- label: z5.string().min(1).max(200).optional(),
337
- description: z5.string().min(1).max(1e3).optional(),
338
- autoActive: z5.boolean().optional(),
365
+ events: z6.array(analyticsEventNameSchema).min(1).max(20).optional(),
366
+ route: z6.string().min(1).max(1024).optional(),
367
+ label: z6.string().min(1).max(200).optional(),
368
+ description: z6.string().min(1).max(1e3).optional(),
369
+ autoActive: z6.boolean().optional(),
339
370
  sourceHints: analyticsManifestRecordSchema.optional()
340
371
  }).passthrough().superRefine((target, context) => {
341
372
  if (target.event === void 0 && target.events === void 0) {
@@ -360,21 +391,21 @@ var analyticsManifestTargetSchema = z5.object({
360
391
  });
361
392
  }
362
393
  });
363
- var analyticsManifestSchema = z5.object({
364
- schemaVersion: z5.literal(ANALYTICS_SCHEMA_VERSION),
365
- siteId: z5.string().min(1),
366
- siteKeyRef: z5.string().regex(/^env:[A-Z][A-Z0-9_]*$/u, {
394
+ var analyticsManifestSchema = z6.object({
395
+ schemaVersion: z6.literal(ANALYTICS_SCHEMA_VERSION),
396
+ siteId: z6.string().min(1),
397
+ siteKeyRef: z6.string().regex(/^env:[A-Z][A-Z0-9_]*$/u, {
367
398
  message: "siteKeyRef must be an environment-variable reference."
368
399
  }),
369
- siteKeyLookup: z5.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}$/),
370
- routes: z5.array(analyticsManifestRouteSchema),
371
- targets: z5.array(analyticsManifestTargetSchema),
400
+ siteKeyLookup: z6.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}$/),
401
+ routes: z6.array(analyticsManifestRouteSchema),
402
+ targets: z6.array(analyticsManifestTargetSchema),
372
403
  metadata: analyticsManifestRecordSchema.optional(),
373
- siteKey: z5.string().optional(),
374
- secretKey: z5.string().optional(),
375
- rawKey: z5.string().optional(),
376
- token: z5.string().optional(),
377
- accessToken: z5.string().optional()
404
+ siteKey: z6.string().optional(),
405
+ secretKey: z6.string().optional(),
406
+ rawKey: z6.string().optional(),
407
+ token: z6.string().optional(),
408
+ accessToken: z6.string().optional()
378
409
  }).passthrough().superRefine((manifest, context) => {
379
410
  const targetIds = /* @__PURE__ */ new Set();
380
411
  for (const [index, target] of manifest.targets.entries()) {
@@ -461,9 +492,9 @@ function isPlainRecord(value) {
461
492
  }
462
493
 
463
494
  // ../shared/dist/analytics-metrics.js
464
- import { z as z6 } from "zod";
495
+ import { z as z7 } from "zod";
465
496
  var analyticsVisitorQualities = ["exact", "estimated"];
466
- var analyticsVisitorQualitySchema = z6.enum(analyticsVisitorQualities);
497
+ var analyticsVisitorQualitySchema = z7.enum(analyticsVisitorQualities);
467
498
  var analyticsKpiKeys = [
468
499
  "pageViews",
469
500
  "sessions",
@@ -475,7 +506,7 @@ var analyticsKpiKeys = [
475
506
  "conversionRate",
476
507
  "inquiryRate"
477
508
  ];
478
- var analyticsKpiKeySchema = z6.enum(analyticsKpiKeys);
509
+ var analyticsKpiKeySchema = z7.enum(analyticsKpiKeys);
479
510
 
480
511
  // ../shared/dist/analytics-privacy.js
481
512
  var serverPropertySchemas = {
@@ -513,7 +544,7 @@ function revenuePropertySchema() {
513
544
  }
514
545
 
515
546
  // ../shared/dist/assets.js
516
- import { z as z7 } from "zod";
547
+ import { z as z8 } from "zod";
517
548
  var ASSET_STAGES = ["staging", "final", "deleted"];
518
549
  var ASSET_VISIBILITIES = ["private", "public", "deleted"];
519
550
  var ASSET_USAGE_ENTITY_TYPES = [
@@ -522,13 +553,13 @@ var ASSET_USAGE_ENTITY_TYPES = [
522
553
  "change_set",
523
554
  "published_value"
524
555
  ];
525
- var assetStageSchema = z7.enum(ASSET_STAGES);
526
- var assetVisibilitySchema = z7.enum(ASSET_VISIBILITIES);
527
- var assetUsageEntityTypeSchema = z7.enum(ASSET_USAGE_ENTITY_TYPES);
528
- var brandingAccentColorSchema = z7.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);
556
+ var assetStageSchema = z8.enum(ASSET_STAGES);
557
+ var assetVisibilitySchema = z8.enum(ASSET_VISIBILITIES);
558
+ var assetUsageEntityTypeSchema = z8.enum(ASSET_USAGE_ENTITY_TYPES);
559
+ var brandingAccentColorSchema = z8.string().regex(/^#(?:[0-9a-fA-F]{3}|[0-9a-fA-F]{6})$/);
529
560
 
530
561
  // ../shared/dist/booking-contracts.js
531
- import { z as z8 } from "zod";
562
+ import { z as z9 } from "zod";
532
563
  var bookingStatuses = [
533
564
  "pending_payment",
534
565
  "confirmed",
@@ -583,30 +614,30 @@ var bookingResourceKinds = [
583
614
  "equipment",
584
615
  "other"
585
616
  ];
586
- var bookingStatusSchema = z8.enum(bookingStatuses);
587
- var bookingPaymentStatusSchema = z8.enum(bookingPaymentStatuses);
588
- var bookingAccountReadinessStatusSchema = z8.enum(bookingAccountReadinessStatuses);
589
- var bookingRefundStatusSchema = z8.enum(bookingRefundStatuses);
590
- var bookingDisputeStatusSchema = z8.enum(bookingDisputeStatuses);
591
- var bookingPaymentModeSchema = z8.enum(bookingPaymentModes);
592
- var bookingPaymentCollectionTypeSchema = z8.enum(bookingPaymentCollectionTypes);
593
- var bookingPaymentCollectionSchema = z8.discriminatedUnion("type", [
594
- z8.object({ type: z8.literal("full_amount") }).strict(),
595
- z8.object({
596
- type: z8.literal("deposit_percent"),
597
- depositPercent: z8.number().int().min(10).max(90)
617
+ var bookingStatusSchema = z9.enum(bookingStatuses);
618
+ var bookingPaymentStatusSchema = z9.enum(bookingPaymentStatuses);
619
+ var bookingAccountReadinessStatusSchema = z9.enum(bookingAccountReadinessStatuses);
620
+ var bookingRefundStatusSchema = z9.enum(bookingRefundStatuses);
621
+ var bookingDisputeStatusSchema = z9.enum(bookingDisputeStatuses);
622
+ var bookingPaymentModeSchema = z9.enum(bookingPaymentModes);
623
+ var bookingPaymentCollectionTypeSchema = z9.enum(bookingPaymentCollectionTypes);
624
+ var bookingPaymentCollectionSchema = z9.discriminatedUnion("type", [
625
+ z9.object({ type: z9.literal("full_amount") }).strict(),
626
+ z9.object({
627
+ type: z9.literal("deposit_percent"),
628
+ depositPercent: z9.number().int().min(10).max(90)
598
629
  }).strict()
599
630
  ]);
600
631
  var bookingPaymentChoices = ["onsite", "online"];
601
- var bookingPaymentChoiceSchema = z8.enum(bookingPaymentChoices);
602
- var bookingPaymentSnapshotSchema = z8.object({
603
- snapshotId: z8.string().uuid(),
604
- snapshotVersion: z8.number().int().positive(),
605
- currency: z8.literal("EUR"),
606
- totalAmountCents: z8.number().int().min(0),
607
- onlineAmountCents: z8.number().int().min(0),
608
- onsiteRemainderCents: z8.number().int().min(0),
609
- maxStripeRefundAmountCents: z8.number().int().min(0)
632
+ var bookingPaymentChoiceSchema = z9.enum(bookingPaymentChoices);
633
+ var bookingPaymentSnapshotSchema = z9.object({
634
+ snapshotId: z9.string().uuid(),
635
+ snapshotVersion: z9.number().int().positive(),
636
+ currency: z9.literal("EUR"),
637
+ totalAmountCents: z9.number().int().min(0),
638
+ onlineAmountCents: z9.number().int().min(0),
639
+ onsiteRemainderCents: z9.number().int().min(0),
640
+ maxStripeRefundAmountCents: z9.number().int().min(0)
610
641
  }).strict().superRefine((snapshot, context) => {
611
642
  if (snapshot.onlineAmountCents + snapshot.onsiteRemainderCents !== snapshot.totalAmountCents) {
612
643
  context.addIssue({
@@ -621,17 +652,17 @@ var bookingPaymentSnapshotSchema = z8.object({
621
652
  });
622
653
  }
623
654
  });
624
- var bookingServiceVariantSchema = z8.object({
625
- id: z8.string().uuid(),
626
- name: z8.string().trim().min(1).max(120),
627
- durationMinutes: z8.number().int().min(1).max(1440),
628
- priceCents: z8.number().int().min(0).nullable()
655
+ var bookingServiceVariantSchema = z9.object({
656
+ id: z9.string().uuid(),
657
+ name: z9.string().trim().min(1).max(120),
658
+ durationMinutes: z9.number().int().min(1).max(1440),
659
+ priceCents: z9.number().int().min(0).nullable()
629
660
  }).strict();
630
- var bookingServiceVariantsSchema = z8.array(bookingServiceVariantSchema).min(1).max(20);
631
- var isoDateSchema = z8.string().regex(/^\d{4}-\d{2}-\d{2}$/);
632
- var utcDateTimeSchema = z8.string().datetime();
633
- var bookingLocalTimeSchema = z8.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/);
634
- var bookingAvailabilityIntervalsSchema = z8.array(z8.object({
661
+ var bookingServiceVariantsSchema = z9.array(bookingServiceVariantSchema).min(1).max(20);
662
+ var isoDateSchema = z9.string().regex(/^\d{4}-\d{2}-\d{2}$/);
663
+ var utcDateTimeSchema = z9.string().datetime();
664
+ var bookingLocalTimeSchema = z9.string().regex(/^(?:[01]\d|2[0-3]):[0-5]\d$/);
665
+ var bookingAvailabilityIntervalsSchema = z9.array(z9.object({
635
666
  start: bookingLocalTimeSchema,
636
667
  end: bookingLocalTimeSchema
637
668
  }).strict().refine((interval) => interval.end > interval.start)).superRefine((intervals, context) => {
@@ -646,75 +677,75 @@ var bookingAvailabilityIntervalsSchema = z8.array(z8.object({
646
677
  }
647
678
  }
648
679
  });
649
- var bookingPublicConfigSchema = z8.object({
650
- site: z8.object({
651
- displayName: z8.string().trim().min(1),
652
- timezone: z8.string().trim().min(1),
653
- locale: z8.string().trim().min(2),
654
- bookingPageSlug: z8.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
655
- privacyUrl: z8.string().url().nullable()
680
+ var bookingPublicConfigSchema = z9.object({
681
+ site: z9.object({
682
+ displayName: z9.string().trim().min(1),
683
+ timezone: z9.string().trim().min(1),
684
+ locale: z9.string().trim().min(2),
685
+ bookingPageSlug: z9.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
686
+ privacyUrl: z9.string().url().nullable()
656
687
  }),
657
- branding: z8.object({
658
- logoUrl: z8.string().url().nullable(),
659
- accentColor: z8.string().trim().min(1).nullable()
688
+ branding: z9.object({
689
+ logoUrl: z9.string().url().nullable(),
690
+ accentColor: z9.string().trim().min(1).nullable()
660
691
  }),
661
- settings: z8.object({
662
- slotIntervalMinutes: z8.number().int().positive(),
663
- minLeadMinutes: z8.number().int().min(0),
664
- maxAdvanceDays: z8.number().int().min(1),
665
- requirePhone: z8.boolean(),
666
- collectNote: z8.boolean(),
667
- confirmationMessage: z8.string().nullable()
692
+ settings: z9.object({
693
+ slotIntervalMinutes: z9.number().int().positive(),
694
+ minLeadMinutes: z9.number().int().min(0),
695
+ maxAdvanceDays: z9.number().int().min(1),
696
+ requirePhone: z9.boolean(),
697
+ collectNote: z9.boolean(),
698
+ confirmationMessage: z9.string().nullable()
668
699
  }),
669
700
  /** Freitexte des Salons, im Kassen-Schritt vor der Bestaetigung sichtbar. */
670
- policies: z8.object({
671
- cancellation: z8.string().nullable(),
672
- lateArrival: z8.string().nullable()
701
+ policies: z9.object({
702
+ cancellation: z9.string().nullable(),
703
+ lateArrival: z9.string().nullable()
673
704
  }),
674
- payment: z8.object({
705
+ payment: z9.object({
675
706
  mode: bookingPaymentModeSchema,
676
707
  collection: bookingPaymentCollectionSchema,
677
- onlinePaymentsReady: z8.boolean()
708
+ onlinePaymentsReady: z9.boolean()
678
709
  }).strict(),
679
- serviceCategories: z8.array(z8.object({
680
- id: z8.string().uuid(),
681
- name: z8.string().trim().min(1),
682
- sortOrder: z8.number().int()
710
+ serviceCategories: z9.array(z9.object({
711
+ id: z9.string().uuid(),
712
+ name: z9.string().trim().min(1),
713
+ sortOrder: z9.number().int()
683
714
  })),
684
- serviceSubcategories: z8.array(z8.object({
685
- id: z8.string().uuid(),
686
- categoryId: z8.string().uuid(),
687
- name: z8.string().trim().min(1),
688
- sortOrder: z8.number().int()
715
+ serviceSubcategories: z9.array(z9.object({
716
+ id: z9.string().uuid(),
717
+ categoryId: z9.string().uuid(),
718
+ name: z9.string().trim().min(1),
719
+ sortOrder: z9.number().int()
689
720
  })),
690
- services: z8.array(z8.object({
691
- id: z8.string().trim().min(1),
692
- name: z8.string().trim().min(1),
693
- durationMinutes: z8.number().int().positive(),
694
- priceCents: z8.number().int().min(0).nullable(),
695
- currency: z8.string().regex(/^[A-Z]{3}$/),
696
- description: z8.string().nullable(),
697
- categoryId: z8.string().uuid(),
698
- subcategoryId: z8.string().uuid().nullable(),
721
+ services: z9.array(z9.object({
722
+ id: z9.string().trim().min(1),
723
+ name: z9.string().trim().min(1),
724
+ durationMinutes: z9.number().int().positive(),
725
+ priceCents: z9.number().int().min(0).nullable(),
726
+ currency: z9.string().regex(/^[A-Z]{3}$/),
727
+ description: z9.string().nullable(),
728
+ categoryId: z9.string().uuid(),
729
+ subcategoryId: z9.string().uuid().nullable(),
699
730
  variants: bookingServiceVariantsSchema,
700
- allowsAnyResource: z8.boolean(),
701
- sortOrder: z8.number().int()
731
+ allowsAnyResource: z9.boolean(),
732
+ sortOrder: z9.number().int()
702
733
  })),
703
- resources: z8.array(z8.object({
704
- id: z8.string().trim().min(1),
705
- name: z8.string().trim().min(1),
706
- kind: z8.enum(bookingResourceKinds)
734
+ resources: z9.array(z9.object({
735
+ id: z9.string().trim().min(1),
736
+ name: z9.string().trim().min(1),
737
+ kind: z9.enum(bookingResourceKinds)
707
738
  })),
708
- serviceResources: z8.array(z8.object({
709
- serviceId: z8.string().trim().min(1),
710
- resourceId: z8.string().trim().min(1)
739
+ serviceResources: z9.array(z9.object({
740
+ serviceId: z9.string().trim().min(1),
741
+ resourceId: z9.string().trim().min(1)
711
742
  }))
712
743
  });
713
- var bookingItemSchema = z8.object({
714
- serviceId: z8.string().trim().min(1),
715
- variantId: z8.string().trim().min(1)
744
+ var bookingItemSchema = z9.object({
745
+ serviceId: z9.string().trim().min(1),
746
+ variantId: z9.string().trim().min(1)
716
747
  }).strict();
717
- var bookingItemsSchema = z8.array(bookingItemSchema).min(1).max(10);
748
+ var bookingItemsSchema = z9.array(bookingItemSchema).min(1).max(10);
718
749
  function parseBookingItemsParam(value) {
719
750
  const items = value.split(",").map((entry) => entry.trim()).filter((entry) => entry !== "").map((entry) => {
720
751
  const [serviceId, variantId, ...rest] = entry.split(":");
@@ -722,36 +753,36 @@ function parseBookingItemsParam(value) {
722
753
  });
723
754
  return items.every((item) => item !== null) ? items : null;
724
755
  }
725
- var bookingSlotsQuerySchema = z8.object({
726
- items: z8.preprocess((value) => typeof value === "string" ? parseBookingItemsParam(value) : value, bookingItemsSchema),
727
- resourceId: z8.string().trim().min(1).optional(),
756
+ var bookingSlotsQuerySchema = z9.object({
757
+ items: z9.preprocess((value) => typeof value === "string" ? parseBookingItemsParam(value) : value, bookingItemsSchema),
758
+ resourceId: z9.string().trim().min(1).optional(),
728
759
  fromDate: isoDateSchema,
729
760
  toDate: isoDateSchema
730
761
  });
731
- var bookingSlotsResponseSchema = z8.object({
732
- timezone: z8.string().trim().min(1),
762
+ var bookingSlotsResponseSchema = z9.object({
763
+ timezone: z9.string().trim().min(1),
733
764
  items: bookingItemsSchema,
734
765
  // Reine Behandlungsdauer ohne Puffer: das UI zeigt damit die Terminspanne,
735
766
  // ohne selbst rechnen zu muessen.
736
- totalDurationMinutes: z8.number().int().min(1),
737
- mode: z8.enum(["any", "resource"]),
738
- slots: z8.array(z8.object({
767
+ totalDurationMinutes: z9.number().int().min(1),
768
+ mode: z9.enum(["any", "resource"]),
769
+ slots: z9.array(z9.object({
739
770
  startUtc: utcDateTimeSchema,
740
- resourceId: z8.string().trim().min(1).optional()
771
+ resourceId: z9.string().trim().min(1).optional()
741
772
  }))
742
773
  });
743
- var bookingAvailabilityQuerySchema = z8.object({
744
- items: z8.preprocess((value) => typeof value === "string" ? parseBookingItemsParam(value) : value, bookingItemsSchema),
745
- resourceId: z8.string().trim().min(1).optional(),
774
+ var bookingAvailabilityQuerySchema = z9.object({
775
+ items: z9.preprocess((value) => typeof value === "string" ? parseBookingItemsParam(value) : value, bookingItemsSchema),
776
+ resourceId: z9.string().trim().min(1).optional(),
746
777
  fromDate: isoDateSchema,
747
778
  toDate: isoDateSchema
748
779
  });
749
- var bookingAvailabilityResponseSchema = z8.object({
750
- timezone: z8.string().trim().min(1),
751
- totalDurationMinutes: z8.number().int().min(1),
752
- days: z8.array(z8.object({
780
+ var bookingAvailabilityResponseSchema = z9.object({
781
+ timezone: z9.string().trim().min(1),
782
+ totalDurationMinutes: z9.number().int().min(1),
783
+ days: z9.array(z9.object({
753
784
  date: isoDateSchema,
754
- hasSlots: z8.boolean()
785
+ hasSlots: z9.boolean()
755
786
  })),
756
787
  /** Erster Tag mit Slot ab `fromDate`, auch ausserhalb des Fensters. */
757
788
  nextAvailableDate: isoDateSchema.nullable()
@@ -769,72 +800,72 @@ var bookingPublicErrorCodes = [
769
800
  "too_late",
770
801
  "not_found"
771
802
  ];
772
- var bookingPublicErrorSchema = z8.object({
773
- error: z8.enum(bookingPublicErrorCodes),
774
- message: z8.string().optional(),
775
- requestId: z8.string().optional()
803
+ var bookingPublicErrorSchema = z9.object({
804
+ error: z9.enum(bookingPublicErrorCodes),
805
+ message: z9.string().optional(),
806
+ requestId: z9.string().optional()
776
807
  }).strict();
777
- var bookingCreateRequestSchema = z8.object({
808
+ var bookingCreateRequestSchema = z9.object({
778
809
  items: bookingItemsSchema,
779
- resourceId: z8.string().min(1).nullable(),
810
+ resourceId: z9.string().min(1).nullable(),
780
811
  startUtc: utcDateTimeSchema,
781
- customer: z8.object({
782
- name: z8.string().min(1).max(120),
783
- email: z8.string().email().max(254),
784
- phone: z8.string().max(32).optional(),
785
- note: z8.string().max(1e3).optional()
812
+ customer: z9.object({
813
+ name: z9.string().min(1).max(120),
814
+ email: z9.string().email().max(254),
815
+ phone: z9.string().max(32).optional(),
816
+ note: z9.string().max(1e3).optional()
786
817
  }).strict(),
787
- hp: z8.string().optional(),
788
- clientToken: z8.string().uuid(),
818
+ hp: z9.string().optional(),
819
+ clientToken: z9.string().uuid(),
789
820
  paymentChoice: bookingPaymentChoiceSchema,
790
821
  // Werbe-Einwilligung. Bestaetigung, Erinnerung und Storno-Link sind davon
791
822
  // unabhaengig und werden immer versendet.
792
- consent: z8.object({
793
- marketingEmail: z8.boolean(),
794
- marketingSms: z8.boolean()
823
+ consent: z9.object({
824
+ marketingEmail: z9.boolean(),
825
+ marketingSms: z9.boolean()
795
826
  }).strict().optional()
796
827
  }).strict();
797
- var bookingPublicPaymentResponseSchema = z8.object({
798
- clientSecret: z8.string().min(1),
799
- stripeAccountId: z8.string().startsWith("acct_")
828
+ var bookingPublicPaymentResponseSchema = z9.object({
829
+ clientSecret: z9.string().min(1),
830
+ stripeAccountId: z9.string().startsWith("acct_")
800
831
  }).strict();
801
- var bookingCreateResponseSchema = z8.union([
802
- z8.object({
803
- status: z8.literal("confirmed"),
804
- booking: z8.object({
805
- id: z8.string().min(1),
832
+ var bookingCreateResponseSchema = z9.union([
833
+ z9.object({
834
+ status: z9.literal("confirmed"),
835
+ booking: z9.object({
836
+ id: z9.string().min(1),
806
837
  startUtc: utcDateTimeSchema,
807
838
  endUtc: utcDateTimeSchema,
808
- timezone: z8.string().trim().min(1),
809
- serviceName: z8.string().trim().min(1),
810
- resourceName: z8.string().trim().min(1)
839
+ timezone: z9.string().trim().min(1),
840
+ serviceName: z9.string().trim().min(1),
841
+ resourceName: z9.string().trim().min(1)
811
842
  }).strict(),
812
- manageUrl: z8.string().url(),
813
- confirmationMessage: z8.string().nullable()
843
+ manageUrl: z9.string().url(),
844
+ confirmationMessage: z9.string().nullable()
814
845
  }).strict(),
815
- z8.object({
816
- status: z8.literal("pending_payment"),
817
- bookingId: z8.string().min(1),
846
+ z9.object({
847
+ status: z9.literal("pending_payment"),
848
+ bookingId: z9.string().min(1),
818
849
  holdExpiresAt: utcDateTimeSchema,
819
850
  payment: bookingPublicPaymentResponseSchema,
820
- statusToken: z8.string().min(20),
821
- manageUrl: z8.string().url().optional()
851
+ statusToken: z9.string().min(20),
852
+ manageUrl: z9.string().url().optional()
822
853
  }).strict(),
823
854
  bookingPublicErrorSchema
824
855
  ]);
825
- var bookingStatusResponseSchema = z8.object({
856
+ var bookingStatusResponseSchema = z9.object({
826
857
  bookingStatus: bookingStatusSchema,
827
858
  paymentStatus: bookingPaymentStatusSchema,
828
859
  refundStatus: bookingRefundStatusSchema,
829
860
  disputeStatus: bookingDisputeStatusSchema,
830
861
  holdExpiresAt: utcDateTimeSchema.nullable()
831
862
  }).strict();
832
- var bookingCancelRequestSchema = z8.object({
833
- token: z8.string().min(20)
863
+ var bookingCancelRequestSchema = z9.object({
864
+ token: z9.string().min(20)
834
865
  });
835
- var bookingCancelResponseSchema = z8.union([
836
- z8.object({
837
- status: z8.enum(["cancelled", "already_cancelled", "too_late", "not_found"])
866
+ var bookingCancelResponseSchema = z9.union([
867
+ z9.object({
868
+ status: z9.enum(["cancelled", "already_cancelled", "too_late", "not_found"])
838
869
  }),
839
870
  bookingPublicErrorSchema
840
871
  ]);
@@ -843,34 +874,34 @@ var bookingMoveErrorCodes = [
843
874
  "booking_not_movable",
844
875
  "not_found"
845
876
  ];
846
- var bookingMoveRequestSchema = z8.object({
847
- bookingId: z8.string().uuid(),
877
+ var bookingMoveRequestSchema = z9.object({
878
+ bookingId: z9.string().uuid(),
848
879
  newStartUtc: utcDateTimeSchema,
849
- newResourceId: z8.string().uuid().optional(),
850
- notifyCustomer: z8.boolean().default(false),
851
- reason: z8.string().max(500).optional()
880
+ newResourceId: z9.string().uuid().optional(),
881
+ notifyCustomer: z9.boolean().default(false),
882
+ reason: z9.string().max(500).optional()
852
883
  });
853
- var bookingMoveResponseSchema = z8.union([
854
- z8.object({
855
- status: z8.literal("moved"),
856
- bookingId: z8.string().uuid(),
884
+ var bookingMoveResponseSchema = z9.union([
885
+ z9.object({
886
+ status: z9.literal("moved"),
887
+ bookingId: z9.string().uuid(),
857
888
  startUtc: utcDateTimeSchema,
858
889
  endUtc: utcDateTimeSchema,
859
- resourceId: z8.string().uuid()
890
+ resourceId: z9.string().uuid()
860
891
  }),
861
- z8.object({
862
- error: z8.enum(bookingMoveErrorCodes),
863
- message: z8.string().optional(),
864
- requestId: z8.string().optional()
892
+ z9.object({
893
+ error: z9.enum(bookingMoveErrorCodes),
894
+ message: z9.string().optional(),
895
+ requestId: z9.string().optional()
865
896
  })
866
897
  ]);
867
- var bookingManifestSchema = z8.object({
868
- schemaVersion: z8.number().int().positive(),
869
- siteId: z8.string().trim().min(1),
870
- siteKeyPrefix: z8.string().startsWith("bk_pub_"),
871
- bookingPageSlug: z8.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
872
- embedMode: z8.enum(["script", "web_component", "iframe"]).optional(),
873
- productionOrigin: z8.string().url().optional()
898
+ var bookingManifestSchema = z9.object({
899
+ schemaVersion: z9.number().int().positive(),
900
+ siteId: z9.string().trim().min(1),
901
+ siteKeyPrefix: z9.string().startsWith("bk_pub_"),
902
+ bookingPageSlug: z9.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
903
+ embedMode: z9.enum(["script", "web_component", "iframe"]).optional(),
904
+ productionOrigin: z9.string().url().optional()
874
905
  }).passthrough();
875
906
  var secretManifestKeys = /* @__PURE__ */ new Set([
876
907
  "siteKey",
@@ -892,23 +923,23 @@ function redactBookingManifest(value) {
892
923
  var BOOKING_CREATE_PAYLOAD_LIMIT_BYTES = 16 * 1024;
893
924
 
894
925
  // ../shared/dist/bridge-protocol.js
895
- import { z as z16 } from "zod";
926
+ import { z as z17 } from "zod";
896
927
 
897
928
  // ../shared/dist/field-id.js
898
- import { z as z9 } from "zod";
929
+ import { z as z10 } from "zod";
899
930
  var FIELD_ID_PATTERN = /^[a-z][a-z0-9_-]*(\.[a-z][a-z0-9_-]*)+$/;
900
- var fieldIdSchema = z9.string().regex(FIELD_ID_PATTERN, "Invalid field id");
931
+ var fieldIdSchema = z10.string().regex(FIELD_ID_PATTERN, "Invalid field id");
901
932
  function isFieldId(value) {
902
933
  return typeof value === "string" && fieldIdSchema.safeParse(value).success;
903
934
  }
904
935
 
905
936
  // ../shared/dist/field-types.js
906
- import { z as z10 } from "zod";
937
+ import { z as z11 } from "zod";
907
938
  var FIELD_TYPES = ["text", "longText", "image", "link"];
908
- var fieldTypeSchema = z10.enum(FIELD_TYPES);
939
+ var fieldTypeSchema = z11.enum(FIELD_TYPES);
909
940
 
910
941
  // ../shared/dist/image-value.js
911
- import { z as z11 } from "zod";
942
+ import { z as z12 } from "zod";
912
943
  var SUPPORTED_IMAGE_CONTENT_TYPES = [
913
944
  "image/jpeg",
914
945
  "image/png",
@@ -917,21 +948,21 @@ var SUPPORTED_IMAGE_CONTENT_TYPES = [
917
948
  ];
918
949
  var maxImageUploadBytes = 10 * 1024 * 1024;
919
950
  var largeImageWarningBytes = 2 * 1024 * 1024;
920
- var imageContentTypeSchema = z11.enum(SUPPORTED_IMAGE_CONTENT_TYPES);
921
- var imageCropSchema = z11.object({
922
- x: z11.number().min(0).max(100),
923
- y: z11.number().min(0).max(100),
924
- zoom: z11.number().min(1).max(4),
925
- aspectRatio: z11.number().positive().max(10)
951
+ var imageContentTypeSchema = z12.enum(SUPPORTED_IMAGE_CONTENT_TYPES);
952
+ var imageCropSchema = z12.object({
953
+ x: z12.number().min(0).max(100),
954
+ y: z12.number().min(0).max(100),
955
+ zoom: z12.number().min(1).max(4),
956
+ aspectRatio: z12.number().positive().max(10)
926
957
  });
927
- var imageValueSchema = z11.object({
928
- src: z11.string().trim().min(1),
929
- alt: z11.string().trim().min(1).max(300),
930
- width: z11.number().int().positive().optional(),
931
- height: z11.number().int().positive().optional(),
958
+ var imageValueSchema = z12.object({
959
+ src: z12.string().trim().min(1),
960
+ alt: z12.string().trim().min(1).max(300),
961
+ width: z12.number().int().positive().optional(),
962
+ height: z12.number().int().positive().optional(),
932
963
  crop: imageCropSchema.optional(),
933
- assetId: z11.string().uuid().optional(),
934
- finalStorageProvider: z11.enum([
964
+ assetId: z12.string().uuid().optional(),
965
+ finalStorageProvider: z12.enum([
935
966
  "repo_static_assets",
936
967
  "repo_handoff",
937
968
  "site_owned_storage",
@@ -940,31 +971,36 @@ var imageValueSchema = z11.object({
940
971
  });
941
972
 
942
973
  // ../shared/dist/setup-deployment.js
943
- import { z as z12 } from "zod";
944
- var version = z12.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u);
945
- var hash = z12.string().regex(/^sha256:[0-9a-f]{64}$/u);
946
- var setupDeploymentRecordSchema = z12.object({
947
- version: z12.literal(1),
948
- operationId: z12.string().uuid(),
949
- provider: z12.literal("vercel"),
950
- projectId: z12.string().regex(/^prj_[A-Za-z0-9]+$/u),
951
- teamId: z12.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u),
952
- origin: z12.string().url().refine((value) => {
974
+ import { z as z13 } from "zod";
975
+ var version = z13.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u);
976
+ var siteSetupPackagesSchema = z13.object({
977
+ siteplane: version,
978
+ runtimeNext: version,
979
+ analytics: version.optional()
980
+ }).strict();
981
+ var hash = z13.string().regex(/^sha256:[0-9a-f]{64}$/u);
982
+ var setupDeploymentRecordSchema = z13.object({
983
+ version: z13.literal(1),
984
+ operationId: z13.string().uuid(),
985
+ provider: z13.literal("vercel"),
986
+ projectId: z13.string().regex(/^prj_[A-Za-z0-9]+$/u),
987
+ teamId: z13.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u),
988
+ origin: z13.string().url().refine((value) => {
953
989
  const url = new URL(value);
954
990
  return url.protocol === "https:" && url.origin === value && !url.username && !url.password;
955
991
  }),
956
- deploymentId: z12.string().regex(/^dpl_[A-Za-z0-9]+$/u).nullable(),
957
- revision: z12.string().regex(/^[0-9a-f]{40}$/u),
992
+ deploymentId: z13.string().regex(/^dpl_[A-Za-z0-9]+$/u).nullable(),
993
+ revision: z13.string().regex(/^[0-9a-f]{40}$/u),
958
994
  fieldContractHash: hash,
959
- packages: z12.object({ siteplane: version, runtimeNext: version }).strict(),
995
+ packages: siteSetupPackagesSchema,
960
996
  configurationFingerprint: hash,
961
- adminSecretGeneration: z12.string().uuid(),
962
- revalidationGeneration: z12.number().int().positive(),
963
- startedAt: z12.string().datetime(),
964
- environmentWrittenAt: z12.string().datetime().nullable(),
965
- deployRequestedAt: z12.string().datetime().nullable(),
966
- deadline: z12.string().datetime(),
967
- phase: z12.enum([
997
+ adminSecretGeneration: z13.string().uuid(),
998
+ revalidationGeneration: z13.number().int().positive(),
999
+ startedAt: z13.string().datetime(),
1000
+ environmentWrittenAt: z13.string().datetime().nullable(),
1001
+ deployRequestedAt: z13.string().datetime().nullable(),
1002
+ deadline: z13.string().datetime(),
1003
+ phase: z13.enum([
968
1004
  "planned",
969
1005
  "environment_written",
970
1006
  "deploy_requested",
@@ -972,37 +1008,37 @@ var setupDeploymentRecordSchema = z12.object({
972
1008
  "verified",
973
1009
  "failed"
974
1010
  ]),
975
- build: z12.object({
1011
+ build: z13.object({
976
1012
  node: version,
977
- packageManager: z12.enum(["npm", "pnpm"]),
1013
+ packageManager: z13.enum(["npm", "pnpm"]),
978
1014
  packageManagerVersion: version,
979
1015
  lockfileHash: hash
980
1016
  }).strict().nullable()
981
1017
  }).strict();
982
- var setupDeploymentInputSchema = z12.discriminatedUnion("action", [
983
- z12.object({ action: z12.literal("read") }).strict(),
984
- z12.object({
985
- action: z12.literal("record"),
986
- expectedOperationId: z12.string().uuid().nullable(),
1018
+ var setupDeploymentInputSchema = z13.discriminatedUnion("action", [
1019
+ z13.object({ action: z13.literal("read") }).strict(),
1020
+ z13.object({
1021
+ action: z13.literal("record"),
1022
+ expectedOperationId: z13.string().uuid().nullable(),
987
1023
  record: setupDeploymentRecordSchema
988
1024
  }).strict()
989
1025
  ]);
990
1026
 
991
1027
  // ../shared/dist/site-setup.js
992
- import { z as z15 } from "zod";
1028
+ import { z as z16 } from "zod";
993
1029
 
994
1030
  // ../shared/dist/site-field-contract.js
995
- import { z as z14 } from "zod";
1031
+ import { z as z15 } from "zod";
996
1032
 
997
1033
  // ../shared/dist/fallback-hash.js
998
- import { z as z13 } from "zod";
1034
+ import { z as z14 } from "zod";
999
1035
  var SAFE_REPRESENTATION_REASONS = [
1000
1036
  "asset_import_rewritten",
1001
1037
  "relative_url_normalized",
1002
1038
  "line_endings_normalized",
1003
1039
  "image_value_serialized"
1004
1040
  ];
1005
- var safeRepresentationReasonSchema = z13.enum(SAFE_REPRESENTATION_REASONS);
1041
+ var safeRepresentationReasonSchema = z14.enum(SAFE_REPRESENTATION_REASONS);
1006
1042
  function canonicalizeFallbackValue(input) {
1007
1043
  const fieldType = fieldTypeSchema.parse(input.fieldType);
1008
1044
  if (input.safeRepresentationReason !== void 0) {
@@ -1038,10 +1074,10 @@ function createCanonicalFallbackHash(input) {
1038
1074
  const payload = stableJsonStringify(canonical);
1039
1075
  return `sha256:${sha256Hex(payload)}`;
1040
1076
  }
1041
- var linkFallbackSchema = z13.object({
1042
- href: z13.string().trim().min(1),
1043
- label: z13.string().trim().min(1).optional(),
1044
- target: z13.enum(["_self", "_blank"]).optional()
1077
+ var linkFallbackSchema = z14.object({
1078
+ href: z14.string().trim().min(1),
1079
+ label: z14.string().trim().min(1).optional(),
1080
+ target: z14.enum(["_self", "_blank"]).optional()
1045
1081
  }).passthrough();
1046
1082
  function normalizeLineEndings(value) {
1047
1083
  return value.replace(/\r\n/g, "\n").replace(/\r/g, "\n");
@@ -1219,67 +1255,67 @@ var SHA256_CONSTANTS = [
1219
1255
  // ../shared/dist/site-field-contract.js
1220
1256
  var fieldContractVersion = "1.0.0";
1221
1257
  var scannerContractVersion = "1.0.0";
1222
- var siteFieldStatusSchema = z14.enum(["hidden", "active"]);
1223
- var semanticVersionSchema = z14.string().regex(/^\d+\.\d+\.\d+$/u);
1224
- var siteFieldRouteKeySchema = z14.string().trim().refine((value) => value === "$global" || value.startsWith("/") && !value.includes("?") && !value.includes("#") && (value === "/" || !value.endsWith("/")), "Route keys must be canonical paths or $global.");
1225
- var repositoryRelativePosixPathSchema = z14.string().trim().min(1).refine((value) => !value.startsWith("/") && !value.includes("\\") && !/^[a-z]:/iu.test(value) && !value.split("/").includes(".."), "Source paths must be repository-relative POSIX paths.");
1226
- var sourceMappingSchema = z14.object({
1227
- kind: z14.literal("function"),
1258
+ var siteFieldStatusSchema = z15.enum(["hidden", "active"]);
1259
+ var semanticVersionSchema = z15.string().regex(/^\d+\.\d+\.\d+$/u);
1260
+ var siteFieldRouteKeySchema = z15.string().trim().refine((value) => value === "$global" || value.startsWith("/") && !value.includes("?") && !value.includes("#") && (value === "/" || !value.endsWith("/")), "Route keys must be canonical paths or $global.");
1261
+ var repositoryRelativePosixPathSchema = z15.string().trim().min(1).refine((value) => !value.startsWith("/") && !value.includes("\\") && !/^[a-z]:/iu.test(value) && !value.split("/").includes(".."), "Source paths must be repository-relative POSIX paths.");
1262
+ var sourceMappingSchema = z15.object({
1263
+ kind: z15.literal("function"),
1228
1264
  filePath: repositoryRelativePosixPathSchema,
1229
- exportName: z14.string().trim().min(1).optional(),
1230
- sourcePath: z14.string().trim().min(1).optional(),
1265
+ exportName: z15.string().trim().min(1).optional(),
1266
+ sourcePath: z15.string().trim().min(1).optional(),
1231
1267
  editTarget: fieldIdSchema.optional()
1232
1268
  }).strict();
1233
- var domMappingSchema = z14.object({
1234
- attribute: z14.literal("data-siteplane-field-id"),
1235
- previewStrategy: z14.enum(["dom", "event"])
1269
+ var domMappingSchema = z15.object({
1270
+ attribute: z15.literal("data-siteplane-field-id"),
1271
+ previewStrategy: z15.enum(["dom", "event"])
1236
1272
  }).strict();
1237
- var fieldBaseSchema = z14.object({
1273
+ var fieldBaseSchema = z15.object({
1238
1274
  fieldId: fieldIdSchema,
1239
1275
  routeKey: siteFieldRouteKeySchema,
1240
1276
  source: sourceMappingSchema,
1241
1277
  dom: domMappingSchema.optional()
1242
1278
  }).strict();
1243
- var linkFallbackSchema2 = z14.object({
1244
- href: z14.string().trim().min(1),
1245
- label: z14.string().trim().min(1).optional(),
1246
- target: z14.enum(["_self", "_blank"]).optional()
1279
+ var linkFallbackSchema2 = z15.object({
1280
+ href: z15.string().trim().min(1),
1281
+ label: z15.string().trim().min(1).optional(),
1282
+ target: z15.enum(["_self", "_blank"]).optional()
1247
1283
  }).strict();
1248
- var imageFallbackSchema = z14.object({
1249
- src: z14.string().trim().min(1),
1250
- alt: z14.string().trim().max(300),
1251
- width: z14.number().int().positive().optional(),
1252
- height: z14.number().int().positive().optional(),
1253
- crop: z14.object({
1254
- x: z14.number().min(0).max(100),
1255
- y: z14.number().min(0).max(100),
1256
- zoom: z14.number().min(1).max(4),
1257
- aspectRatio: z14.number().positive().max(10)
1284
+ var imageFallbackSchema = z15.object({
1285
+ src: z15.string().trim().min(1),
1286
+ alt: z15.string().trim().max(300),
1287
+ width: z15.number().int().positive().optional(),
1288
+ height: z15.number().int().positive().optional(),
1289
+ crop: z15.object({
1290
+ x: z15.number().min(0).max(100),
1291
+ y: z15.number().min(0).max(100),
1292
+ zoom: z15.number().min(1).max(4),
1293
+ aspectRatio: z15.number().positive().max(10)
1258
1294
  }).strict().optional()
1259
1295
  }).strict();
1260
- var siteFieldContractFieldSchema = z14.discriminatedUnion("fieldType", [
1296
+ var siteFieldContractFieldSchema = z15.discriminatedUnion("fieldType", [
1261
1297
  fieldBaseSchema.extend({
1262
- fieldType: z14.literal("text"),
1263
- fallback: z14.string()
1298
+ fieldType: z15.literal("text"),
1299
+ fallback: z15.string()
1264
1300
  }),
1265
1301
  fieldBaseSchema.extend({
1266
- fieldType: z14.literal("longText"),
1267
- fallback: z14.string()
1302
+ fieldType: z15.literal("longText"),
1303
+ fallback: z15.string()
1268
1304
  }),
1269
1305
  fieldBaseSchema.extend({
1270
- fieldType: z14.literal("link"),
1306
+ fieldType: z15.literal("link"),
1271
1307
  fallback: linkFallbackSchema2
1272
1308
  }),
1273
1309
  fieldBaseSchema.extend({
1274
- fieldType: z14.literal("image"),
1310
+ fieldType: z15.literal("image"),
1275
1311
  fallback: imageFallbackSchema
1276
1312
  })
1277
1313
  ]);
1278
- var siteFieldContractV1Schema = z14.object({
1279
- version: z14.literal(1),
1314
+ var siteFieldContractV1Schema = z15.object({
1315
+ version: z15.literal(1),
1280
1316
  fieldContractVersion: semanticVersionSchema,
1281
1317
  scannerContractVersion: semanticVersionSchema,
1282
- fields: z14.array(siteFieldContractFieldSchema)
1318
+ fields: z15.array(siteFieldContractFieldSchema)
1283
1319
  }).strict().superRefine((contract, context) => {
1284
1320
  const seen = /* @__PURE__ */ new Set();
1285
1321
  for (const [index, field] of contract.fields.entries()) {
@@ -1339,20 +1375,20 @@ var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH = 2e3;
1339
1375
  var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES = 8e3;
1340
1376
  var CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES = 32 * 1024;
1341
1377
  var CONTINUE_SITE_SETUP_HTTP_BODY_MAX_BYTES = 64 * 1024;
1342
- var siteSetupRunStatusSchema = z15.enum(SITE_SETUP_RUN_STATUSES);
1343
- var siteSetupRunModeSchema = z15.enum(SITE_SETUP_RUN_MODES);
1344
- var siteSetupErrorCodeSchema = z15.enum(SITE_SETUP_ERROR_CODES);
1345
- var editorFieldSchema = z15.object({
1378
+ var siteSetupRunStatusSchema = z16.enum(SITE_SETUP_RUN_STATUSES);
1379
+ var siteSetupRunModeSchema = z16.enum(SITE_SETUP_RUN_MODES);
1380
+ var siteSetupErrorCodeSchema = z16.enum(SITE_SETUP_ERROR_CODES);
1381
+ var editorFieldSchema = z16.object({
1346
1382
  fieldId: fieldIdSchema,
1347
- label: z15.string().trim().min(1),
1348
- subsection: z15.string().trim().min(1).optional(),
1349
- description: z15.string().trim().min(1).optional(),
1350
- required: z15.boolean().optional(),
1351
- maxLength: z15.number().int().positive().optional()
1383
+ label: z16.string().trim().min(1),
1384
+ subsection: z16.string().trim().min(1).optional(),
1385
+ description: z16.string().trim().min(1).optional(),
1386
+ required: z16.boolean().optional(),
1387
+ maxLength: z16.number().int().positive().optional()
1352
1388
  }).strict();
1353
- var editorSectionSchema = z15.object({
1354
- label: z15.string().trim().min(1),
1355
- fields: z15.array(editorFieldSchema).min(1)
1389
+ var editorSectionSchema = z16.object({
1390
+ label: z16.string().trim().min(1),
1391
+ fields: z16.array(editorFieldSchema).min(1)
1356
1392
  }).strict().superRefine((section, context) => {
1357
1393
  const closedSubsections = /* @__PURE__ */ new Set();
1358
1394
  let currentSubsection;
@@ -1371,10 +1407,10 @@ var editorSectionSchema = z15.object({
1371
1407
  }
1372
1408
  }
1373
1409
  });
1374
- var editorRouteSchema = z15.object({
1410
+ var editorRouteSchema = z16.object({
1375
1411
  routeKey: siteFieldRouteKeySchema,
1376
- label: z15.string().trim().min(1),
1377
- sections: z15.array(editorSectionSchema).min(1)
1412
+ label: z16.string().trim().min(1),
1413
+ sections: z16.array(editorSectionSchema).min(1)
1378
1414
  }).strict().superRefine((route, context) => {
1379
1415
  const sections = /* @__PURE__ */ new Set();
1380
1416
  for (const [index, section] of route.sections.entries()) {
@@ -1388,9 +1424,9 @@ var editorRouteSchema = z15.object({
1388
1424
  sections.add(section.label);
1389
1425
  }
1390
1426
  });
1391
- var editorDefinitionV1Schema = z15.object({
1392
- version: z15.literal(1),
1393
- routes: z15.array(editorRouteSchema).min(1)
1427
+ var editorDefinitionV1Schema = z16.object({
1428
+ version: z16.literal(1),
1429
+ routes: z16.array(editorRouteSchema).min(1)
1394
1430
  }).strict().superRefine((definition, context) => {
1395
1431
  const routes = /* @__PURE__ */ new Set();
1396
1432
  const fields = /* @__PURE__ */ new Set();
@@ -1428,7 +1464,7 @@ var editorDefinitionV1Schema = z15.object({
1428
1464
  var forbiddenControlOrBidi = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
1429
1465
  var forbiddenOwnerNoteControlOrBidi = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
1430
1466
  var unsafeLocator = /<\/?[a-z][^>]*>|\b(?:javascript|data:text\/html)\s*:|\bon[a-z]+\s*=/iu;
1431
- var renderedPathSchema = z15.string().trim().transform((value) => value !== "/" ? value.replace(/\/+$/u, "") : value).superRefine((value, context) => {
1467
+ var renderedPathSchema = z16.string().trim().transform((value) => value !== "/" ? value.replace(/\/+$/u, "") : value).superRefine((value, context) => {
1432
1468
  if (!value.startsWith("/") || value === "$global" || value.includes("?") || value.includes("#")) {
1433
1469
  context.addIssue({
1434
1470
  code: "custom",
@@ -1438,7 +1474,7 @@ var renderedPathSchema = z15.string().trim().transform((value) => value !== "/"
1438
1474
  addSafeByteIssues(value, CONTINUE_SITE_SETUP_RENDERED_PATH_MAX_BYTES, "renderedPath", context);
1439
1475
  });
1440
1476
  function normalizedSafeTextSchema(maxBytes, label) {
1441
- return z15.string().transform((value) => value.trim().replace(new RegExp("\\p{White_Space}+", "gu"), " ")).pipe(z15.string().min(1)).superRefine((value, context) => {
1477
+ return z16.string().transform((value) => value.trim().replace(new RegExp("\\p{White_Space}+", "gu"), " ")).pipe(z16.string().min(1)).superRefine((value, context) => {
1442
1478
  addSafeByteIssues(value, maxBytes, label, context);
1443
1479
  if (label === "locatorHint" && unsafeLocator.test(value)) {
1444
1480
  context.addIssue({
@@ -1455,12 +1491,12 @@ var correctionItemBase = {
1455
1491
  requestedLabel: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES, "requestedLabel").optional(),
1456
1492
  requestedSection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES, "requestedSection").optional(),
1457
1493
  requestedSubsection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES, "requestedSubsection").optional(),
1458
- requestedSortOrder: z15.number().int().nonnegative().optional()
1494
+ requestedSortOrder: z16.number().int().nonnegative().optional()
1459
1495
  };
1460
- var setupCorrectionItemSchema = z15.discriminatedUnion("kind", [
1461
- z15.object({ kind: z15.literal("text"), ...correctionItemBase }).strict(),
1462
- z15.object({ kind: z15.literal("link"), ...correctionItemBase }).strict(),
1463
- z15.object({ kind: z15.literal("image"), ...correctionItemBase }).strict()
1496
+ var setupCorrectionItemSchema = z16.discriminatedUnion("kind", [
1497
+ z16.object({ kind: z16.literal("text"), ...correctionItemBase }).strict(),
1498
+ z16.object({ kind: z16.literal("link"), ...correctionItemBase }).strict(),
1499
+ z16.object({ kind: z16.literal("image"), ...correctionItemBase }).strict()
1464
1500
  ]).superRefine((item, context) => {
1465
1501
  if (item.requestedSubsection && !item.requestedSection) {
1466
1502
  context.addIssue({
@@ -1470,7 +1506,7 @@ var setupCorrectionItemSchema = z15.discriminatedUnion("kind", [
1470
1506
  });
1471
1507
  }
1472
1508
  });
1473
- var setupCorrectionItemsSchema = z15.array(setupCorrectionItemSchema).max(CONTINUE_SITE_SETUP_MAX_ITEMS).superRefine((items, context) => {
1509
+ var setupCorrectionItemsSchema = z16.array(setupCorrectionItemSchema).max(CONTINUE_SITE_SETUP_MAX_ITEMS).superRefine((items, context) => {
1474
1510
  const bytes = utf8Bytes(stableJsonStringify(items));
1475
1511
  if (bytes > CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES) {
1476
1512
  context.addIssue({
@@ -1479,7 +1515,7 @@ var setupCorrectionItemsSchema = z15.array(setupCorrectionItemSchema).max(CONTIN
1479
1515
  });
1480
1516
  }
1481
1517
  });
1482
- var siteSetupOwnerEditabilityNoteSchema = z15.string().max(SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH).superRefine((value, context) => {
1518
+ var siteSetupOwnerEditabilityNoteSchema = z16.string().max(SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH).superRefine((value, context) => {
1483
1519
  if (utf8Bytes(value) > SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES) {
1484
1520
  context.addIssue({
1485
1521
  code: "custom",
@@ -1504,7 +1540,7 @@ var SITE_SETUP_MODULE_SCOPES = {
1504
1540
  "analytics:public_key_read"
1505
1541
  ]
1506
1542
  };
1507
- var siteSetupModulesSchema = z15.array(z15.enum(["editing", "analytics"])).min(1).max(2).refine((modules) => modules[0] === "editing" && (modules.length === 1 || modules[1] === "analytics"), "Choose Editing with optional Analytics.");
1543
+ var siteSetupModulesSchema = z16.array(z16.enum(["editing", "analytics"])).min(1).max(2).refine((modules) => modules[0] === "editing" && (modules.length === 1 || modules[1] === "analytics"), "Choose Editing with optional Analytics.");
1508
1544
  function siteSetupScopes(modules) {
1509
1545
  return modules.flatMap((module) => [...SITE_SETUP_MODULE_SCOPES[module]]);
1510
1546
  }
@@ -1512,15 +1548,15 @@ function hasExactSiteSetupScopes(scopes, modules) {
1512
1548
  const matches = (expected) => scopes.length === expected.length && expected.every((scope) => scopes.includes(scope));
1513
1549
  return modules ? matches(siteSetupScopes(modules)) : matches(siteSetupScopes(["editing"])) || matches(siteSetupScopes(["editing", "analytics"]));
1514
1550
  }
1515
- var siteSetupActivityInputSchema = z15.object({
1516
- phase: z15.enum([
1551
+ var siteSetupActivityInputSchema = z16.object({
1552
+ phase: z16.enum([
1517
1553
  "inspecting",
1518
1554
  "integrating",
1519
1555
  "deploying",
1520
1556
  "verifying",
1521
1557
  "repairing"
1522
1558
  ]),
1523
- textId: z15.enum([
1559
+ textId: z16.enum([
1524
1560
  "inspecting",
1525
1561
  "integrating",
1526
1562
  "deploying",
@@ -1529,8 +1565,8 @@ var siteSetupActivityInputSchema = z15.object({
1529
1565
  ])
1530
1566
  }).strict().refine((value) => value.phase === value.textId, "Activity text must describe its phase.");
1531
1567
  var nextActionFields = {
1532
- actor: z15.enum(["agent", "user", "siteplane"]),
1533
- boundary: z15.enum([
1568
+ actor: z16.enum(["agent", "user", "siteplane"]),
1569
+ boundary: z16.enum([
1534
1570
  "source",
1535
1571
  "environment",
1536
1572
  "deployment",
@@ -1538,33 +1574,33 @@ var nextActionFields = {
1538
1574
  "authorization",
1539
1575
  "review"
1540
1576
  ]),
1541
- precondition: z15.string().min(1).max(1e3),
1542
- instruction: z15.string().min(1).max(2e3),
1543
- expectedEvidence: z15.string().min(1).max(1e3)
1577
+ precondition: z16.string().min(1).max(1e3),
1578
+ instruction: z16.string().min(1).max(2e3),
1579
+ expectedEvidence: z16.string().min(1).max(1e3)
1544
1580
  };
1545
- var siteSetupNextActionSchema = z15.discriminatedUnion("kind", [
1546
- z15.object({
1581
+ var siteSetupNextActionSchema = z16.discriminatedUnion("kind", [
1582
+ z16.object({
1547
1583
  ...nextActionFields,
1548
- kind: z15.literal("run_command"),
1549
- command: z15.string().min(1).max(500)
1584
+ kind: z16.literal("run_command"),
1585
+ command: z16.string().min(1).max(500)
1550
1586
  }).strict(),
1551
- z15.object({ ...nextActionFields, kind: z15.literal("agent_edit") }).strict(),
1552
- z15.object({ ...nextActionFields, kind: z15.literal("needs_user_action") }).strict(),
1553
- z15.object({ ...nextActionFields, kind: z15.literal("wait") }).strict(),
1554
- z15.object({ ...nextActionFields, kind: z15.literal("done") }).strict()
1587
+ z16.object({ ...nextActionFields, kind: z16.literal("agent_edit") }).strict(),
1588
+ z16.object({ ...nextActionFields, kind: z16.literal("needs_user_action") }).strict(),
1589
+ z16.object({ ...nextActionFields, kind: z16.literal("wait") }).strict(),
1590
+ z16.object({ ...nextActionFields, kind: z16.literal("done") }).strict()
1555
1591
  ]);
1556
- var siteSetupTaskRunSchema = z15.object({
1557
- runId: z15.string().uuid(),
1592
+ var siteSetupTaskRunSchema = z16.object({
1593
+ runId: z16.string().uuid(),
1558
1594
  mode: siteSetupRunModeSchema,
1559
1595
  status: siteSetupRunStatusSchema,
1560
- fieldContractHash: z15.string().nullable(),
1561
- deploymentOrigin: z15.string().url().nullable(),
1562
- deploymentRevision: z15.string().nullable(),
1563
- publicRuntimeKeyId: z15.string().uuid().nullable(),
1564
- reviewVersion: z15.string().nullable()
1596
+ fieldContractHash: z16.string().nullable(),
1597
+ deploymentOrigin: z16.string().url().nullable(),
1598
+ deploymentRevision: z16.string().nullable(),
1599
+ publicRuntimeKeyId: z16.string().uuid().nullable(),
1600
+ reviewVersion: z16.number().int().positive()
1565
1601
  }).strict();
1566
- var siteSetupTaskProgressSchema = z15.object({
1567
- progressStage: z15.enum([
1602
+ var siteSetupTaskProgressSchema = z16.object({
1603
+ progressStage: z16.enum([
1568
1604
  "waiting_for_connection",
1569
1605
  "agent_connected",
1570
1606
  "project_context_loaded",
@@ -1574,73 +1610,70 @@ var siteSetupTaskProgressSchema = z15.object({
1574
1610
  "action_required",
1575
1611
  "completed"
1576
1612
  ]),
1577
- lastVerifiedAt: z15.string().datetime().nullable(),
1578
- lastActivityAt: z15.string().datetime(),
1579
- activitySource: z15.enum(["user", "server", "agent"]),
1613
+ lastVerifiedAt: z16.string().datetime().nullable(),
1614
+ lastActivityAt: z16.string().datetime(),
1615
+ activitySource: z16.enum(["user", "server", "agent"]),
1580
1616
  activityPhase: siteSetupActivityInputSchema.shape.phase.nullable(),
1581
1617
  activityTextId: siteSetupActivityInputSchema.shape.textId.nullable()
1582
1618
  }).strict();
1583
- var siteSetupTaskSchema = z15.object({
1584
- contractVersion: z15.literal("siteplane.setup-task.v2"),
1585
- workflow: z15.enum(["initial_setup", "structure_update"]),
1586
- goal: z15.string().min(1),
1619
+ var siteSetupTaskSchema = z16.object({
1620
+ contractVersion: z16.literal("siteplane.setup-task.v2"),
1621
+ workflow: z16.enum(["initial_setup", "structure_update"]),
1622
+ goal: z16.string().min(1),
1587
1623
  modules: siteSetupModulesSchema,
1588
- authorizationVersion: z15.number().int().positive(),
1589
- authorizedScopes: z15.array(z15.string()).min(2),
1590
- site: z15.object({
1591
- siteId: z15.string().uuid(),
1592
- portalPath: z15.string(),
1593
- adminOrigin: z15.string().url()
1624
+ authorizationVersion: z16.number().int().positive(),
1625
+ authorizedScopes: z16.array(z16.string()).min(2),
1626
+ site: z16.object({
1627
+ siteId: z16.string().uuid(),
1628
+ portalPath: z16.string(),
1629
+ adminOrigin: z16.string().url()
1594
1630
  }).strict().nullable(),
1595
1631
  run: siteSetupTaskRunSchema.nullable(),
1596
1632
  progress: siteSetupTaskProgressSchema.nullable(),
1597
1633
  deployment: setupDeploymentRecordSchema.nullable(),
1598
- revalidationGeneration: z15.number().int().positive(),
1599
- assignment: z15.literal("owned"),
1600
- deadline: z15.string().datetime().nullable(),
1601
- userInstructions: z15.object({
1634
+ revalidationGeneration: z16.number().int().positive(),
1635
+ assignment: z16.literal("owned"),
1636
+ deadline: z16.string().datetime().nullable(),
1637
+ userInstructions: z16.object({
1602
1638
  text: siteSetupOwnerEditabilityNoteSchema,
1603
- source: z15.literal("user"),
1604
- trust: z15.literal("untrusted")
1639
+ source: z16.literal("user"),
1640
+ trust: z16.literal("untrusted")
1605
1641
  }).strict(),
1606
1642
  corrections: setupCorrectionItemsSchema,
1607
- contentSelectionSummary: z15.object({
1643
+ contentSelectionSummary: z16.object({
1608
1644
  text: siteSetupOwnerEditabilityNoteSchema,
1609
- source: z15.literal("agent"),
1610
- trust: z15.literal("untrusted")
1645
+ source: z16.literal("agent"),
1646
+ trust: z16.literal("untrusted")
1611
1647
  }).strict().nullable(),
1612
- environmentBindings: z15.array(z15.object({
1613
- name: z15.string().regex(/^[A-Z][A-Z0-9_]+$/u),
1614
- source: z15.string().min(1),
1615
- sensitivity: z15.enum(["public", "secret"]),
1616
- usage: z15.enum(["build", "server", "build_and_server"]),
1617
- evidence: z15.string().min(1)
1648
+ environmentBindings: z16.array(z16.object({
1649
+ name: z16.string().regex(/^[A-Z][A-Z0-9_]+$/u),
1650
+ source: z16.string().min(1),
1651
+ sensitivity: z16.enum(["public", "secret"]),
1652
+ usage: z16.enum(["build", "server", "build_and_server"]),
1653
+ evidence: z16.string().min(1)
1618
1654
  }).strict()),
1619
1655
  nextAction: siteSetupNextActionSchema,
1620
- error: z15.object({
1621
- code: z15.string().regex(/^[a-z0-9_.]+$/u).max(160),
1656
+ error: z16.object({
1657
+ code: z16.string().regex(/^[a-z0-9_.]+$/u).max(160),
1622
1658
  boundary: nextActionFields.boundary,
1623
1659
  responsibleActor: nextActionFields.actor,
1624
- retryable: z15.boolean(),
1625
- retryAfter: z15.number().int().nonnegative().nullable(),
1626
- requestId: z15.string().regex(/^[A-Za-z0-9_-]+$/u).max(128)
1660
+ retryable: z16.boolean(),
1661
+ retryAfter: z16.number().int().nonnegative().nullable(),
1662
+ requestId: z16.string().regex(/^[A-Za-z0-9_-]+$/u).max(128)
1627
1663
  }).strict().nullable(),
1628
- packages: z15.object({
1629
- siteplane: z15.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u),
1630
- runtimeNext: z15.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
1664
+ packages: siteSetupPackagesSchema,
1665
+ communication: z16.object({
1666
+ beforeSourceChanges: z16.string().min(1),
1667
+ updates: z16.array(z16.string().min(1)).min(1),
1668
+ blocker: z16.string().min(1)
1631
1669
  }).strict(),
1632
- communication: z15.object({
1633
- beforeSourceChanges: z15.string().min(1),
1634
- updates: z15.array(z15.string().min(1)).min(1),
1635
- blocker: z15.string().min(1)
1670
+ discovery: z16.object({
1671
+ inspectPublicRoutes: z16.boolean(),
1672
+ contentKinds: z16.array(z16.enum(["text", "longText", "link", "image"])).min(1),
1673
+ rules: z16.array(z16.string().min(1)).min(1)
1636
1674
  }).strict(),
1637
- discovery: z15.object({
1638
- inspectPublicRoutes: z15.boolean(),
1639
- contentKinds: z15.array(z15.enum(["text", "longText", "link", "image"])).min(1),
1640
- rules: z15.array(z15.string().min(1)).min(1)
1641
- }).strict(),
1642
- steps: z15.array(z15.object({
1643
- id: z15.enum([
1675
+ steps: z16.array(z16.object({
1676
+ id: z16.enum([
1644
1677
  "inspect_repository",
1645
1678
  "install_packages",
1646
1679
  "instrument_fields",
@@ -1648,32 +1681,52 @@ var siteSetupTaskSchema = z15.object({
1648
1681
  "deploy_production",
1649
1682
  "verify_deployment"
1650
1683
  ]),
1651
- instruction: z15.string().min(1)
1684
+ instruction: z16.string().min(1)
1652
1685
  }).strict()).length(6),
1653
- completion: z15.object({
1654
- verifiedStatus: z15.literal("ready_for_review"),
1655
- instruction: z15.string().min(1)
1686
+ completion: z16.object({
1687
+ verifiedStatus: z16.literal("ready_for_review"),
1688
+ instruction: z16.string().min(1)
1656
1689
  }).strict()
1657
- }).strict().refine((task) => hasExactSiteSetupScopes(task.authorizedScopes, task.modules), "Task scopes must exactly match its modules.");
1658
- var canonicalHashSchema = z15.string().regex(/^sha256:[0-9a-f]{64}$/iu);
1690
+ }).strict().refine((task) => hasExactSiteSetupScopes(task.authorizedScopes, task.modules), "Task scopes must exactly match its modules.").refine((task) => task.modules.includes("analytics") === (task.packages.analytics !== void 0), "The Analytics package pin must be present exactly when Analytics is selected.");
1691
+ var canonicalHashSchema = z16.string().regex(/^sha256:[0-9a-f]{64}$/iu);
1659
1692
  var deploymentRevisionSchema = normalizedSafeTextSchema(256, "deploymentRevision");
1660
- var continueSiteSetupInputSchema = z15.object({
1661
- siteId: z15.string().uuid(),
1662
- runId: z15.string().uuid(),
1693
+ var continueSiteSetupInputSchema = z16.object({
1694
+ siteId: z16.string().uuid(),
1695
+ runId: z16.string().uuid(),
1696
+ expectedReviewVersion: z16.number().int().positive(),
1697
+ mutationId: z16.string().uuid(),
1698
+ intent: z16.enum(["continue_review", "correct_completed_review"]),
1663
1699
  expectedFieldContractHash: canonicalHashSchema,
1664
1700
  expectedDeploymentRevision: deploymentRevisionSchema,
1665
1701
  correctionItems: setupCorrectionItemsSchema,
1666
1702
  ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema.optional()
1667
1703
  }).strict();
1668
- var saveSiteSetupOwnerNoteInputSchema = z15.object({
1669
- siteId: z15.string().uuid(),
1670
- runId: z15.string().uuid(),
1704
+ var saveSiteSetupOwnerNoteInputSchema = z16.object({
1705
+ siteId: z16.string().uuid(),
1706
+ runId: z16.string().uuid(),
1707
+ expectedReviewVersion: z16.number().int().positive(),
1671
1708
  expectedFieldContractHash: canonicalHashSchema,
1672
1709
  expectedDeploymentRevision: deploymentRevisionSchema,
1673
1710
  ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema
1674
1711
  }).strict();
1675
- var siteSetupContextInputSchema = z15.object({}).strict();
1676
- var siteSetupApplyInputSchema = z15.object({
1712
+ var setupReviewPreferenceSelectionSchema = z16.object({
1713
+ analyticsMode: z16.enum(["disabled", "session_only"]).nullable(),
1714
+ assetTargetType: z16.enum(["repo_static_assets", "siteplane_managed_fallback"]).nullable(),
1715
+ assetTargetId: z16.string().uuid().nullable()
1716
+ }).strict().refine((value) => value.assetTargetType !== null || value.assetTargetId === null, {
1717
+ message: "An asset target requires its delivery type."
1718
+ });
1719
+ var setupReviewPreferencesSchema = setupReviewPreferenceSelectionSchema.safeExtend({
1720
+ managedHostingApproved: z16.boolean()
1721
+ });
1722
+ var saveSetupReviewPreferencesInputSchema = z16.object({
1723
+ siteId: z16.string().uuid(),
1724
+ runId: z16.string().uuid(),
1725
+ expectedReviewVersion: z16.number().int().positive(),
1726
+ preferences: setupReviewPreferenceSelectionSchema
1727
+ }).strict();
1728
+ var siteSetupContextInputSchema = z16.object({}).strict();
1729
+ var siteSetupApplyInputSchema = z16.object({
1677
1730
  fieldContract: siteFieldContractV1Schema,
1678
1731
  editorDefinition: editorDefinitionV1Schema,
1679
1732
  contentSelectionSummary: siteSetupOwnerEditabilityNoteSchema.refine((text) => text.trim().length > 0, "Describe the selected content, important exclusions and any open gaps.")
@@ -1740,37 +1793,44 @@ var siteSetupApplyInputSchema = z15.object({
1740
1793
  }
1741
1794
  }
1742
1795
  });
1743
- var siteSetupVerifyInputSchema = z15.object({
1744
- deploymentUrl: z15.string().url().refine((value) => value.startsWith("https://")),
1796
+ var siteSetupVerifyInputSchema = z16.object({
1797
+ deploymentUrl: z16.string().url().refine((value) => value.startsWith("https://")),
1745
1798
  deploymentRevision: deploymentRevisionSchema,
1746
- wait: z15.boolean().optional()
1799
+ wait: z16.boolean().optional()
1747
1800
  }).strict();
1748
- var siteSetupEvidenceInputSchema = z15.object({
1749
- siteId: z15.string().uuid(),
1750
- runId: z15.string().uuid(),
1801
+ var siteSetupEvidenceInputSchema = z16.object({
1802
+ siteId: z16.string().uuid(),
1803
+ runId: z16.string().uuid(),
1751
1804
  expectedFieldContractHash: canonicalHashSchema,
1752
- expectedDeploymentOrigin: z15.string().url().refine((value) => value.startsWith("https://")),
1805
+ expectedDeploymentOrigin: z16.string().url().refine((value) => value.startsWith("https://")),
1753
1806
  expectedDeploymentRevision: deploymentRevisionSchema,
1754
- publicRuntimeKeyId: z15.string().uuid(),
1807
+ publicRuntimeKeyId: z16.string().uuid(),
1755
1808
  bridgeSessionId: normalizedSafeTextSchema(256, "bridgeSessionId"),
1756
- observations: z15.array(z15.object({
1809
+ observations: z16.array(z16.object({
1757
1810
  fieldId: fieldIdSchema,
1758
1811
  routeKey: siteFieldRouteKeySchema,
1759
1812
  renderedPath: renderedPathSchema,
1760
- targetResolved: z15.boolean(),
1761
- previewAck: z15.boolean()
1813
+ targetResolved: z16.boolean(),
1814
+ previewAck: z16.boolean()
1762
1815
  }).strict().refine((value) => !value.previewAck || value.targetResolved, "Preview ACK requires a resolved target.")).min(1).max(200)
1763
1816
  }).strict();
1764
- var completeSiteSetupInputSchema = z15.object({
1765
- siteId: z15.string().uuid(),
1766
- runId: z15.string().uuid(),
1817
+ var completeSetupReviewInputSchema = z16.object({
1818
+ siteId: z16.string().uuid(),
1819
+ runId: z16.string().uuid(),
1820
+ expectedReviewVersion: z16.number().int().positive(),
1767
1821
  expectedFieldContractHash: canonicalHashSchema,
1768
1822
  expectedDeploymentRevision: deploymentRevisionSchema,
1769
1823
  expectedReadyFingerprint: canonicalHashSchema
1770
1824
  }).strict();
1771
- var refreshSiteSetupDeploymentInputSchema = z15.object({
1772
- siteId: z15.string().uuid(),
1773
- deploymentUrl: z15.string().url().refine((value) => value.startsWith("https://")),
1825
+ var activateSiteSetupInputSchema = z16.object({
1826
+ siteId: z16.string().uuid(),
1827
+ runId: z16.string().uuid(),
1828
+ expectedReviewVersion: z16.number().int().positive(),
1829
+ expectedSnapshotHash: canonicalHashSchema
1830
+ }).strict();
1831
+ var refreshSiteSetupDeploymentInputSchema = z16.object({
1832
+ siteId: z16.string().uuid(),
1833
+ deploymentUrl: z16.string().url().refine((value) => value.startsWith("https://")),
1774
1834
  deploymentRevision: deploymentRevisionSchema
1775
1835
  }).strict();
1776
1836
  function addSafeByteIssues(value, maxBytes, label, context) {
@@ -1790,37 +1850,61 @@ function addSafeByteIssues(value, maxBytes, label, context) {
1790
1850
  function utf8Bytes(value) {
1791
1851
  return new TextEncoder().encode(value).byteLength;
1792
1852
  }
1853
+ var setupActivationApprovalSchema = z16.object({
1854
+ reviewVersion: z16.number().int().positive(),
1855
+ snapshotHash: canonicalHashSchema,
1856
+ analytics: z16.object({
1857
+ status: z16.enum(["active", "skipped"]),
1858
+ reviewVersion: z16.number().int().positive(),
1859
+ generation: z16.number().int().nonnegative()
1860
+ }).optional()
1861
+ });
1862
+ var activateSetupModulesInputSchema = activateSiteSetupInputSchema.extend({
1863
+ analytics: z16.discriminatedUnion("decision", [
1864
+ z16.object({ decision: z16.literal("pending") }).strict(),
1865
+ z16.object({
1866
+ decision: z16.literal("enable"),
1867
+ expectedInstallationGeneration: z16.number().int().positive(),
1868
+ measurementApproved: z16.literal(true)
1869
+ }).strict(),
1870
+ z16.object({
1871
+ decision: z16.literal("skip"),
1872
+ expectedInstallationGeneration: z16.number().int().nonnegative(),
1873
+ continueWithoutAnalytics: z16.literal(true)
1874
+ }).strict()
1875
+ ])
1876
+ }).strict();
1793
1877
 
1794
1878
  // ../shared/dist/bridge-protocol.js
1795
1879
  var BRIDGE_PROTOCOL_VERSION = 2;
1796
- var bridgeRectSchema = z16.object({
1797
- x: z16.number(),
1798
- y: z16.number(),
1799
- width: z16.number().nonnegative(),
1800
- height: z16.number().nonnegative()
1880
+ var bridgeRectSchema = z17.object({
1881
+ x: z17.number(),
1882
+ y: z17.number(),
1883
+ width: z17.number().nonnegative(),
1884
+ height: z17.number().nonnegative()
1801
1885
  });
1802
- var previewTextValueSchema = z16.object({
1803
- fieldType: z16.enum(["text", "longText"]),
1804
- value: z16.string()
1886
+ var previewTextValueSchema = z17.object({
1887
+ fieldType: z17.enum(["text", "longText"]),
1888
+ value: z17.string()
1805
1889
  });
1806
- var previewLinkValueSchema = z16.object({
1807
- fieldType: z16.literal("link"),
1808
- value: z16.object({
1809
- href: z16.string().trim().min(1),
1810
- label: z16.string().trim().min(1).optional()
1890
+ var previewLinkValueSchema = z17.object({
1891
+ fieldType: z17.literal("link"),
1892
+ value: z17.object({
1893
+ href: z17.string().trim().min(1),
1894
+ label: z17.string().trim().min(1).optional()
1811
1895
  })
1812
1896
  });
1813
- var previewImageValueSchema = z16.object({
1814
- fieldType: z16.literal("image"),
1897
+ var previewImageValueSchema = z17.object({
1898
+ fieldType: z17.literal("image"),
1815
1899
  value: imageValueSchema
1816
1900
  });
1817
- var bridgePreviewValueSchema = z16.discriminatedUnion("fieldType", [
1901
+ var bridgePreviewValueSchema = z17.discriminatedUnion("fieldType", [
1818
1902
  previewTextValueSchema,
1819
1903
  previewLinkValueSchema,
1820
1904
  previewImageValueSchema
1821
1905
  ]);
1822
- var fieldSelectionModeSchema = z16.enum(["replace", "range", "toggle"]);
1823
- var fieldBridgeMissingContentActionSchema = z16.enum([
1906
+ var fieldSelectionModeSchema = z17.enum(["replace", "range", "toggle"]);
1907
+ var fieldBridgeMissingContentActionSchema = z17.enum([
1824
1908
  "add",
1825
1909
  "select",
1826
1910
  "remove"
@@ -1837,79 +1921,81 @@ var FIELD_BRIDGE_MESSAGE_TYPES = [
1837
1921
  "siteplane:field-bridge:set-visual-control-state",
1838
1922
  "siteplane:field-bridge:missing-content",
1839
1923
  "siteplane:field-bridge:preview-scrolled",
1924
+ "siteplane:field-bridge:analytics-probe",
1925
+ "siteplane:field-bridge:analytics-probe-result",
1840
1926
  "siteplane:field-bridge:error"
1841
1927
  ];
1842
- var canonicalFieldContractHashSchema = z16.string().regex(/^sha256:[0-9a-f]{64}$/u);
1843
- var bridgeSectionSchema = z16.string().trim().min(1).max(256);
1844
- var realRenderedPathSchema = z16.string().trim().refine((value) => value.startsWith("/") && value !== "$global" && !value.includes("?") && !value.includes("#"), "A field bridge rendered path must be a real canonical path.");
1845
- var fieldBridgeIdentitySchema = z16.object({
1846
- publicRuntimeKeyId: z16.string().uuid(),
1928
+ var canonicalFieldContractHashSchema = z17.string().regex(/^sha256:[0-9a-f]{64}$/u);
1929
+ var bridgeSectionSchema = z17.string().trim().min(1).max(256);
1930
+ var realRenderedPathSchema = z17.string().trim().refine((value) => value.startsWith("/") && value !== "$global" && !value.includes("?") && !value.includes("#"), "A field bridge rendered path must be a real canonical path.");
1931
+ var fieldBridgeIdentitySchema = z17.object({
1932
+ publicRuntimeKeyId: z17.string().uuid(),
1847
1933
  fieldContractHash: canonicalFieldContractHashSchema,
1848
- deploymentRevision: z16.string().trim().min(1).max(256)
1934
+ deploymentRevision: z17.string().trim().min(1).max(256)
1849
1935
  }).strict();
1850
- var fieldBridgeBaseSchema = z16.object({
1851
- version: z16.literal(BRIDGE_PROTOCOL_VERSION),
1852
- type: z16.enum(FIELD_BRIDGE_MESSAGE_TYPES),
1853
- siteId: z16.string().uuid(),
1854
- sessionId: z16.string().trim().min(1),
1855
- publicRuntimeKeyId: z16.string().uuid(),
1936
+ var fieldBridgeBaseSchema = z17.object({
1937
+ version: z17.literal(BRIDGE_PROTOCOL_VERSION),
1938
+ type: z17.enum(FIELD_BRIDGE_MESSAGE_TYPES),
1939
+ siteId: z17.string().uuid(),
1940
+ sessionId: z17.string().trim().min(1),
1941
+ publicRuntimeKeyId: z17.string().uuid(),
1856
1942
  fieldContractHash: canonicalFieldContractHashSchema,
1857
- deploymentRevision: z16.string().trim().min(1).max(256),
1858
- requestId: z16.string().trim().min(1),
1859
- sentAt: z16.string().datetime()
1943
+ deploymentRevision: z17.string().trim().min(1).max(256),
1944
+ requestId: z17.string().trim().min(1),
1945
+ sentAt: z17.string().datetime()
1860
1946
  }).strict();
1861
- var fieldBridgeFieldSchema = z16.object({
1947
+ var fieldBridgeFieldSchema = z17.object({
1862
1948
  fieldId: fieldIdSchema,
1863
1949
  fieldType: fieldTypeSchema,
1864
1950
  routeKey: siteFieldRouteKeySchema,
1865
1951
  renderedPath: realRenderedPathSchema,
1866
- sourcePath: z16.string().trim().min(1).optional(),
1952
+ sourcePath: z17.string().trim().min(1).optional(),
1867
1953
  editTarget: fieldIdSchema,
1868
1954
  rect: bridgeRectSchema,
1869
- targetResolved: z16.literal(true),
1955
+ targetResolved: z17.literal(true),
1870
1956
  currentValue: bridgePreviewValueSchema.optional()
1871
1957
  }).strict();
1872
1958
  var fieldBridgeInitMessageSchema = fieldBridgeBaseSchema.extend({
1873
- type: z16.literal("siteplane:field-bridge:init"),
1874
- payload: z16.object({
1875
- adminOrigin: z16.string().url(),
1876
- customerOrigin: z16.string().url(),
1959
+ type: z17.literal("siteplane:field-bridge:init"),
1960
+ payload: z17.object({
1961
+ adminOrigin: z17.string().url(),
1962
+ customerOrigin: z17.string().url(),
1877
1963
  renderedPath: realRenderedPathSchema
1878
1964
  }).strict()
1879
1965
  });
1880
1966
  var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
1881
- type: z16.literal("siteplane:field-bridge:ready"),
1882
- payload: z16.object({
1967
+ type: z17.literal("siteplane:field-bridge:ready"),
1968
+ payload: z17.object({
1883
1969
  renderedPath: realRenderedPathSchema,
1884
- fieldCount: z16.number().int().nonnegative(),
1885
- capabilities: z16.tuple([
1886
- z16.literal("field_selection"),
1887
- z16.literal("preview_values"),
1888
- z16.literal("field_evidence"),
1889
- z16.literal("visual_field_control")
1890
- ])
1970
+ fieldCount: z17.number().int().nonnegative(),
1971
+ capabilities: z17.tuple([
1972
+ z17.literal("field_selection"),
1973
+ z17.literal("preview_values"),
1974
+ z17.literal("field_evidence"),
1975
+ z17.literal("visual_field_control")
1976
+ ]).rest(z17.literal("analytics_preview_readiness")).refine((capabilities) => capabilities.length <= 5)
1891
1977
  }).strict()
1892
1978
  });
1893
1979
  var fieldBridgeFieldsMessageSchema = fieldBridgeBaseSchema.extend({
1894
- type: z16.literal("siteplane:field-bridge:fields"),
1895
- payload: z16.object({
1980
+ type: z17.literal("siteplane:field-bridge:fields"),
1981
+ payload: z17.object({
1896
1982
  renderedPath: realRenderedPathSchema,
1897
- fields: z16.array(fieldBridgeFieldSchema)
1983
+ fields: z17.array(fieldBridgeFieldSchema)
1898
1984
  }).strict()
1899
1985
  });
1900
1986
  var fieldBridgeSelectFieldMessageSchema = fieldBridgeBaseSchema.extend({
1901
- type: z16.literal("siteplane:field-bridge:select-field"),
1902
- payload: z16.object({
1987
+ type: z17.literal("siteplane:field-bridge:select-field"),
1988
+ payload: z17.object({
1903
1989
  fieldId: fieldIdSchema,
1904
1990
  selectionMode: fieldSelectionModeSchema
1905
1991
  }).strict()
1906
1992
  });
1907
1993
  var fieldBridgeSetSelectedFieldMessageSchema = fieldBridgeBaseSchema.extend({
1908
- type: z16.literal("siteplane:field-bridge:set-selected-field"),
1909
- payload: z16.object({
1910
- fieldIds: z16.array(fieldIdSchema).max(200),
1994
+ type: z17.literal("siteplane:field-bridge:set-selected-field"),
1995
+ payload: z17.object({
1996
+ fieldIds: z17.array(fieldIdSchema).max(200),
1911
1997
  primaryFieldId: fieldIdSchema.nullable(),
1912
- scrollIntoView: z16.boolean().optional()
1998
+ scrollIntoView: z17.boolean().optional()
1913
1999
  }).strict().superRefine((value, context) => {
1914
2000
  if (value.fieldIds.length > 0 && value.primaryFieldId === null) {
1915
2001
  context.addIssue({
@@ -1928,58 +2014,76 @@ var fieldBridgeSetSelectedFieldMessageSchema = fieldBridgeBaseSchema.extend({
1928
2014
  })
1929
2015
  });
1930
2016
  var fieldBridgeApplyPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
1931
- type: z16.literal("siteplane:field-bridge:apply-preview-values"),
1932
- payload: z16.object({ values: z16.record(fieldIdSchema, bridgePreviewValueSchema) }).strict()
2017
+ type: z17.literal("siteplane:field-bridge:apply-preview-values"),
2018
+ payload: z17.object({ values: z17.record(fieldIdSchema, bridgePreviewValueSchema) }).strict()
1933
2019
  });
1934
2020
  var fieldBridgeTestPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
1935
- type: z16.literal("siteplane:field-bridge:test-preview-values"),
1936
- payload: z16.object({ fieldIds: z16.array(fieldIdSchema).min(1).max(200) }).strict()
2021
+ type: z17.literal("siteplane:field-bridge:test-preview-values"),
2022
+ payload: z17.object({ fieldIds: z17.array(fieldIdSchema).min(1).max(200) }).strict()
1937
2023
  });
1938
2024
  var fieldBridgePreviewAckMessageSchema = fieldBridgeBaseSchema.extend({
1939
- type: z16.literal("siteplane:field-bridge:preview-ack"),
1940
- payload: z16.object({
1941
- ackRequestId: z16.string().trim().min(1),
1942
- kind: z16.enum(["apply", "test"]),
2025
+ type: z17.literal("siteplane:field-bridge:preview-ack"),
2026
+ payload: z17.object({
2027
+ ackRequestId: z17.string().trim().min(1),
2028
+ kind: z17.enum(["apply", "test"]),
1943
2029
  renderedPath: realRenderedPathSchema,
1944
- fieldIds: z16.array(fieldIdSchema).max(200)
2030
+ fieldIds: z17.array(fieldIdSchema).max(200)
1945
2031
  }).strict()
1946
2032
  });
1947
2033
  var fieldBridgeSetVisualControlStateMessageSchema = fieldBridgeBaseSchema.extend({
1948
- type: z16.literal("siteplane:field-bridge:set-visual-control-state"),
1949
- payload: z16.object({
1950
- enabled: z16.boolean(),
1951
- fieldProximityEnabled: z16.boolean(),
1952
- pendingKeys: z16.array(z16.string().trim().min(1).max(2048)).max(50),
1953
- activeFieldIds: z16.array(fieldIdSchema),
1954
- fieldSections: z16.record(fieldIdSchema, bridgeSectionSchema),
1955
- selectedPending: z16.array(z16.object({
1956
- key: z16.string().trim().min(1).max(2048),
1957
- locatorHint: z16.string().trim().min(1).max(2048)
2034
+ type: z17.literal("siteplane:field-bridge:set-visual-control-state"),
2035
+ payload: z17.object({
2036
+ enabled: z17.boolean(),
2037
+ fieldProximityEnabled: z17.boolean(),
2038
+ pendingKeys: z17.array(z17.string().trim().min(1).max(2048)).max(50),
2039
+ activeFieldIds: z17.array(fieldIdSchema),
2040
+ fieldSections: z17.record(fieldIdSchema, bridgeSectionSchema),
2041
+ selectedPending: z17.array(z17.object({
2042
+ key: z17.string().trim().min(1).max(2048),
2043
+ locatorHint: z17.string().trim().min(1).max(2048)
1958
2044
  }).strict()).max(50),
1959
- scrollPendingIntoView: z16.boolean().optional()
2045
+ scrollPendingIntoView: z17.boolean().optional()
1960
2046
  }).strict()
1961
2047
  });
1962
2048
  var fieldBridgeMissingContentMessageSchema = fieldBridgeBaseSchema.extend({
1963
- type: z16.literal("siteplane:field-bridge:missing-content"),
1964
- payload: z16.object({
2049
+ type: z17.literal("siteplane:field-bridge:missing-content"),
2050
+ payload: z17.object({
1965
2051
  action: fieldBridgeMissingContentActionSchema,
1966
2052
  item: setupCorrectionItemSchema,
1967
2053
  suggestedSection: bridgeSectionSchema.optional()
1968
2054
  }).strict()
1969
2055
  });
1970
2056
  var fieldBridgePreviewScrolledMessageSchema = fieldBridgeBaseSchema.extend({
1971
- type: z16.literal("siteplane:field-bridge:preview-scrolled"),
1972
- payload: z16.object({ renderedPath: realRenderedPathSchema }).strict()
2057
+ type: z17.literal("siteplane:field-bridge:preview-scrolled"),
2058
+ payload: z17.object({ renderedPath: realRenderedPathSchema }).strict()
2059
+ });
2060
+ var analyticsPreviewChallengeSchema = z17.object({
2061
+ bridgeSessionId: z17.string().uuid(),
2062
+ challenge: z17.string().min(32).max(512),
2063
+ testRunId: z17.string().trim().min(1).max(160),
2064
+ expiresAt: z17.string().datetime()
2065
+ }).strict();
2066
+ var fieldBridgeAnalyticsProbeSchema = fieldBridgeBaseSchema.extend({
2067
+ type: z17.literal("siteplane:field-bridge:analytics-probe"),
2068
+ requestId: z17.string().min(1).max(256),
2069
+ payload: analyticsPreviewChallengeSchema
2070
+ });
2071
+ var fieldBridgeAnalyticsProbeResultSchema = fieldBridgeBaseSchema.extend({
2072
+ type: z17.literal("siteplane:field-bridge:analytics-probe-result"),
2073
+ payload: z17.object({
2074
+ ackRequestId: z17.string().min(1).max(256),
2075
+ status: z17.enum(["recorded", "failed"])
2076
+ }).strict()
1973
2077
  });
1974
2078
  var fieldBridgeErrorMessageSchema = fieldBridgeBaseSchema.extend({
1975
- type: z16.literal("siteplane:field-bridge:error"),
1976
- payload: z16.object({
1977
- code: z16.string().trim().min(1),
1978
- message: z16.string().trim().min(1),
1979
- recoverable: z16.boolean().default(false)
2079
+ type: z17.literal("siteplane:field-bridge:error"),
2080
+ payload: z17.object({
2081
+ code: z17.string().trim().min(1),
2082
+ message: z17.string().trim().min(1),
2083
+ recoverable: z17.boolean().default(false)
1980
2084
  }).strict()
1981
2085
  });
1982
- var fieldBridgeMessageSchema = z16.discriminatedUnion("type", [
2086
+ var fieldBridgeMessageSchema = z17.discriminatedUnion("type", [
1983
2087
  fieldBridgeInitMessageSchema,
1984
2088
  fieldBridgeReadyMessageSchema,
1985
2089
  fieldBridgeFieldsMessageSchema,
@@ -1991,55 +2095,57 @@ var fieldBridgeMessageSchema = z16.discriminatedUnion("type", [
1991
2095
  fieldBridgeSetVisualControlStateMessageSchema,
1992
2096
  fieldBridgeMissingContentMessageSchema,
1993
2097
  fieldBridgePreviewScrolledMessageSchema,
1994
- fieldBridgeErrorMessageSchema
2098
+ fieldBridgeErrorMessageSchema,
2099
+ fieldBridgeAnalyticsProbeSchema,
2100
+ fieldBridgeAnalyticsProbeResultSchema
1995
2101
  ]);
1996
2102
 
1997
2103
  // ../shared/dist/commands.js
1998
- import { z as z18 } from "zod";
2104
+ import { z as z19 } from "zod";
1999
2105
 
2000
2106
  // ../shared/dist/errors.js
2001
- import { z as z17 } from "zod";
2107
+ import { z as z18 } from "zod";
2002
2108
  var UI_ERROR_CATEGORIES = [
2003
2109
  "site_member",
2004
2110
  "workspace_member",
2005
2111
  "internal"
2006
2112
  ];
2007
- var uiErrorCategorySchema = z17.enum(UI_ERROR_CATEGORIES);
2008
- var commandErrorPayloadSchema = z17.object({
2009
- code: z17.string().min(1),
2010
- message: z17.string().min(1),
2113
+ var uiErrorCategorySchema = z18.enum(UI_ERROR_CATEGORIES);
2114
+ var commandErrorPayloadSchema = z18.object({
2115
+ code: z18.string().min(1),
2116
+ message: z18.string().min(1),
2011
2117
  category: uiErrorCategorySchema,
2012
- details: z17.record(z17.string(), z17.unknown()).optional()
2118
+ details: z18.record(z18.string(), z18.unknown()).optional()
2013
2119
  });
2014
2120
 
2015
2121
  // ../shared/dist/commands.js
2016
- var commandSuccessSchema = z18.object({
2017
- ok: z18.literal(true),
2018
- data: z18.unknown()
2122
+ var commandSuccessSchema = z19.object({
2123
+ ok: z19.literal(true),
2124
+ data: z19.unknown()
2019
2125
  });
2020
- var commandErrorSchema = z18.object({
2021
- ok: z18.literal(false),
2126
+ var commandErrorSchema = z19.object({
2127
+ ok: z19.literal(false),
2022
2128
  error: commandErrorPayloadSchema
2023
2129
  });
2024
- var commandResultSchema = z18.discriminatedUnion("ok", [
2130
+ var commandResultSchema = z19.discriminatedUnion("ok", [
2025
2131
  commandSuccessSchema,
2026
2132
  commandErrorSchema
2027
2133
  ]);
2028
2134
 
2029
2135
  // ../shared/dist/editor-settings.js
2030
- import { z as z19 } from "zod";
2031
- var editorColorSchemeSchema = z19.enum([
2136
+ import { z as z20 } from "zod";
2137
+ var editorColorSchemeSchema = z20.enum([
2032
2138
  "paper",
2033
2139
  "slate",
2034
2140
  "siteplane",
2035
2141
  "bloom"
2036
2142
  ]);
2037
2143
  var editorColorSchemes = editorColorSchemeSchema.options;
2038
- var editorColorModeSchema = z19.enum(["light", "dark"]);
2144
+ var editorColorModeSchema = z20.enum(["light", "dark"]);
2039
2145
  var editorColorModes = editorColorModeSchema.options;
2040
2146
 
2041
2147
  // ../shared/dist/site-slug.js
2042
- import { z as z20 } from "zod";
2148
+ import { z as z21 } from "zod";
2043
2149
  var SITE_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
2044
2150
  var RESERVED_SITE_SLUGS = /* @__PURE__ */ new Set([
2045
2151
  "account",
@@ -2056,31 +2162,31 @@ var RESERVED_SITE_SLUGS = /* @__PURE__ */ new Set([
2056
2162
  "support",
2057
2163
  "workspace"
2058
2164
  ]);
2059
- var siteSlugSchema = z20.string().regex(SITE_SLUG_PATTERN, "Invalid site slug").refine((value) => !RESERVED_SITE_SLUGS.has(value), "Reserved site slug");
2165
+ var siteSlugSchema = z21.string().regex(SITE_SLUG_PATTERN, "Invalid site slug").refine((value) => !RESERVED_SITE_SLUGS.has(value), "Reserved site slug");
2060
2166
 
2061
2167
  // ../shared/dist/entitlements.js
2062
- import { z as z21 } from "zod";
2063
- var entitlementSnapshotSchema = z21.object({
2064
- planKey: z21.string().trim().min(1),
2065
- sitesLimit: z21.number().int().positive(),
2066
- siteMembersPerSiteLimit: z21.number().int().positive(),
2067
- customAdminDomainsEnabled: z21.boolean(),
2068
- agentMcpEnabled: z21.boolean(),
2069
- emailNotificationsEnabled: z21.boolean(),
2070
- analyticsEnabled: z21.boolean(),
2071
- analyticsSitesLimit: z21.number().int().min(0),
2072
- analyticsPortalPerformanceEnabled: z21.boolean(),
2073
- analyticsMonthlyReportsEnabled: z21.boolean(),
2074
- analyticsAiSummaryEnabled: z21.boolean(),
2075
- analyticsRawEventRetentionDays: z21.number().int().min(1).max(ANALYTICS_RETENTION_DEFAULTS.maxRawEventRetentionDaysWithoutAdr),
2076
- analyticsMonthlyEventLimit: z21.number().int().min(0),
2077
- bookingEnabled: z21.boolean().default(false),
2078
- bookingSitesLimit: z21.number().int().min(0).default(0),
2079
- bookingPortalManagementEnabled: z21.boolean().default(false),
2080
- bookingResourcesPerSiteLimit: z21.number().int().min(0).default(0),
2081
- bookingServicesPerSiteLimit: z21.number().int().min(0).default(0),
2082
- bookingMonthlyBookingsLimit: z21.number().int().min(0).default(0),
2083
- bookingRemindersEnabled: z21.boolean().default(false)
2168
+ import { z as z22 } from "zod";
2169
+ var entitlementSnapshotSchema = z22.object({
2170
+ planKey: z22.string().trim().min(1),
2171
+ sitesLimit: z22.number().int().positive(),
2172
+ siteMembersPerSiteLimit: z22.number().int().positive(),
2173
+ customAdminDomainsEnabled: z22.boolean(),
2174
+ agentMcpEnabled: z22.boolean(),
2175
+ emailNotificationsEnabled: z22.boolean(),
2176
+ analyticsEnabled: z22.boolean(),
2177
+ analyticsSitesLimit: z22.number().int().min(0),
2178
+ analyticsPortalPerformanceEnabled: z22.boolean(),
2179
+ analyticsMonthlyReportsEnabled: z22.boolean(),
2180
+ analyticsAiSummaryEnabled: z22.boolean(),
2181
+ analyticsRawEventRetentionDays: z22.number().int().min(1).max(ANALYTICS_RETENTION_DEFAULTS.maxRawEventRetentionDaysWithoutAdr),
2182
+ analyticsMonthlyEventLimit: z22.number().int().min(0),
2183
+ bookingEnabled: z22.boolean().default(false),
2184
+ bookingSitesLimit: z22.number().int().min(0).default(0),
2185
+ bookingPortalManagementEnabled: z22.boolean().default(false),
2186
+ bookingResourcesPerSiteLimit: z22.number().int().min(0).default(0),
2187
+ bookingServicesPerSiteLimit: z22.number().int().min(0).default(0),
2188
+ bookingMonthlyBookingsLimit: z22.number().int().min(0).default(0),
2189
+ bookingRemindersEnabled: z22.boolean().default(false)
2084
2190
  });
2085
2191
  var EARLY_ACCESS_PLAN = {
2086
2192
  planKey: "early_access_2026",
@@ -2089,8 +2195,8 @@ var EARLY_ACCESS_PLAN = {
2089
2195
  customAdminDomainsEnabled: true,
2090
2196
  agentMcpEnabled: true,
2091
2197
  emailNotificationsEnabled: true,
2092
- analyticsEnabled: false,
2093
- analyticsSitesLimit: 0,
2198
+ analyticsEnabled: true,
2199
+ analyticsSitesLimit: 3,
2094
2200
  analyticsPortalPerformanceEnabled: false,
2095
2201
  analyticsMonthlyReportsEnabled: false,
2096
2202
  analyticsAiSummaryEnabled: false,
@@ -2106,7 +2212,7 @@ var EARLY_ACCESS_PLAN = {
2106
2212
  };
2107
2213
 
2108
2214
  // ../shared/dist/readiness.js
2109
- import { z as z22 } from "zod";
2215
+ import { z as z23 } from "zod";
2110
2216
  var READINESS_CHECK_KEYS = [
2111
2217
  "agent_instructions_installed",
2112
2218
  "runtime_package_connected",
@@ -2121,19 +2227,80 @@ var READINESS_STATUSES = [
2121
2227
  "failing",
2122
2228
  "warning"
2123
2229
  ];
2124
- var readinessCheckKeySchema = z22.enum(READINESS_CHECK_KEYS);
2125
- var readinessStatusSchema = z22.enum(READINESS_STATUSES);
2230
+ var readinessCheckKeySchema = z23.enum(READINESS_CHECK_KEYS);
2231
+ var readinessStatusSchema = z23.enum(READINESS_STATUSES);
2126
2232
 
2127
2233
  // ../shared/dist/site.js
2128
- import { z as z23 } from "zod";
2234
+ import { z as z24 } from "zod";
2129
2235
  var SITE_STATUSES = [
2130
2236
  "setup",
2131
2237
  "active",
2132
2238
  "disabled",
2133
2239
  "archived"
2134
2240
  ];
2135
- var siteStatusSchema = z23.enum(SITE_STATUSES);
2136
- var websiteUrlSchema = z23.string().trim().url().refine((value) => value.startsWith("https://") || value.startsWith("http://"), "Website URL must use http or https");
2241
+ var siteStatusSchema = z24.enum(SITE_STATUSES);
2242
+ var websiteUrlSchema = z24.string().trim().url().refine((value) => value.startsWith("https://") || value.startsWith("http://"), "Website URL must use http or https");
2243
+
2244
+ // ../shared/dist/setup-assets.js
2245
+ import { z as z25 } from "zod";
2246
+ var configureSetupAssetTargetInputSchema = z25.object({
2247
+ siteId: z25.string().uuid(),
2248
+ runId: z25.string().uuid(),
2249
+ expectedReviewVersion: z25.number().int().positive(),
2250
+ expectedSnapshotHash: z25.string().regex(/^sha256:[0-9a-f]{64}$/u),
2251
+ mutationId: z25.string().uuid(),
2252
+ expectedApprovalId: z25.string().uuid().nullable(),
2253
+ targetId: z25.string().uuid().nullable(),
2254
+ targetType: z25.enum(["repo_static_assets", "siteplane_managed_fallback"]),
2255
+ approveManagedHosting: z25.boolean()
2256
+ }).strict().refine((value) => value.targetType === "siteplane_managed_fallback" || !value.approveManagedHosting);
2257
+ var setupAssetTargetApprovalSchema = z25.object({
2258
+ id: z25.string().uuid(),
2259
+ runId: z25.string().uuid(),
2260
+ reviewVersion: z25.number().int().positive(),
2261
+ snapshotHash: z25.string().regex(/^sha256:[0-9a-f]{64}$/u),
2262
+ targetId: z25.string().uuid(),
2263
+ targetType: z25.enum(["repo_static_assets", "siteplane_managed_fallback"]),
2264
+ targetRevision: z25.number().int().positive(),
2265
+ deploymentOrigin: z25.string().url(),
2266
+ gitConnectionId: z25.string().uuid().nullable(),
2267
+ gitRevision: z25.number().int().positive().nullable(),
2268
+ managedHostingApproved: z25.boolean(),
2269
+ actorUserId: z25.string().uuid(),
2270
+ approvedAt: z25.string().datetime({ offset: true })
2271
+ }).strict();
2272
+ var setupAssetReadinessSchema = z25.union([
2273
+ z25.object({
2274
+ status: z25.enum([
2275
+ "not_required",
2276
+ "needs_choice",
2277
+ "stale_setup_review",
2278
+ "permission_denied"
2279
+ ])
2280
+ }).strict(),
2281
+ z25.object({
2282
+ status: z25.literal("stale_approval"),
2283
+ approval: setupAssetTargetApprovalSchema.optional()
2284
+ }).strict(),
2285
+ z25.object({
2286
+ status: z25.literal("not_verified"),
2287
+ approval: setupAssetTargetApprovalSchema,
2288
+ jobId: z25.string().uuid().optional(),
2289
+ checkedAt: z25.string().datetime({ offset: true }).nullable().optional()
2290
+ }).strict(),
2291
+ z25.object({
2292
+ status: z25.enum(["ready", "checking", "retrying"]),
2293
+ approval: setupAssetTargetApprovalSchema,
2294
+ jobId: z25.string().uuid(),
2295
+ checkedAt: z25.string().datetime({ offset: true }).nullable()
2296
+ }).strict().refine((value) => value.status !== "ready" || value.checkedAt !== null)
2297
+ ]);
2298
+ var checkSetupAssetTargetInputSchema = z25.object({
2299
+ siteId: z25.string().uuid(),
2300
+ runId: z25.string().uuid(),
2301
+ approvalId: z25.string().uuid(),
2302
+ intent: z25.enum(["start", "poll"])
2303
+ }).strict();
2137
2304
 
2138
2305
  // ../cli/dist/analytics/manifest.js
2139
2306
  async function readAnalyticsManifestFile(manifestPath) {
@@ -2714,6 +2881,13 @@ function createIntegrationErrors(manifest, sourceFiles, manifestPath) {
2714
2881
  filePath: manifestPath
2715
2882
  });
2716
2883
  }
2884
+ if (/\b(?:Cookiebot|OneTrust|cookieyes|consentManager|cookieConsent)\b/iu.test(sourceText) && !sourceText.includes("consentAdapter")) {
2885
+ issues.push({
2886
+ code: "analytics_check.consent_adapter_missing",
2887
+ message: "Existing consent management was detected without a Siteplane consentAdapter. Bind its current choice and change callbacks; unknown or denied consent must block Analytics. Verify the actual visitor flow in the browser.",
2888
+ filePath: manifestPath
2889
+ });
2890
+ }
2717
2891
  if (manifest.metadata?.siteplanePreviewSuppression !== true) {
2718
2892
  issues.push({
2719
2893
  code: "analytics_check.preview_suppression_unverified",
@@ -2793,7 +2967,19 @@ async function readCspWarnings(filePaths) {
2793
2967
  import { mkdir as mkdir3, writeFile as writeFile3 } from "fs/promises";
2794
2968
  import { dirname as dirname3, join } from "path";
2795
2969
  async function analyticsInitCommand(input) {
2796
- const manifest = {
2970
+ const manifestPath = join(input.projectDir, "siteplane.analytics.json");
2971
+ const existing = await readAnalyticsManifestFile(manifestPath).catch((error) => {
2972
+ if (error.code === "ENOENT")
2973
+ return null;
2974
+ throw error;
2975
+ });
2976
+ if (existing && existing.manifest.siteId !== input.siteId)
2977
+ throw new Error("The Analytics manifest belongs to a different site. The existing manifest was preserved.");
2978
+ const manifest = existing ? {
2979
+ ...existing.manifest,
2980
+ siteKeyRef: input.siteKeyRef,
2981
+ siteKeyLookup: input.siteKeyLookup
2982
+ } : {
2797
2983
  schemaVersion: ANALYTICS_SCHEMA_VERSION,
2798
2984
  siteId: input.siteId,
2799
2985
  siteKeyRef: input.siteKeyRef,
@@ -2802,7 +2988,6 @@ async function analyticsInitCommand(input) {
2802
2988
  targets: [],
2803
2989
  metadata: { siteplanePreviewSuppression: true }
2804
2990
  };
2805
- const manifestPath = join(input.projectDir, "siteplane.analytics.json");
2806
2991
  const artifacts = createAnalyticsArtifacts(input.agentClient);
2807
2992
  await writeAnalyticsManifestFile(manifestPath, manifest);
2808
2993
  for (const artifact of artifacts) {
@@ -2855,6 +3040,9 @@ Analytics contract hash: ${ANALYTICS_CONTRACT_HASH}
2855
3040
  - Use stable data-siteplane-target-id values that do not depend on visible copy.
2856
3041
  - Use public site keys only through environment references.
2857
3042
  - Do not write secret analytics keys, setup tokens or project CLI tokens into source files.
3043
+ - Mount the SDK once in the existing client lifecycle. Wire installDataAttributeTracking and createNextAppRouterNavigationAdapter to analytics.track/getRouteViewId/setPageContext, feed initial and subsequent Next.js pathname changes, and refresh attribute targets after navigation. Dispose attribute tracking and the SDK on unmount.
3044
+ - Inspect existing consent management. Pass consentAdapter with getConsent and subscribe to initSiteplaneAnalytics for an existing CMP; return unknown while unresolved, disabled for denial and a permitted mode only for its actual visitor grant. Subscribe returns cleanup. Do not mirror CMP snapshots with setConsent or replace stored opt-outs.
3045
+ - Omit consentAdapter only after confirming no existing CMP. An unrecognized CMP blocks Analytics with a concrete repair diagnostic; do not invent a grant or a no-op adapter to pass a check.
2858
3046
  - Suppress editor-preview traffic from live analytics.
2859
3047
  - Run npx siteplane analytics check, npx siteplane analytics sync and npx siteplane analytics test after setup.
2860
3048
  `;
@@ -2938,26 +3126,28 @@ async function analyticsReadinessCommand(input) {
2938
3126
  }
2939
3127
 
2940
3128
  // ../cli/dist/commands/analytics/public-key.js
2941
- import { z as z24 } from "zod";
2942
- var responseSchema = z24.object({
2943
- ok: z24.literal(true),
2944
- data: z24.object({
2945
- rawPublicKey: z24.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
3129
+ import { z as z26 } from "zod";
3130
+ var responseSchema = z26.object({
3131
+ ok: z26.literal(true),
3132
+ data: z26.object({
3133
+ rawPublicKey: z26.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
2946
3134
  })
2947
3135
  });
2948
- var errorResponseSchema = z24.object({
2949
- error: z24.object({
2950
- code: z24.string().regex(/^[a-z][a-z0-9_.-]+$/u)
3136
+ var errorResponseSchema = z26.object({
3137
+ error: z26.object({
3138
+ code: z26.string().regex(/^[a-z][a-z0-9_.-]+$/u)
2951
3139
  })
2952
3140
  });
2953
3141
  async function analyticsPublicKeyCommand(input) {
2954
3142
  const fetcher = input.fetchImpl ?? fetch;
2955
3143
  const response = await fetcher(`${input.config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/analytics/public-key`, {
2956
3144
  method: "POST",
3145
+ redirect: "error",
3146
+ signal: AbortSignal.timeout(2e4),
2957
3147
  headers: createAnalyticsCliRequestHeaders(input.config),
2958
3148
  body: JSON.stringify({ siteId: input.config.siteId })
2959
3149
  });
2960
- const payload = await response.json();
3150
+ const payload = await response.json().catch(() => null);
2961
3151
  const parsed = responseSchema.safeParse(payload);
2962
3152
  if (!response.ok || !parsed.success) {
2963
3153
  const error = errorResponseSchema.safeParse(payload);
@@ -2966,6 +3156,43 @@ async function analyticsPublicKeyCommand(input) {
2966
3156
  return parsed.data.data.rawPublicKey;
2967
3157
  }
2968
3158
 
3159
+ // ../cli/dist/commands/analytics/prepare.js
3160
+ import { z as z27 } from "zod";
3161
+ var resultSchema = z27.object({
3162
+ ok: z27.literal(true),
3163
+ data: z27.object({
3164
+ rawPublicKey: z27.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/u),
3165
+ generation: z27.number().int().positive(),
3166
+ status: z27.enum([
3167
+ "setup_started",
3168
+ "test_mode",
3169
+ "active",
3170
+ "paused",
3171
+ "error",
3172
+ "deleting"
3173
+ ])
3174
+ }).strict()
3175
+ }).strict();
3176
+ var errorSchema = z27.object({
3177
+ error: z27.object({ code: z27.string().regex(/^[a-z][a-z0-9_.-]+$/u) })
3178
+ });
3179
+ async function analyticsPrepareCommand(input) {
3180
+ const response = await (input.fetchImpl ?? fetch)(`${input.config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/analytics/prepare`, {
3181
+ method: "POST",
3182
+ redirect: "error",
3183
+ headers: createAnalyticsCliRequestHeaders(input.config),
3184
+ body: JSON.stringify({ siteId: input.config.siteId }),
3185
+ signal: AbortSignal.timeout(2e4)
3186
+ });
3187
+ const payload = await response.json().catch(() => null);
3188
+ const parsed = resultSchema.safeParse(payload);
3189
+ if (!response.ok || !parsed.success) {
3190
+ const error = errorSchema.safeParse(payload);
3191
+ throw new Error(`${error.success ? error.data.error.code : "analytics_prepare.invalid_response"}: Analytics preparation failed. Use the current setup context; the existing connection is unchanged.`);
3192
+ }
3193
+ return parsed.data.data;
3194
+ }
3195
+
2969
3196
  // ../cli/dist/commands/analytics/test.js
2970
3197
  import { randomUUID } from "crypto";
2971
3198
  async function analyticsTestCommand(input) {
@@ -3167,22 +3394,19 @@ async function bookingTestCommand(input) {
3167
3394
  import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
3168
3395
  import { randomUUID as randomUUID2 } from "crypto";
3169
3396
  import { join as join3 } from "path";
3170
- import { z as z25 } from "zod";
3171
- var siteplaneProjectConfigSchema = z25.object({
3172
- version: z25.literal(2),
3173
- apiBaseUrl: z25.string().url(),
3174
- siteId: z25.string().uuid(),
3175
- publicSiteKeyId: z25.string().uuid(),
3176
- publicSiteKey: z25.string().trim().min(1),
3177
- runId: z25.string().uuid(),
3178
- appDirectory: z25.string().min(1),
3179
- taskContractVersion: z25.literal("siteplane.setup-task.v2"),
3180
- adminProtocolVersion: z25.literal(2),
3181
- packages: z25.object({
3182
- siteplane: z25.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u),
3183
- runtimeNext: z25.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
3184
- }).strict(),
3185
- fieldContractHash: z25.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
3397
+ import { z as z28 } from "zod";
3398
+ var siteplaneProjectConfigSchema = z28.object({
3399
+ version: z28.literal(2),
3400
+ apiBaseUrl: z28.string().url(),
3401
+ siteId: z28.string().uuid(),
3402
+ publicSiteKeyId: z28.string().uuid(),
3403
+ publicSiteKey: z28.string().trim().min(1),
3404
+ runId: z28.string().uuid(),
3405
+ appDirectory: z28.string().min(1),
3406
+ taskContractVersion: z28.literal("siteplane.setup-task.v2"),
3407
+ adminProtocolVersion: z28.literal(2),
3408
+ packages: siteSetupPackagesSchema,
3409
+ fieldContractHash: z28.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
3186
3410
  }).strict();
3187
3411
  async function readProjectPackageJson(projectDir) {
3188
3412
  return JSON.parse(await readFile5(join3(projectDir, "package.json"), "utf8"));
@@ -3242,13 +3466,13 @@ import { randomUUID as randomUUID3 } from "crypto";
3242
3466
  import { chmod as chmod2, lstat, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
3243
3467
  import { dirname as dirname5, join as join4, relative } from "path";
3244
3468
  import { promisify } from "util";
3245
- import { z as z26 } from "zod";
3246
- var siteplaneCredentialsSchema = z26.object({
3247
- accessToken: z26.string().trim().min(1),
3248
- siteRevalidationSecret: z26.string().trim().min(1),
3249
- adminSession: z26.object({
3250
- secret: z26.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3251
- generation: z26.string().uuid()
3469
+ import { z as z29 } from "zod";
3470
+ var siteplaneCredentialsSchema = z29.object({
3471
+ accessToken: z29.string().trim().min(1),
3472
+ siteRevalidationSecret: z29.string().trim().min(1),
3473
+ adminSession: z29.object({
3474
+ secret: z29.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3475
+ generation: z29.string().uuid()
3252
3476
  }).strict().optional()
3253
3477
  }).strict();
3254
3478
  async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
@@ -3331,7 +3555,7 @@ async function gitPathMatches(projectDir, path, command) {
3331
3555
  // ../cli/dist/commands/init.js
3332
3556
  import { access as access3 } from "fs/promises";
3333
3557
  import { join as join7, relative as relative3 } from "path";
3334
- import { z as z29 } from "zod";
3558
+ import { z as z32 } from "zod";
3335
3559
 
3336
3560
  // ../cli/dist/commands/setup-preflight.js
3337
3561
  import { createHash as createHash2 } from "crypto";
@@ -3343,11 +3567,11 @@ import { parse as parseYaml } from "yaml";
3343
3567
  import { createRequire } from "module";
3344
3568
  import { readFile as readFile7 } from "fs/promises";
3345
3569
  import { join as join5 } from "path";
3346
- import { z as z27 } from "zod";
3347
- var packageSchema = z27.object({
3348
- name: z27.string().optional(),
3349
- version: z27.string(),
3350
- peerDependencies: z27.record(z27.string(), z27.string()).optional()
3570
+ import { z as z30 } from "zod";
3571
+ var packageSchema = z30.object({
3572
+ name: z30.string().optional(),
3573
+ version: z30.string(),
3574
+ peerDependencies: z30.record(z30.string(), z30.string()).optional()
3351
3575
  });
3352
3576
  async function readInstalledPackage(projectDir, name2) {
3353
3577
  const require2 = createRequire(join5(projectDir, "package.json"));
@@ -3362,13 +3586,14 @@ async function readInstalledPackage(projectDir, name2) {
3362
3586
  throw new Error(`Install ${name2} with the canonical package manager before setup.`);
3363
3587
  }
3364
3588
  async function assertExactSetupPackages(projectDir, packages) {
3365
- const manifest = z27.object({
3366
- dependencies: z27.record(z27.string(), z27.string()).optional(),
3367
- devDependencies: z27.record(z27.string(), z27.string()).optional()
3589
+ const manifest = z30.object({
3590
+ dependencies: z30.record(z30.string(), z30.string()).optional(),
3591
+ devDependencies: z30.record(z30.string(), z30.string()).optional()
3368
3592
  }).parse(JSON.parse(await readFile7(join5(projectDir, "package.json"), "utf8")));
3369
3593
  for (const [name2, version2] of [
3370
3594
  ["siteplane", packages.siteplane],
3371
- ["@siteplane/runtime-next", packages.runtimeNext]
3595
+ ["@siteplane/runtime-next", packages.runtimeNext],
3596
+ ...packages.analytics ? [["@siteplane/analytics", packages.analytics]] : []
3372
3597
  ]) {
3373
3598
  const declared = manifest.dependencies?.[name2] ?? manifest.devDependencies?.[name2];
3374
3599
  const installed = await readInstalledPackage(projectDir, name2);
@@ -3380,7 +3605,7 @@ async function assertExactSetupPackages(projectDir, packages) {
3380
3605
  // ../cli/dist/commands/setup-preflight.js
3381
3606
  import { access as access2, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
3382
3607
  import { dirname as dirname6, join as join6, relative as relative2, resolve, sep } from "path";
3383
- import { z as z28 } from "zod";
3608
+ import { z as z31 } from "zod";
3384
3609
 
3385
3610
  // ../cli/dist/commands/setup-process.js
3386
3611
  import { spawn } from "child_process";
@@ -3481,29 +3706,29 @@ async function setupVercelApi(cwd, endpoint, body, method, options) {
3481
3706
  }
3482
3707
 
3483
3708
  // ../cli/dist/commands/setup-preflight.js
3484
- var manifestSchema = z28.object({
3485
- packageManager: z28.string().optional(),
3486
- engines: z28.object({ node: z28.string().optional() }).optional(),
3487
- dependencies: z28.record(z28.string(), z28.string()).optional(),
3488
- devDependencies: z28.record(z28.string(), z28.string()).optional(),
3489
- scripts: z28.record(z28.string(), z28.string()).optional(),
3490
- workspaces: z28.unknown().optional()
3709
+ var manifestSchema = z31.object({
3710
+ packageManager: z31.string().optional(),
3711
+ engines: z31.object({ node: z31.string().optional() }).optional(),
3712
+ dependencies: z31.record(z31.string(), z31.string()).optional(),
3713
+ devDependencies: z31.record(z31.string(), z31.string()).optional(),
3714
+ scripts: z31.record(z31.string(), z31.string()).optional(),
3715
+ workspaces: z31.unknown().optional()
3491
3716
  });
3492
- var vercelProjectSchema = z28.object({
3493
- id: z28.string(),
3494
- accountId: z28.string(),
3495
- name: z28.string(),
3496
- nodeVersion: z28.string().nullable().optional(),
3497
- rootDirectory: z28.string().nullable().optional(),
3498
- framework: z28.string().nullable().optional(),
3499
- installCommand: z28.string().nullable().optional(),
3500
- buildCommand: z28.string().nullable().optional(),
3501
- link: z28.object({
3502
- type: z28.string(),
3503
- repo: z28.string().optional(),
3504
- repoId: z28.union([z28.string(), z28.number()]).optional(),
3505
- org: z28.string().optional(),
3506
- productionBranch: z28.string().optional()
3717
+ var vercelProjectSchema = z31.object({
3718
+ id: z31.string(),
3719
+ accountId: z31.string(),
3720
+ name: z31.string(),
3721
+ nodeVersion: z31.string().nullable().optional(),
3722
+ rootDirectory: z31.string().nullable().optional(),
3723
+ framework: z31.string().nullable().optional(),
3724
+ installCommand: z31.string().nullable().optional(),
3725
+ buildCommand: z31.string().nullable().optional(),
3726
+ link: z31.object({
3727
+ type: z31.string(),
3728
+ repo: z31.string().optional(),
3729
+ repoId: z31.union([z31.string(), z31.number()]).optional(),
3730
+ org: z31.string().optional(),
3731
+ productionBranch: z31.string().optional()
3507
3732
  }).nullable().optional()
3508
3733
  });
3509
3734
  var exists = async (path) => access2(path).then(() => true, () => false);
@@ -3560,9 +3785,9 @@ async function inspectSetupLocalProject(projectDir) {
3560
3785
  const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join6(lockfileRoot, "package.json"), "utf8")));
3561
3786
  if (lockfileRoot !== projectDirectory) {
3562
3787
  const workspaceFile = join6(lockfileRoot, "pnpm-workspace.yaml");
3563
- const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z28.object({ packages: z28.array(z28.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z28.union([
3564
- z28.array(z28.string()),
3565
- z28.object({ packages: z28.array(z28.string()) }).transform((value) => value.packages)
3788
+ const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z31.object({ packages: z31.array(z31.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z31.union([
3789
+ z31.array(z31.string()),
3790
+ z31.object({ packages: z31.array(z31.string()) }).transform((value) => value.packages)
3566
3791
  ]).parse(rootManifest.workspaces);
3567
3792
  const selected = relative2(lockfileRoot, projectDirectory).split(sep).join("/");
3568
3793
  if (!workspace.some((pattern) => !pattern.startsWith("!") && minimatch(selected, pattern)) || workspace.some((pattern) => pattern.startsWith("!") && minimatch(selected, pattern.slice(1))))
@@ -3576,11 +3801,11 @@ async function inspectSetupLocalProject(projectDir) {
3576
3801
  break;
3577
3802
  }
3578
3803
  const lockText = await readFile8(join6(lockfileRoot, lockName), "utf8");
3579
- const npmLock = lockName === "package-lock.json" ? z28.object({
3580
- lockfileVersion: z28.number(),
3581
- packages: z28.record(z28.string(), z28.object({
3582
- version: z28.string().optional(),
3583
- peerDependencies: z28.record(z28.string(), z28.string()).optional()
3804
+ const npmLock = lockName === "package-lock.json" ? z31.object({
3805
+ lockfileVersion: z31.number(),
3806
+ packages: z31.record(z31.string(), z31.object({
3807
+ version: z31.string().optional(),
3808
+ peerDependencies: z31.record(z31.string(), z31.string()).optional()
3584
3809
  })).optional()
3585
3810
  }).parse(JSON.parse(lockText)) : null;
3586
3811
  async function version2(name3) {
@@ -3635,8 +3860,12 @@ async function inspectSetupLocalProject(projectDir) {
3635
3860
  sourceConflicts.push("static_export");
3636
3861
  if (/\bbasePath\s*:/u.test(source))
3637
3862
  sourceConflicts.push("base_path");
3863
+ if (/\bloaderFile\s*:|\bloader\s*:\s*['"](?:custom|imgix|cloudinary|akamai)['"]/u.test(source))
3864
+ sourceConflicts.push(`inspect_image_loader:${file}`);
3865
+ if (/\bmaximumRedirects\s*:\s*[1-9]/u.test(source))
3866
+ sourceConflicts.push(`inspect_image_redirects:${file}`);
3638
3867
  }
3639
- if (sourceConflicts.length)
3868
+ if (sourceConflicts.some((conflict) => conflict === "static_export" || conflict === "base_path"))
3640
3869
  fail("unsupported_server_configuration", "Resolve static export/basePath configuration explicitly; Siteplane requires its server-side admin and revalidation handlers.");
3641
3870
  for (const name3 of [
3642
3871
  "middleware.ts",
@@ -3648,8 +3877,14 @@ async function inspectSetupLocalProject(projectDir) {
3648
3877
  "src/proxy.ts",
3649
3878
  "src/proxy.js"
3650
3879
  ]) {
3651
- if (await exists(join6(projectDirectory, name3)))
3880
+ if (await exists(join6(projectDirectory, name3))) {
3652
3881
  sourceConflicts.push(`inspect_routing:${name3}`);
3882
+ if (await readlink(join6(projectDirectory, name3)).catch(() => null))
3883
+ continue;
3884
+ const policySource = await readFile8(join6(projectDirectory, name3), "utf8");
3885
+ if (/Content-Security-Policy|img-src|default-src/iu.test(policySource))
3886
+ sourceConflicts.push(`inspect_image_csp:${name3}`);
3887
+ }
3653
3888
  }
3654
3889
  async function inspectSource(directory) {
3655
3890
  for (const entry of await readdir(directory, { withFileTypes: true })) {
@@ -3663,6 +3898,8 @@ async function inspectSetupLocalProject(projectDir) {
3663
3898
  if (!/\.[cm]?[jt]sx?$/u.test(entry.name))
3664
3899
  continue;
3665
3900
  const source = await readFile8(path, "utf8");
3901
+ if (/Content-Security-Policy|img-src|default-src/iu.test(source))
3902
+ sourceConflicts.push(`inspect_image_csp:${relative2(projectDirectory, path)}`);
3666
3903
  if (/from\s*["']next\/image["']/u.test(source))
3667
3904
  sourceConflicts.push(`inspect_image_policy:${relative2(projectDirectory, path)}`);
3668
3905
  if (/\b(?:Cookiebot|OneTrust|cookieyes|consentManager|cookieConsent)\b/iu.test(source))
@@ -3708,9 +3945,9 @@ async function setupPreflightCommand(input) {
3708
3945
  linkDirectory = dirname6(linkDirectory);
3709
3946
  if (!await exists(join6(linkDirectory, ".vercel/project.json")))
3710
3947
  fail("vercel_project_not_linked", "Link this application to its intended Vercel project before setup; Siteplane will not guess a target.");
3711
- const linked = z28.object({
3712
- projectId: z28.string().regex(/^prj_[A-Za-z0-9]+$/u),
3713
- orgId: z28.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
3948
+ const linked = z31.object({
3949
+ projectId: z31.string().regex(/^prj_[A-Za-z0-9]+$/u),
3950
+ orgId: z31.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
3714
3951
  }).parse(JSON.parse(await readFile8(join6(linkDirectory, ".vercel/project.json"), "utf8")));
3715
3952
  const project = vercelProjectSchema.parse(await setupVercelApi(linkDirectory, `/v9/projects/${linked.projectId}?teamId=${linked.orgId}`));
3716
3953
  if (project.id !== linked.projectId || project.accountId !== linked.orgId)
@@ -3724,11 +3961,11 @@ async function setupPreflightCommand(input) {
3724
3961
  fail("vercel_production_branch_conflict", "The local branch differs from the bound Vercel Production branch.");
3725
3962
  if (project.link?.repo && project.link.org && !local.git.remote?.replace(/\.git$/u, "").endsWith(`${project.link.org}/${project.link.repo}`))
3726
3963
  fail("vercel_git_conflict", "The local origin repository differs from the Vercel Git connection.");
3727
- const env = z28.object({
3728
- envs: z28.array(z28.object({
3729
- key: z28.string(),
3730
- value: z28.string().optional(),
3731
- target: z28.array(z28.string()).optional()
3964
+ const env = z31.object({
3965
+ envs: z31.array(z31.object({
3966
+ key: z31.string(),
3967
+ value: z31.string().optional(),
3968
+ target: z31.array(z31.string()).optional()
3732
3969
  }))
3733
3970
  }).parse(await setupVercelApi(linkDirectory, `/v10/projects/${linked.projectId}/env?teamId=${linked.orgId}`));
3734
3971
  const corepack = env.envs.some((item) => item.key === "ENABLE_EXPERIMENTAL_COREPACK" && item.value === "1" && item.target?.includes("production"));
@@ -3818,29 +4055,26 @@ async function initCommand(input) {
3818
4055
  ]
3819
4056
  };
3820
4057
  }
3821
- var siteSetupBootstrapDataSchema = z29.object({
3822
- credentialPurpose: z29.literal("site_setup"),
3823
- apiBaseUrl: z29.string().url(),
3824
- siteId: z29.string().uuid(),
3825
- publicSiteKeyId: z29.string().uuid(),
3826
- publicSiteKey: z29.string().trim().min(1),
3827
- accessToken: z29.string().trim().min(1),
3828
- siteRevalidationSecret: z29.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3829
- runId: z29.string().uuid(),
3830
- packages: z29.object({
3831
- siteplane: z29.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u),
3832
- runtimeNext: z29.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
3833
- }).strict()
4058
+ var siteSetupBootstrapDataSchema = z32.object({
4059
+ credentialPurpose: z32.literal("site_setup"),
4060
+ apiBaseUrl: z32.string().url(),
4061
+ siteId: z32.string().uuid(),
4062
+ publicSiteKeyId: z32.string().uuid(),
4063
+ publicSiteKey: z32.string().trim().min(1),
4064
+ accessToken: z32.string().trim().min(1),
4065
+ siteRevalidationSecret: z32.string().regex(/^[A-Za-z0-9_-]{43}$/u),
4066
+ runId: z32.string().uuid(),
4067
+ packages: siteSetupPackagesSchema
3834
4068
  }).strict();
3835
- var featureBootstrapDataSchema = z29.object({
3836
- credentialPurpose: z29.enum(["analytics", "booking"]),
3837
- apiBaseUrl: z29.string().url(),
3838
- siteId: z29.string().uuid(),
3839
- accessToken: z29.string().trim().min(1)
4069
+ var featureBootstrapDataSchema = z32.object({
4070
+ credentialPurpose: z32.enum(["analytics", "booking"]),
4071
+ apiBaseUrl: z32.string().url(),
4072
+ siteId: z32.string().uuid(),
4073
+ accessToken: z32.string().trim().min(1)
3840
4074
  }).strict();
3841
- var bootstrapResponseSchema = z29.object({
3842
- ok: z29.literal(true),
3843
- data: z29.discriminatedUnion("credentialPurpose", [
4075
+ var bootstrapResponseSchema = z32.object({
4076
+ ok: z32.literal(true),
4077
+ data: z32.discriminatedUnion("credentialPurpose", [
3844
4078
  siteSetupBootstrapDataSchema,
3845
4079
  featureBootstrapDataSchema
3846
4080
  ])
@@ -3907,7 +4141,7 @@ async function persistSiteSetupBootstrap(input, bootstrap, appDirectory) {
3907
4141
  readLocalCredentials(input.projectDir),
3908
4142
  readProjectConfig(input.projectDir)
3909
4143
  ]);
3910
- if (credentials.accessToken !== bootstrap.accessToken || credentials.siteRevalidationSecret !== bootstrap.siteRevalidationSecret || config.runId !== bootstrap.runId || config.packages.siteplane !== bootstrap.packages.siteplane || config.packages.runtimeNext !== bootstrap.packages.runtimeNext || config.apiBaseUrl !== bootstrap.apiBaseUrl || config.siteId !== bootstrap.siteId || config.publicSiteKeyId !== bootstrap.publicSiteKeyId || config.publicSiteKey !== bootstrap.publicSiteKey) {
4144
+ if (credentials.accessToken !== bootstrap.accessToken || credentials.siteRevalidationSecret !== bootstrap.siteRevalidationSecret || config.runId !== bootstrap.runId || config.packages.siteplane !== bootstrap.packages.siteplane || config.packages.runtimeNext !== bootstrap.packages.runtimeNext || config.packages.analytics !== bootstrap.packages.analytics || config.apiBaseUrl !== bootstrap.apiBaseUrl || config.siteId !== bootstrap.siteId || config.publicSiteKeyId !== bootstrap.publicSiteKeyId || config.publicSiteKey !== bootstrap.publicSiteKey) {
3911
4145
  throw new Error("Siteplane setup files could not be verified.");
3912
4146
  }
3913
4147
  return { configPath, credentialsPath };
@@ -3998,7 +4232,7 @@ async function collectSourceFiles(directory) {
3998
4232
  import { execFile as execFile2 } from "child_process";
3999
4233
  import { readFile as readFile9 } from "fs/promises";
4000
4234
  import { promisify as promisify2 } from "util";
4001
- import { z as z30 } from "zod";
4235
+ import { z as z33 } from "zod";
4002
4236
 
4003
4237
  // ../cli/dist/scan/next-source-scan.js
4004
4238
  import ts2 from "typescript";
@@ -4075,6 +4309,7 @@ function scanSourceFacts(files) {
4075
4309
  const hardErrors = [];
4076
4310
  const warnings = [];
4077
4311
  const suggestions = [];
4312
+ const directAttrs = [];
4078
4313
  const eventPreviewAttrs = [];
4079
4314
  const eventPreviewComponentPropConsumers = [];
4080
4315
  const eventPreviewComponentPropUsages = [];
@@ -4082,6 +4317,7 @@ function scanSourceFacts(files) {
4082
4317
  let hasGenericEventPreviewConsumer = false;
4083
4318
  for (const file of files) {
4084
4319
  const facts = scanSourceFile2(file, fields, hardErrors);
4320
+ directAttrs.push(...facts.directAttrs);
4085
4321
  eventPreviewAttrs.push(...facts.eventPreviewAttrs);
4086
4322
  eventPreviewComponentPropConsumers.push(...facts.eventPreviewComponentPropConsumers);
4087
4323
  eventPreviewComponentPropUsages.push(...facts.eventPreviewComponentPropUsages);
@@ -4095,6 +4331,18 @@ function scanSourceFacts(files) {
4095
4331
  eventPreviewConsumerFieldIds.add(usage.fieldId);
4096
4332
  }
4097
4333
  }
4334
+ for (const attr of directAttrs) {
4335
+ const field = fields.find((candidate) => candidate.fieldId === attr.fieldId);
4336
+ const expectedRoute = field?.technicalRouteKey ?? field?.routeHint;
4337
+ if (!attr.routeKey || expectedRoute && attr.routeKey !== expectedRoute) {
4338
+ hardErrors.push({
4339
+ code: attr.routeKey ? "field_scan.attrs_route_key_mismatch" : "field_scan.attrs_route_key_missing",
4340
+ message: `DOM attrs for ${attr.fieldId} must include the same canonical routeKey as its value call${expectedRoute ? ` (${expectedRoute})` : ""}. Pass it explicitly to siteplane.attrs(fieldId, { routeKey }); the value call does not attach DOM metadata.`,
4341
+ fieldId: attr.fieldId,
4342
+ filePath: attr.filePath
4343
+ });
4344
+ }
4345
+ }
4098
4346
  markMissingEventPreviewHandlerErrors(eventPreviewAttrs, eventPreviewConsumerFieldIds, hasGenericEventPreviewConsumer, hardErrors);
4099
4347
  validateScannedFields(fields, hardErrors, warnings, suggestions);
4100
4348
  return {
@@ -4120,6 +4368,7 @@ function scanSourceFile2(file, fields, hardErrors) {
4120
4368
  const fieldsInFile = [];
4121
4369
  const attrFieldIds = /* @__PURE__ */ new Set();
4122
4370
  const attrRouteRefs = /* @__PURE__ */ new Set();
4371
+ const directAttrs = [];
4123
4372
  const eventPreviewAttrs = [];
4124
4373
  const eventPreviewAttrVariables = /* @__PURE__ */ new Map();
4125
4374
  const eventPreviewComponentPropConsumers = [];
@@ -4141,7 +4390,7 @@ function scanSourceFile2(file, fields, hardErrors) {
4141
4390
  collectEventPreviewComponentPropUsages(node, eventPreviewAttrVariables, eventPreviewComponentPropUsages, file);
4142
4391
  }
4143
4392
  if (ts2.isCallExpression(node)) {
4144
- collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs, eventPreviewAttrVariables, file);
4393
+ collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs, eventPreviewAttrVariables, directAttrs, file);
4145
4394
  collectUnusedValueCallError(node, hardErrors, file);
4146
4395
  const extractedFields = extractFunctionFields(node, file);
4147
4396
  for (const field of extractedFields) {
@@ -4169,6 +4418,7 @@ function scanSourceFile2(file, fields, hardErrors) {
4169
4418
  visit(sourceFile);
4170
4419
  markMissingAttrsWarnings(fieldsInFile, attrFieldIds, attrRouteRefs);
4171
4420
  return {
4421
+ directAttrs,
4172
4422
  eventPreviewAttrs,
4173
4423
  eventPreviewComponentPropConsumers,
4174
4424
  eventPreviewComponentPropUsages,
@@ -4349,7 +4599,7 @@ function createFallbackHash(fieldType, fallback) {
4349
4599
  return void 0;
4350
4600
  }
4351
4601
  }
4352
- function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs, eventPreviewAttrVariables, file) {
4602
+ function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs, eventPreviewAttrVariables, directAttrs, file) {
4353
4603
  if (!ts2.isPropertyAccessExpression(node.expression)) {
4354
4604
  return;
4355
4605
  }
@@ -4361,6 +4611,11 @@ function collectAttrsCall(node, attrFieldIds, attrRouteRefs, eventPreviewAttrs,
4361
4611
  const directFieldId = staticExpressionValue2(firstArg);
4362
4612
  if (typeof directFieldId === "string") {
4363
4613
  attrFieldIds.add(directFieldId);
4614
+ directAttrs.push({
4615
+ fieldId: directFieldId,
4616
+ routeKey: secondArg && typeof secondArg === "object" && "routeKey" in secondArg ? stringValue2(secondArg.routeKey) : void 0,
4617
+ filePath: file.filePath
4618
+ });
4364
4619
  if (hasEventPreviewStrategy(secondArg)) {
4365
4620
  eventPreviewAttrs.push({
4366
4621
  fieldId: directFieldId,
@@ -4665,30 +4920,32 @@ function isPositionalFieldReference(value) {
4665
4920
 
4666
4921
  // ../cli/dist/commands/site-setup.js
4667
4922
  var execFileAsync2 = promisify2(execFile2);
4668
- var safeErrorSchema = z30.object({
4669
- code: z30.string().trim().min(1),
4670
- message: z30.string().trim().min(1)
4923
+ var safeErrorSchema = z33.object({
4924
+ code: z33.string().trim().min(1),
4925
+ message: z33.string().trim().min(1)
4671
4926
  }).passthrough();
4672
- var errorResponseSchema2 = z30.object({ ok: z30.literal(false), error: safeErrorSchema }).passthrough();
4673
- var contextDataSchema = z30.object({ task: siteSetupTaskSchema }).strict();
4674
- var contextResponseSchema = z30.object({ ok: z30.literal(true), data: contextDataSchema }).strict();
4675
- var applyDataSchema = z30.object({
4676
- status: z30.enum(["applied", "ready_for_review"]),
4677
- runId: z30.string().uuid().optional(),
4678
- contractVersionId: z30.string().uuid().optional(),
4679
- fieldContractHash: z30.string().regex(/^sha256:[0-9a-f]{64}$/u),
4680
- editorDefinitionHash: z30.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
4681
- fieldCount: z30.number().int().nonnegative().optional(),
4682
- routeCount: z30.number().int().nonnegative().optional()
4927
+ var errorResponseSchema2 = z33.object({ ok: z33.literal(false), error: safeErrorSchema }).passthrough();
4928
+ var contextDataSchema = z33.object({
4929
+ task: siteSetupTaskSchema.refine((task) => task.run !== null)
4930
+ }).strict();
4931
+ var contextResponseSchema = z33.object({ ok: z33.literal(true), data: contextDataSchema }).strict();
4932
+ var applyDataSchema = z33.object({
4933
+ status: z33.enum(["applied", "ready_for_review"]),
4934
+ runId: z33.string().uuid().optional(),
4935
+ contractVersionId: z33.string().uuid().optional(),
4936
+ fieldContractHash: z33.string().regex(/^sha256:[0-9a-f]{64}$/u),
4937
+ editorDefinitionHash: z33.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
4938
+ fieldCount: z33.number().int().nonnegative().optional(),
4939
+ routeCount: z33.number().int().nonnegative().optional()
4683
4940
  }).strict();
4684
- var applyResponseSchema = z30.object({ ok: z30.literal(true), data: applyDataSchema }).strict();
4685
- var verifyDataSchema = z30.object({
4686
- status: z30.literal("ready_for_review"),
4687
- runId: z30.string().uuid().optional(),
4688
- deploymentOrigin: z30.string().url().optional(),
4689
- deploymentRevision: z30.string().optional()
4941
+ var applyResponseSchema = z33.object({ ok: z33.literal(true), data: applyDataSchema }).strict();
4942
+ var verifyDataSchema = z33.object({
4943
+ status: z33.literal("ready_for_review"),
4944
+ runId: z33.string().uuid().optional(),
4945
+ deploymentOrigin: z33.string().url().optional(),
4946
+ deploymentRevision: z33.string().optional()
4690
4947
  }).strict();
4691
- var verifyResponseSchema = z30.object({ ok: z30.literal(true), data: verifyDataSchema }).strict();
4948
+ var verifyResponseSchema = z33.object({ ok: z33.literal(true), data: verifyDataSchema }).strict();
4692
4949
  async function siteSetupContextCommand(input) {
4693
4950
  const response = await postSiteSetup(input, "context", {});
4694
4951
  const parsed = contextResponseSchema.safeParse(response.payload);
@@ -4844,9 +5101,9 @@ async function siteSetupActivityCommand(input) {
4844
5101
  message: "Choose inspecting, integrating, deploying, verifying or repairing."
4845
5102
  };
4846
5103
  const response = await postSiteSetup(input, "activity", activity.data);
4847
- const parsed = z30.object({
4848
- ok: z30.literal(true),
4849
- data: z30.object({ status: z30.enum(["recorded", "rate_limited"]) }).strict()
5104
+ const parsed = z33.object({
5105
+ ok: z33.literal(true),
5106
+ data: z33.object({ status: z33.enum(["recorded", "rate_limited"]) }).strict()
4850
5107
  }).strict().safeParse(response.payload);
4851
5108
  return response.ok && parsed.success ? parsed.data.data : actionRequired(response.payload, "Setup activity could not be recorded.");
4852
5109
  }
@@ -4871,7 +5128,7 @@ async function setupPrepareCommand(input) {
4871
5128
  if (context.status !== "ok")
4872
5129
  return context;
4873
5130
  const task = context.task;
4874
- if (task.site?.siteId !== config.siteId || task.run?.runId !== config.runId || task.packages.siteplane !== config.packages.siteplane || task.packages.runtimeNext !== config.packages.runtimeNext) {
5131
+ if (task.site?.siteId !== config.siteId || task.run?.runId !== config.runId || task.packages.siteplane !== config.packages.siteplane || task.packages.analytics !== config.packages.analytics || task.packages.runtimeNext !== config.packages.runtimeNext) {
4875
5132
  throw new SetupFailure("setup_contract_conflict", "The local configuration does not match this server task and its exact package versions.");
4876
5133
  }
4877
5134
  if (task.run.status === "completed" || task.run.status === "ready_for_review")
@@ -4951,7 +5208,7 @@ export default function SiteplaneBridge() {
4951
5208
  const session = query.get("siteplaneSessionId");
4952
5209
  if (query.get("siteplanePreview") === "1" && query.get("siteplaneAdminOrigin") === new URL(config.apiBaseUrl).origin && session && /^[A-Za-z0-9_-]{1,128}$/.test(session)) setSessionId(session);
4953
5210
  }, []);
4954
- return sessionId ? <FieldRuntimeBridge siteId={config.siteId} adminOrigin={new URL(config.apiBaseUrl).origin} sessionId={sessionId} /> : null;
5211
+ return sessionId ? <FieldRuntimeBridge siteId={config.siteId} adminOrigin={new URL(config.apiBaseUrl).origin} sessionId={sessionId}${task.modules.includes("analytics") ? " analyticsSiteKey={process.env.NEXT_PUBLIC_SITEPLANE_ANALYTICS_SITE_KEY}" : ""} /> : null;
4955
5212
  }
4956
5213
  `;
4957
5214
  const files = /* @__PURE__ */ new Map([
@@ -4997,7 +5254,7 @@ ${task.goal}
4997
5254
 
4998
5255
  ${task.discovery.rules.map((rule) => `- ${rule}`).join("\n")}
4999
5256
 
5000
- Run setup context for the current user instructions and authorized modules. Keep the user instructions distinct from your selection summary. Use setup deploy --wait for environment transfer and deployment; never read or print credential values.
5257
+ Run setup context for the current user instructions and authorized modules. Keep the user instructions distinct from your selection summary. Use setup deploy --wait for environment transfer and deployment; never read or print credential values. For image fields, withSiteplane prepares the exact Siteplane asset route and the website /siteplane-assets/ path in Next Image and existing img-src policies at build time. This grants no hosting permission. Preserve existing image sources; explicitly resolve custom loaders, redirect dependencies, or CSP written by middleware/proxy/meta tags before deployment. Use the provider-selected public SITEPLANE_SITE_ORIGIN for local builds.
5001
5258
  `);
5002
5259
  for (const [path, content] of files) {
5003
5260
  if (path === layoutPath || path === nextPath)
@@ -5042,6 +5299,12 @@ Run setup context for the current user instructions and authorized modules. Keep
5042
5299
  "--save-exact",
5043
5300
  `@siteplane/runtime-next@${task.packages.runtimeNext}`
5044
5301
  ]);
5302
+ if (task.packages.analytics && packageManifest.dependencies?.["@siteplane/analytics"] !== task.packages.analytics)
5303
+ await command([
5304
+ pm.name === "npm" ? "install" : "add",
5305
+ "--save-exact",
5306
+ `@siteplane/analytics@${task.packages.analytics}`
5307
+ ]);
5045
5308
  try {
5046
5309
  await assertExactSetupPackages(directory, task.packages);
5047
5310
  } catch {
@@ -5119,8 +5382,8 @@ async function assertSourcePath(root, target) {
5119
5382
  import { randomUUID as randomUUID5 } from "crypto";
5120
5383
  import { lstat as lstat3, mkdir as mkdir7, open as open4, readFile as readFile11, rm as rm4, rmdir } from "fs/promises";
5121
5384
  import { resolve as resolve2 } from "path";
5122
- import { z as z31 } from "zod";
5123
- var ownerSchema = z31.object({ pid: z31.number().int().positive(), nonce: z31.string().uuid() }).strict();
5385
+ import { z as z34 } from "zod";
5386
+ var ownerSchema = z34.object({ pid: z34.number().int().positive(), nonce: z34.string().uuid() }).strict();
5124
5387
  async function withSetupLock(projectDir, work) {
5125
5388
  const gitPath = (await setupProcess("git", ["rev-parse", "--git-path", "siteplane-setup.lock"], { cwd: projectDir })).trim();
5126
5389
  const path = resolve2(projectDir, gitPath);
@@ -5184,23 +5447,23 @@ import { execFile as execFile3 } from "child_process";
5184
5447
  import { lstat as lstat4, readFile as readFile12, writeFile as writeFile5, mkdir as mkdir8 } from "fs/promises";
5185
5448
  import { dirname as dirname8, isAbsolute as isAbsolute2, join as join10, relative as relative6, resolve as resolve3, sep as sep3 } from "path";
5186
5449
  import { isDeepStrictEqual, promisify as promisify3 } from "util";
5187
- import { z as z32 } from "zod";
5450
+ import { z as z35 } from "zod";
5188
5451
  var execute = promisify3(execFile3);
5189
5452
  var name = ".siteplane/build-source.json";
5190
- var oid = z32.string().regex(/^[0-9a-f]{40}$/u);
5191
- var entrySchema = z32.object({
5192
- path: z32.string().min(1).max(4096),
5193
- mode: z32.enum(["100644", "100755", "120000"]),
5453
+ var oid = z35.string().regex(/^[0-9a-f]{40}$/u);
5454
+ var entrySchema = z35.object({
5455
+ path: z35.string().min(1).max(4096),
5456
+ mode: z35.enum(["100644", "100755", "120000"]),
5194
5457
  oid
5195
5458
  }).strict();
5196
- var schema = z32.object({
5197
- version: z32.literal(2),
5459
+ var schema = z35.object({
5460
+ version: z35.literal(2),
5198
5461
  revision: oid,
5199
- commit: z32.string().min(1).max(1048576),
5200
- entries: z32.array(entrySchema).min(1).max(1e5),
5201
- providerConfigurations: z32.array(z32.object({
5202
- path: z32.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
5203
- source: z32.string().max(1048576)
5462
+ commit: z35.string().min(1).max(1048576),
5463
+ entries: z35.array(entrySchema).min(1).max(1e5),
5464
+ providerConfigurations: z35.array(z35.object({
5465
+ path: z35.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
5466
+ source: z35.string().max(1048576)
5204
5467
  }).strict()).max(1e3)
5205
5468
  }).strict();
5206
5469
  async function writeBuildProvenance(checkout, revision) {
@@ -5249,37 +5512,38 @@ import { createHash as createHash4, randomBytes, randomUUID as randomUUID6 } fro
5249
5512
  import { access as access5, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
5250
5513
  import { tmpdir } from "os";
5251
5514
  import { join as join11 } from "path";
5252
- import { z as z33 } from "zod";
5253
- var envSchema = z33.object({
5254
- id: z33.string(),
5255
- key: z33.string(),
5256
- target: z33.array(z33.string()),
5257
- type: z33.string(),
5258
- comment: z33.string().optional(),
5259
- updatedAt: z33.number().optional()
5515
+ import { z as z36 } from "zod";
5516
+ var envSchema = z36.object({
5517
+ id: z36.string(),
5518
+ key: z36.string(),
5519
+ target: z36.array(z36.string()),
5520
+ type: z36.string(),
5521
+ comment: z36.string().optional(),
5522
+ updatedAt: z36.number().optional()
5260
5523
  });
5261
- var deploymentSchema = z33.object({
5262
- id: z33.string(),
5263
- projectId: z33.string(),
5264
- ownerId: z33.string().optional(),
5265
- target: z33.string().nullable(),
5266
- readyState: z33.string(),
5267
- createdAt: z33.number(),
5268
- url: z33.string(),
5269
- meta: z33.record(z33.string(), z33.unknown()).optional(),
5270
- gitSource: z33.object({ sha: z33.string().optional() }).nullable().optional()
5524
+ var deploymentSchema = z36.object({
5525
+ id: z36.string(),
5526
+ projectId: z36.string(),
5527
+ ownerId: z36.string().optional(),
5528
+ target: z36.string().nullable(),
5529
+ readyState: z36.string(),
5530
+ createdAt: z36.number(),
5531
+ url: z36.string(),
5532
+ meta: z36.record(z36.string(), z36.unknown()).optional(),
5533
+ gitSource: z36.object({ sha: z36.string().optional() }).nullable().optional()
5271
5534
  });
5272
- var buildProofSchema = z33.object({
5273
- node: z33.string(),
5274
- packageManager: z33.enum(["npm", "pnpm"]),
5275
- packageManagerVersion: z33.string(),
5276
- lockfileHash: z33.string(),
5277
- revision: z33.string(),
5278
- fieldContractHash: z33.string(),
5279
- siteplane: z33.string(),
5280
- runtimeNext: z33.string(),
5281
- next: z33.string(),
5282
- react: z33.string()
5535
+ var buildProofSchema = z36.object({
5536
+ node: z36.string(),
5537
+ packageManager: z36.enum(["npm", "pnpm"]),
5538
+ packageManagerVersion: z36.string(),
5539
+ lockfileHash: z36.string(),
5540
+ revision: z36.string(),
5541
+ fieldContractHash: z36.string(),
5542
+ siteplane: z36.string(),
5543
+ runtimeNext: z36.string(),
5544
+ analytics: z36.string().optional(),
5545
+ next: z36.string(),
5546
+ react: z36.string()
5283
5547
  }).strict();
5284
5548
  var digest = (value) => `sha256:${createHash4("sha256").update(stableJsonStringify(value)).digest("hex")}`;
5285
5549
  function fail2(code, message) {
@@ -5293,6 +5557,7 @@ var defaults = {
5293
5557
  verify: siteSetupVerifyCommand,
5294
5558
  post: postSiteSetup,
5295
5559
  writeBuildProvenance,
5560
+ analyticsPublicKey: analyticsPublicKeyCommand,
5296
5561
  now: Date.now,
5297
5562
  pause: (milliseconds) => new Promise((resolve5) => setTimeout(resolve5, milliseconds))
5298
5563
  };
@@ -5308,11 +5573,22 @@ async function setupDeployCommand(input, deps = defaults) {
5308
5573
  if (context.status !== "ok")
5309
5574
  return context;
5310
5575
  const task = context.task;
5311
- if (task.run?.runId !== config.runId || task.site?.siteId !== config.siteId || task.packages.siteplane !== config.packages.siteplane || task.packages.runtimeNext !== config.packages.runtimeNext || task.run.fieldContractHash !== config.fieldContractHash)
5576
+ if (task.run?.runId !== config.runId || task.site?.siteId !== config.siteId || task.packages.siteplane !== config.packages.siteplane || task.packages.analytics !== config.packages.analytics || task.packages.runtimeNext !== config.packages.runtimeNext || task.run.fieldContractHash !== config.fieldContractHash)
5312
5577
  fail2("setup_contract_conflict", "Local configuration and the current applied setup task must match before deployment.");
5313
5578
  if (!config.fieldContractHash)
5314
5579
  fail2("setup_apply_required", "Instrument the agreed content and run setup apply before deployment.");
5315
5580
  record = task.deployment;
5581
+ let analyticsPublicKey;
5582
+ if (task.modules.includes("analytics")) {
5583
+ try {
5584
+ analyticsPublicKey = await deps.analyticsPublicKey({
5585
+ config: { ...config, ...credentials },
5586
+ ...input.fetcher ? { fetchImpl: input.fetcher } : {}
5587
+ });
5588
+ } catch {
5589
+ fail2("analytics_public_key_unavailable", "Read Analytics setup readiness with the existing connection and run analytics init before retrying setup deploy. The Analytics public key could not be read.");
5590
+ }
5591
+ }
5316
5592
  const preflight = await deps.preflight(input);
5317
5593
  if (preflight.status !== "ready")
5318
5594
  return {
@@ -5352,12 +5628,12 @@ async function setupDeployCommand(input, deps = defaults) {
5352
5628
  remaining();
5353
5629
  return result;
5354
5630
  };
5355
- const domains = z33.object({
5356
- domains: z33.array(z33.object({
5357
- name: z33.string(),
5358
- verified: z33.boolean(),
5359
- redirect: z33.string().nullable().optional(),
5360
- gitBranch: z33.string().nullable().optional()
5631
+ const domains = z36.object({
5632
+ domains: z36.array(z36.object({
5633
+ name: z36.string(),
5634
+ verified: z36.boolean(),
5635
+ redirect: z36.string().nullable().optional(),
5636
+ gitBranch: z36.string().nullable().optional()
5361
5637
  }))
5362
5638
  }).parse(await api(`/v9/projects/${provider.projectId}/domains?${scope}`)).domains.filter((domain) => domain.verified && !domain.redirect && !domain.gitBranch);
5363
5639
  const origin = record?.origin ?? (domains.length === 1 ? `https://${domains[0].name}` : null);
@@ -5365,7 +5641,7 @@ async function setupDeployCommand(input, deps = defaults) {
5365
5641
  fail2("production_origin_ambiguous", "The linked project needs one verified canonical Production domain, or the existing setup domain must still belong to it.");
5366
5642
  if (record && (record.projectId !== provider.projectId || record.teamId !== provider.teamId))
5367
5643
  fail2("deployment_target_conflict", "This setup already belongs to a different provider project/team. Restore its original local link.");
5368
- const listEnv = async () => z33.object({ envs: z33.array(envSchema) }).parse(await api(`/v10/projects/${provider.projectId}/env?${scope}`)).envs;
5644
+ const listEnv = async () => z36.object({ envs: z36.array(envSchema) }).parse(await api(`/v10/projects/${provider.projectId}/env?${scope}`)).envs;
5369
5645
  let env = await listEnv();
5370
5646
  const owned = (key) => {
5371
5647
  const matches2 = env.filter((item) => item.key === key && item.target.includes("production"));
@@ -5403,7 +5679,11 @@ async function setupDeployCommand(input, deps = defaults) {
5403
5679
  SITEPLANE_SETUP_RUN_ID: config.runId,
5404
5680
  SITEPLANE_PORTAL_PATH: task.site.portalPath,
5405
5681
  SITEPLANE_BUILD_FIELD_CONTRACT_HASH: config.fieldContractHash,
5406
- SITEPLANE_BUILD_REVISION: revision
5682
+ SITEPLANE_BUILD_REVISION: revision,
5683
+ ...analyticsPublicKey ? {
5684
+ NEXT_PUBLIC_SITEPLANE_ANALYTICS_SITE_KEY: analyticsPublicKey,
5685
+ NEXT_PUBLIC_SITEPLANE_ANALYTICS_ENDPOINT: `${config.apiBaseUrl.replace(/\/$/u, "")}/api/analytics/collect`
5686
+ } : {}
5407
5687
  };
5408
5688
  const fingerprint = digest({
5409
5689
  publicBindings,
@@ -5434,9 +5714,9 @@ async function setupDeployCommand(input, deps = defaults) {
5434
5714
  expectedOperationId: record?.operationId ?? null,
5435
5715
  record: next
5436
5716
  });
5437
- const parsed = z33.object({
5438
- ok: z33.literal(true),
5439
- data: z33.object({ record: setupDeploymentRecordSchema }).strict()
5717
+ const parsed = z36.object({
5718
+ ok: z36.literal(true),
5719
+ data: z36.object({ record: setupDeploymentRecordSchema }).strict()
5440
5720
  }).strict().safeParse(result.payload);
5441
5721
  if (!result.ok || !parsed.success || stableJsonStringify(parsed.data.data.record) !== stableJsonStringify(next))
5442
5722
  fail2("deployment_record_unconfirmed", "The setup deployment record was not acknowledged. Reload context before continuing; no deployment is blindly repeated.");
@@ -5486,7 +5766,7 @@ async function setupDeployCommand(input, deps = defaults) {
5486
5766
  const item = owned(key);
5487
5767
  if (key === "SITEPLANE_ADMIN_SESSION_SECRET" && item && record.phase === "verified")
5488
5768
  continue;
5489
- const current = item ? z33.object({ key: z33.literal(key), value: z33.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`)).value : null;
5769
+ const current = item ? z36.object({ key: z36.literal(key), value: z36.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`)).value : null;
5490
5770
  if (current !== value)
5491
5771
  pending.push({
5492
5772
  key,
@@ -5511,7 +5791,7 @@ async function setupDeployCommand(input, deps = defaults) {
5511
5791
  const item = owned(key);
5512
5792
  if (!item)
5513
5793
  fail2("environment_write_unconfirmed", "A Siteplane Production binding was not persisted; retry the same configuration.");
5514
- const observed = z33.object({ key: z33.literal(key), value: z33.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`));
5794
+ const observed = z36.object({ key: z36.literal(key), value: z36.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`));
5515
5795
  if (observed.value !== value)
5516
5796
  fail2("environment_write_unconfirmed", "The provider readback does not match the authorized Siteplane value; no deployment was started.");
5517
5797
  }
@@ -5524,7 +5804,7 @@ async function setupDeployCommand(input, deps = defaults) {
5524
5804
  const detail = async (id) => deploymentSchema.parse(await api(`/v13/deployments/${encodeURIComponent(id)}?${scope}&withGitRepoInfo=true`));
5525
5805
  const matches = (deployment2) => deployment2.projectId === provider.projectId && deployment2.target === "production" && (!deployment2.ownerId || deployment2.ownerId === provider.teamId) && deployment2.createdAt >= Date.parse(record.environmentWrittenAt) && (deployment2.meta?.siteplaneOperationId === record.operationId || provider.git && (deployment2.gitSource?.sha ?? deployment2.meta?.githubCommitSha ?? deployment2.meta?.gitlabCommitSha ?? deployment2.meta?.bitbucketCommitSha ?? deployment2.meta?.gitCommitSha) === revision);
5526
5806
  const discover = async () => {
5527
- const result = z33.object({ deployments: z33.array(z33.object({ uid: z33.string() })) }).parse(await api(`/v6/deployments?${scope}&projectId=${provider.projectId}&target=production&since=${Date.parse(record.environmentWrittenAt)}&limit=100`));
5807
+ const result = z36.object({ deployments: z36.array(z36.object({ uid: z36.string() })) }).parse(await api(`/v6/deployments?${scope}&projectId=${provider.projectId}&target=production&since=${Date.parse(record.environmentWrittenAt)}&limit=100`));
5528
5808
  const candidates = [];
5529
5809
  for (const item of result.deployments) {
5530
5810
  const found = await detail(item.uid);
@@ -5656,7 +5936,7 @@ async function setupDeployCommand(input, deps = defaults) {
5656
5936
  ...logs.matchAll(/SITEPLANE_BUILD_PROOF=(\{[^\n]+\})/gu)
5657
5937
  ].map((match) => buildProofSchema.parse(JSON.parse(match[1])));
5658
5938
  const proof = markers.find((item) => item.revision === revision && item.fieldContractHash === config.fieldContractHash);
5659
- if (!proof || !/^22\.\d+\.\d+$/u.test(proof.node) || proof.siteplane !== config.packages.siteplane || proof.runtimeNext !== config.packages.runtimeNext || proof.lockfileHash !== `sha256:${local.lockfile.sha256}` || proof.next !== local.nextVersion || proof.react !== local.reactVersion || !(proof.packageManager === "npm" ? /^10\./u : /^(9|10)\./u).test(proof.packageManagerVersion) || local.packageManager.declared && `${proof.packageManager}@${proof.packageManagerVersion}` !== local.packageManager.declared)
5939
+ if (!proof || !/^22\.\d+\.\d+$/u.test(proof.node) || proof.siteplane !== config.packages.siteplane || proof.runtimeNext !== config.packages.runtimeNext || proof.analytics !== config.packages.analytics || proof.lockfileHash !== `sha256:${local.lockfile.sha256}` || proof.next !== local.nextVersion || proof.react !== local.reactVersion || !(proof.packageManager === "npm" ? /^10\./u : /^(9|10)\./u).test(proof.packageManagerVersion) || local.packageManager.declared && `${proof.packageManager}@${proof.packageManagerVersion}` !== local.packageManager.declared)
5660
5940
  fail2("provider_build_identity_missing", "The actual provider build did not prove the expected Node, package manager, lockfile, package pins and applied source. Inspect its install/build configuration.");
5661
5941
  const canonical = await detail(new URL(origin).hostname);
5662
5942
  if (canonical.id !== deployment.id)
@@ -5699,7 +5979,7 @@ async function setupDeployCommand(input, deps = defaults) {
5699
5979
 
5700
5980
  // src/bin/run-siteplane.ts
5701
5981
  async function runSiteplaneCli(args, dependencies = createDefaultDependencies()) {
5702
- const writes = args[0] === "init" || args[0] === "setup" && ["apply", "prepare", "deploy"].includes(args[1] ?? "");
5982
+ const writes = args[0] === "init" || args[0] === "analytics" && args[1] === "init" || args[0] === "setup" && ["apply", "prepare", "deploy"].includes(args[1] ?? "");
5703
5983
  const missingDeploy = args[0] === "setup" && args[1] === "deploy" && !await access6(join12(dependencies.cwd(), "siteplane.config.json")).then(
5704
5984
  () => true,
5705
5985
  () => false
@@ -5784,7 +6064,7 @@ async function runAnalyticsCommand(args, dependencies) {
5784
6064
  };
5785
6065
  const manifestPath = join12(projectDir, "siteplane.analytics.json");
5786
6066
  if (subcommand === "init") {
5787
- const rawPublicKey = await dependencies.commands.analyticsPublicKeyCommand({
6067
+ const { rawPublicKey } = await dependencies.commands.analyticsPrepareCommand({
5788
6068
  config
5789
6069
  });
5790
6070
  const siteKeyLookup = getAnalyticsKeyLookup(rawPublicKey);
@@ -6111,6 +6391,7 @@ function createDefaultDependencies() {
6111
6391
  analyticsImportCommand,
6112
6392
  analyticsInitCommand,
6113
6393
  analyticsPublicKeyCommand,
6394
+ analyticsPrepareCommand,
6114
6395
  analyticsReadinessCommand,
6115
6396
  analyticsSyncCommand,
6116
6397
  analyticsTestCommand,