siteplane 0.1.36 → 0.1.37

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.
@@ -11,7 +11,7 @@ import { dirname } from "path";
11
11
 
12
12
  // ../shared/dist/actors.js
13
13
  import { z } from "zod";
14
- var ACTOR_TYPES = ["developer", "client", "agent", "system"];
14
+ var ACTOR_TYPES = ["workspace_member", "site_member", "agent", "system"];
15
15
  var actorTypeSchema = z.enum(ACTOR_TYPES);
16
16
 
17
17
  // ../shared/dist/analytics-defaults.js
@@ -648,7 +648,7 @@ var bookingAvailabilityIntervalsSchema = z8.array(z8.object({
648
648
  });
649
649
  var bookingPublicConfigSchema = z8.object({
650
650
  site: z8.object({
651
- name: z8.string().trim().min(1),
651
+ displayName: z8.string().trim().min(1),
652
652
  timezone: z8.string().trim().min(1),
653
653
  locale: z8.string().trim().min(2),
654
654
  bookingPageSlug: z8.string().regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/).min(2).max(64),
@@ -1283,6 +1283,9 @@ var CONTINUE_SITE_SETUP_MAX_ITEMS = 50;
1283
1283
  var CONTINUE_SITE_SETUP_RENDERED_PATH_MAX_BYTES = 512;
1284
1284
  var CONTINUE_SITE_SETUP_VISIBLE_VALUE_MAX_BYTES = 256;
1285
1285
  var CONTINUE_SITE_SETUP_LOCATOR_HINT_MAX_BYTES = 512;
1286
+ var CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES = 120;
1287
+ var CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES = 120;
1288
+ var CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES = 120;
1286
1289
  var CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES = 32 * 1024;
1287
1290
  var CONTINUE_SITE_SETUP_HTTP_BODY_MAX_BYTES = 64 * 1024;
1288
1291
  var siteSetupRunStatusSchema = z14.enum(SITE_SETUP_RUN_STATUSES);
@@ -1291,6 +1294,7 @@ var siteSetupErrorCodeSchema = z14.enum(SITE_SETUP_ERROR_CODES);
1291
1294
  var editorFieldSchema = z14.object({
1292
1295
  fieldId: fieldIdSchema,
1293
1296
  label: z14.string().trim().min(1),
1297
+ subsection: z14.string().trim().min(1).optional(),
1294
1298
  description: z14.string().trim().min(1).optional(),
1295
1299
  required: z14.boolean().optional(),
1296
1300
  maxLength: z14.number().int().positive().optional()
@@ -1298,7 +1302,24 @@ var editorFieldSchema = z14.object({
1298
1302
  var editorSectionSchema = z14.object({
1299
1303
  label: z14.string().trim().min(1),
1300
1304
  fields: z14.array(editorFieldSchema).min(1)
1301
- }).strict();
1305
+ }).strict().superRefine((section, context) => {
1306
+ const closedSubsections = /* @__PURE__ */ new Set();
1307
+ let currentSubsection;
1308
+ for (const [index, field] of section.fields.entries()) {
1309
+ if (field.subsection === currentSubsection)
1310
+ continue;
1311
+ if (currentSubsection)
1312
+ closedSubsections.add(currentSubsection);
1313
+ currentSubsection = field.subsection;
1314
+ if (currentSubsection && closedSubsections.has(currentSubsection)) {
1315
+ context.addIssue({
1316
+ code: "custom",
1317
+ message: `Subgroup fields must stay contiguous: ${currentSubsection}`,
1318
+ path: ["fields", index, "subsection"]
1319
+ });
1320
+ }
1321
+ }
1322
+ });
1302
1323
  var editorRouteSchema = z14.object({
1303
1324
  routeKey: siteFieldRouteKeySchema,
1304
1325
  label: z14.string().trim().min(1),
@@ -1378,13 +1399,34 @@ function normalizedSafeTextSchema(maxBytes, label) {
1378
1399
  var correctionItemBase = {
1379
1400
  renderedPath: renderedPathSchema,
1380
1401
  visibleValue: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_VISIBLE_VALUE_MAX_BYTES, "visibleValue"),
1381
- locatorHint: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_LOCATOR_HINT_MAX_BYTES, "locatorHint")
1402
+ locatorHint: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_LOCATOR_HINT_MAX_BYTES, "locatorHint"),
1403
+ requestedLabel: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES, "requestedLabel").optional(),
1404
+ requestedSection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES, "requestedSection").optional(),
1405
+ requestedSubsection: normalizedSafeTextSchema(CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES, "requestedSubsection").optional(),
1406
+ requestedSortOrder: z14.number().int().nonnegative().optional()
1382
1407
  };
1383
1408
  var setupCorrectionItemSchema = z14.discriminatedUnion("kind", [
1384
1409
  z14.object({ kind: z14.literal("text"), ...correctionItemBase }).strict(),
1385
1410
  z14.object({ kind: z14.literal("link"), ...correctionItemBase }).strict(),
1386
1411
  z14.object({ kind: z14.literal("image"), ...correctionItemBase }).strict()
1387
- ]);
1412
+ ]).superRefine((item, context) => {
1413
+ if (item.requestedSubsection && !item.requestedSection) {
1414
+ context.addIssue({
1415
+ code: "custom",
1416
+ message: "requestedSubsection requires requestedSection.",
1417
+ path: ["requestedSubsection"]
1418
+ });
1419
+ }
1420
+ });
1421
+ var setupCorrectionItemsSchema = z14.array(setupCorrectionItemSchema).max(CONTINUE_SITE_SETUP_MAX_ITEMS).superRefine((items, context) => {
1422
+ const bytes = utf8Bytes(stableJsonStringify(items));
1423
+ if (bytes > CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES) {
1424
+ context.addIssue({
1425
+ code: "custom",
1426
+ message: "Correction items exceed the 32 KiB canonical payload limit."
1427
+ });
1428
+ }
1429
+ });
1388
1430
  var canonicalHashSchema = z14.string().regex(/^sha256:[0-9a-f]{64}$/iu);
1389
1431
  var deploymentRevisionSchema = normalizedSafeTextSchema(256, "deploymentRevision");
1390
1432
  var continueSiteSetupInputSchema = z14.object({
@@ -1392,17 +1434,8 @@ var continueSiteSetupInputSchema = z14.object({
1392
1434
  runId: z14.string().uuid(),
1393
1435
  expectedFieldContractHash: canonicalHashSchema,
1394
1436
  expectedDeploymentRevision: deploymentRevisionSchema,
1395
- correctionItems: z14.array(setupCorrectionItemSchema).max(CONTINUE_SITE_SETUP_MAX_ITEMS)
1396
- }).strict().superRefine((input, context) => {
1397
- const bytes = utf8Bytes(stableJsonStringify(input.correctionItems));
1398
- if (bytes > CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES) {
1399
- context.addIssue({
1400
- code: "custom",
1401
- message: "Correction items exceed the 32 KiB canonical payload limit.",
1402
- path: ["correctionItems"]
1403
- });
1404
- }
1405
- });
1437
+ correctionItems: setupCorrectionItemsSchema
1438
+ }).strict();
1406
1439
  var siteSetupContextInputSchema = z14.object({}).strict();
1407
1440
  var siteSetupApplyInputSchema = z14.object({
1408
1441
  fieldContract: siteFieldContractV1Schema,
@@ -1496,25 +1529,8 @@ var completeSiteSetupInputSchema = z14.object({
1496
1529
  runId: z14.string().uuid(),
1497
1530
  expectedFieldContractHash: canonicalHashSchema,
1498
1531
  expectedDeploymentRevision: deploymentRevisionSchema,
1499
- accessMode: z14.enum(["fallback", "custom_domain"]),
1500
- siteDomainId: z14.string().uuid().optional(),
1501
- defaultCanPublish: z14.boolean()
1502
- }).strict().superRefine((input, context) => {
1503
- if (input.accessMode === "fallback" && input.siteDomainId) {
1504
- context.addIssue({
1505
- code: "custom",
1506
- message: "Fallback access cannot use a custom domain.",
1507
- path: ["siteDomainId"]
1508
- });
1509
- }
1510
- if (input.accessMode === "custom_domain" && !input.siteDomainId) {
1511
- context.addIssue({
1512
- code: "custom",
1513
- message: "Custom-domain access requires a site domain.",
1514
- path: ["siteDomainId"]
1515
- });
1516
- }
1517
- });
1532
+ expectedReadyFingerprint: canonicalHashSchema
1533
+ }).strict();
1518
1534
  var refreshSiteSetupDeploymentInputSchema = z14.object({
1519
1535
  siteId: z14.string().uuid(),
1520
1536
  deploymentUrl: z14.string().url().refine((value) => value.startsWith("https://")),
@@ -1539,7 +1555,7 @@ function utf8Bytes(value) {
1539
1555
  }
1540
1556
 
1541
1557
  // ../shared/dist/bridge-protocol.js
1542
- var BRIDGE_PROTOCOL_VERSION = 1;
1558
+ var BRIDGE_PROTOCOL_VERSION = 2;
1543
1559
  var bridgeRectSchema = z15.object({
1544
1560
  x: z15.number(),
1545
1561
  y: z15.number(),
@@ -1566,6 +1582,12 @@ var bridgePreviewValueSchema = z15.discriminatedUnion("fieldType", [
1566
1582
  previewLinkValueSchema,
1567
1583
  previewImageValueSchema
1568
1584
  ]);
1585
+ var fieldSelectionModeSchema = z15.enum(["replace", "range", "toggle"]);
1586
+ var fieldBridgeMissingContentActionSchema = z15.enum([
1587
+ "add",
1588
+ "select",
1589
+ "remove"
1590
+ ]);
1569
1591
  var FIELD_BRIDGE_MESSAGE_TYPES = [
1570
1592
  "siteplane:field-bridge:init",
1571
1593
  "siteplane:field-bridge:ready",
@@ -1575,11 +1597,12 @@ var FIELD_BRIDGE_MESSAGE_TYPES = [
1575
1597
  "siteplane:field-bridge:apply-preview-values",
1576
1598
  "siteplane:field-bridge:test-preview-values",
1577
1599
  "siteplane:field-bridge:preview-ack",
1578
- "siteplane:field-bridge:set-editability-review",
1600
+ "siteplane:field-bridge:set-visual-control-state",
1579
1601
  "siteplane:field-bridge:missing-content",
1580
1602
  "siteplane:field-bridge:error"
1581
1603
  ];
1582
1604
  var canonicalFieldContractHashSchema = z15.string().regex(/^sha256:[0-9a-f]{64}$/u);
1605
+ var bridgeSectionSchema = z15.string().trim().min(1).max(256);
1583
1606
  var realRenderedPathSchema = z15.string().trim().refine((value) => value.startsWith("/") && value !== "$global" && !value.includes("?") && !value.includes("#"), "A field bridge rendered path must be a real canonical path.");
1584
1607
  var fieldBridgeIdentitySchema = z15.object({
1585
1608
  publicRuntimeKeyId: z15.string().uuid(),
@@ -1625,7 +1648,7 @@ var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
1625
1648
  z15.literal("field_selection"),
1626
1649
  z15.literal("preview_values"),
1627
1650
  z15.literal("field_evidence"),
1628
- z15.literal("editability_review")
1651
+ z15.literal("visual_field_control")
1629
1652
  ])
1630
1653
  }).strict()
1631
1654
  });
@@ -1638,14 +1661,33 @@ var fieldBridgeFieldsMessageSchema = fieldBridgeBaseSchema.extend({
1638
1661
  });
1639
1662
  var fieldBridgeSelectFieldMessageSchema = fieldBridgeBaseSchema.extend({
1640
1663
  type: z15.literal("siteplane:field-bridge:select-field"),
1641
- payload: z15.object({ fieldId: fieldIdSchema }).strict()
1664
+ payload: z15.object({
1665
+ fieldId: fieldIdSchema,
1666
+ selectionMode: fieldSelectionModeSchema
1667
+ }).strict()
1642
1668
  });
1643
1669
  var fieldBridgeSetSelectedFieldMessageSchema = fieldBridgeBaseSchema.extend({
1644
1670
  type: z15.literal("siteplane:field-bridge:set-selected-field"),
1645
1671
  payload: z15.object({
1646
- fieldId: fieldIdSchema.nullable(),
1672
+ fieldIds: z15.array(fieldIdSchema).max(200),
1673
+ primaryFieldId: fieldIdSchema.nullable(),
1647
1674
  scrollIntoView: z15.boolean().optional()
1648
- }).strict()
1675
+ }).strict().superRefine((value, context) => {
1676
+ if (value.fieldIds.length > 0 && value.primaryFieldId === null) {
1677
+ context.addIssue({
1678
+ code: "custom",
1679
+ message: "A non-empty selection needs a primary field.",
1680
+ path: ["primaryFieldId"]
1681
+ });
1682
+ }
1683
+ if (value.primaryFieldId !== null && !value.fieldIds.includes(value.primaryFieldId)) {
1684
+ context.addIssue({
1685
+ code: "custom",
1686
+ message: "The primary field must be part of the selection.",
1687
+ path: ["primaryFieldId"]
1688
+ });
1689
+ }
1690
+ })
1649
1691
  });
1650
1692
  var fieldBridgeApplyPreviewValuesMessageSchema = fieldBridgeBaseSchema.extend({
1651
1693
  type: z15.literal("siteplane:field-bridge:apply-preview-values"),
@@ -1664,13 +1706,28 @@ var fieldBridgePreviewAckMessageSchema = fieldBridgeBaseSchema.extend({
1664
1706
  fieldIds: z15.array(fieldIdSchema).max(200)
1665
1707
  }).strict()
1666
1708
  });
1667
- var fieldBridgeSetEditabilityReviewMessageSchema = fieldBridgeBaseSchema.extend({
1668
- type: z15.literal("siteplane:field-bridge:set-editability-review"),
1669
- payload: z15.object({ enabled: z15.boolean() }).strict()
1709
+ var fieldBridgeSetVisualControlStateMessageSchema = fieldBridgeBaseSchema.extend({
1710
+ type: z15.literal("siteplane:field-bridge:set-visual-control-state"),
1711
+ payload: z15.object({
1712
+ enabled: z15.boolean(),
1713
+ fieldProximityEnabled: z15.boolean(),
1714
+ pendingKeys: z15.array(z15.string().trim().min(1).max(2048)).max(50),
1715
+ activeFieldIds: z15.array(fieldIdSchema),
1716
+ fieldSections: z15.record(fieldIdSchema, bridgeSectionSchema),
1717
+ selectedPending: z15.array(z15.object({
1718
+ key: z15.string().trim().min(1).max(2048),
1719
+ locatorHint: z15.string().trim().min(1).max(2048)
1720
+ }).strict()).max(50),
1721
+ scrollPendingIntoView: z15.boolean().optional()
1722
+ }).strict()
1670
1723
  });
1671
1724
  var fieldBridgeMissingContentMessageSchema = fieldBridgeBaseSchema.extend({
1672
1725
  type: z15.literal("siteplane:field-bridge:missing-content"),
1673
- payload: z15.object({ item: setupCorrectionItemSchema }).strict()
1726
+ payload: z15.object({
1727
+ action: fieldBridgeMissingContentActionSchema,
1728
+ item: setupCorrectionItemSchema,
1729
+ suggestedSection: bridgeSectionSchema.optional()
1730
+ }).strict()
1674
1731
  });
1675
1732
  var fieldBridgeErrorMessageSchema = fieldBridgeBaseSchema.extend({
1676
1733
  type: z15.literal("siteplane:field-bridge:error"),
@@ -1689,7 +1746,7 @@ var fieldBridgeMessageSchema = z15.discriminatedUnion("type", [
1689
1746
  fieldBridgeApplyPreviewValuesMessageSchema,
1690
1747
  fieldBridgeTestPreviewValuesMessageSchema,
1691
1748
  fieldBridgePreviewAckMessageSchema,
1692
- fieldBridgeSetEditabilityReviewMessageSchema,
1749
+ fieldBridgeSetVisualControlStateMessageSchema,
1693
1750
  fieldBridgeMissingContentMessageSchema,
1694
1751
  fieldBridgeErrorMessageSchema
1695
1752
  ]);
@@ -1700,8 +1757,8 @@ import { z as z17 } from "zod";
1700
1757
  // ../shared/dist/errors.js
1701
1758
  import { z as z16 } from "zod";
1702
1759
  var UI_ERROR_CATEGORIES = [
1703
- "client",
1704
- "developer",
1760
+ "site_member",
1761
+ "workspace_member",
1705
1762
  "internal"
1706
1763
  ];
1707
1764
  var uiErrorCategorySchema = z16.enum(UI_ERROR_CATEGORIES);
@@ -1726,52 +1783,79 @@ var commandResultSchema = z17.discriminatedUnion("ok", [
1726
1783
  commandErrorSchema
1727
1784
  ]);
1728
1785
 
1729
- // ../shared/dist/fallback-portal.js
1786
+ // ../shared/dist/editor-settings.js
1730
1787
  import { z as z18 } from "zod";
1731
- var FALLBACK_PORTAL_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
1732
- var fallbackPortalSlugSchema = z18.string().regex(FALLBACK_PORTAL_SLUG_PATTERN, "Invalid fallback portal slug");
1788
+ var editorColorSchemeSchema = z18.enum([
1789
+ "paper",
1790
+ "slate",
1791
+ "siteplane",
1792
+ "bloom"
1793
+ ]);
1794
+ var editorColorSchemes = editorColorSchemeSchema.options;
1795
+ var editorColorModeSchema = z18.enum(["light", "dark"]);
1796
+ var editorColorModes = editorColorModeSchema.options;
1733
1797
 
1734
- // ../shared/dist/entitlements.js
1798
+ // ../shared/dist/site-slug.js
1735
1799
  import { z as z19 } from "zod";
1736
- var entitlementSnapshotSchema = z19.object({
1737
- planKey: z19.string().trim().min(1),
1738
- sitesLimit: z19.number().int().positive(),
1739
- clientAccountsPerSiteLimit: z19.number().int().positive(),
1740
- customAdminDomainsEnabled: z19.boolean(),
1741
- agentMcpEnabled: z19.boolean(),
1742
- emailNotificationsEnabled: z19.boolean(),
1743
- analyticsEnabled: z19.boolean(),
1744
- analyticsSitesLimit: z19.number().int().min(0),
1745
- analyticsClientPerformanceEnabled: z19.boolean(),
1746
- analyticsMonthlyReportsEnabled: z19.boolean(),
1747
- analyticsAiSummaryEnabled: z19.boolean(),
1748
- analyticsRawEventRetentionDays: z19.number().int().min(1).max(ANALYTICS_RETENTION_DEFAULTS.maxRawEventRetentionDaysWithoutAdr),
1749
- analyticsMonthlyEventLimit: z19.number().int().min(0),
1750
- bookingEnabled: z19.boolean().default(false),
1751
- bookingSitesLimit: z19.number().int().min(0).default(0),
1752
- bookingClientManagementEnabled: z19.boolean().default(false),
1753
- bookingResourcesPerSiteLimit: z19.number().int().min(0).default(0),
1754
- bookingServicesPerSiteLimit: z19.number().int().min(0).default(0),
1755
- bookingMonthlyBookingsLimit: z19.number().int().min(0).default(0),
1756
- bookingRemindersEnabled: z19.boolean().default(false)
1800
+ var SITE_SLUG_PATTERN = /^[a-z0-9]+(?:-[a-z0-9]+)*$/;
1801
+ var RESERVED_SITE_SLUGS = /* @__PURE__ */ new Set([
1802
+ "account",
1803
+ "admin",
1804
+ "api",
1805
+ "app",
1806
+ "auth",
1807
+ "book",
1808
+ "claim",
1809
+ "dev",
1810
+ "login",
1811
+ "new",
1812
+ "portal",
1813
+ "support",
1814
+ "workspace"
1815
+ ]);
1816
+ var siteSlugSchema = z19.string().regex(SITE_SLUG_PATTERN, "Invalid site slug").refine((value) => !RESERVED_SITE_SLUGS.has(value), "Reserved site slug");
1817
+
1818
+ // ../shared/dist/entitlements.js
1819
+ import { z as z20 } from "zod";
1820
+ var entitlementSnapshotSchema = z20.object({
1821
+ planKey: z20.string().trim().min(1),
1822
+ sitesLimit: z20.number().int().positive(),
1823
+ siteMembersPerSiteLimit: z20.number().int().positive(),
1824
+ customAdminDomainsEnabled: z20.boolean(),
1825
+ agentMcpEnabled: z20.boolean(),
1826
+ emailNotificationsEnabled: z20.boolean(),
1827
+ analyticsEnabled: z20.boolean(),
1828
+ analyticsSitesLimit: z20.number().int().min(0),
1829
+ analyticsPortalPerformanceEnabled: z20.boolean(),
1830
+ analyticsMonthlyReportsEnabled: z20.boolean(),
1831
+ analyticsAiSummaryEnabled: z20.boolean(),
1832
+ analyticsRawEventRetentionDays: z20.number().int().min(1).max(ANALYTICS_RETENTION_DEFAULTS.maxRawEventRetentionDaysWithoutAdr),
1833
+ analyticsMonthlyEventLimit: z20.number().int().min(0),
1834
+ bookingEnabled: z20.boolean().default(false),
1835
+ bookingSitesLimit: z20.number().int().min(0).default(0),
1836
+ bookingPortalManagementEnabled: z20.boolean().default(false),
1837
+ bookingResourcesPerSiteLimit: z20.number().int().min(0).default(0),
1838
+ bookingServicesPerSiteLimit: z20.number().int().min(0).default(0),
1839
+ bookingMonthlyBookingsLimit: z20.number().int().min(0).default(0),
1840
+ bookingRemindersEnabled: z20.boolean().default(false)
1757
1841
  });
1758
1842
  var EARLY_ACCESS_PLAN = {
1759
1843
  planKey: "early_access_2026",
1760
1844
  sitesLimit: 3,
1761
- clientAccountsPerSiteLimit: 5,
1845
+ siteMembersPerSiteLimit: 5,
1762
1846
  customAdminDomainsEnabled: true,
1763
1847
  agentMcpEnabled: true,
1764
1848
  emailNotificationsEnabled: true,
1765
1849
  analyticsEnabled: false,
1766
1850
  analyticsSitesLimit: 0,
1767
- analyticsClientPerformanceEnabled: false,
1851
+ analyticsPortalPerformanceEnabled: false,
1768
1852
  analyticsMonthlyReportsEnabled: false,
1769
1853
  analyticsAiSummaryEnabled: false,
1770
1854
  analyticsRawEventRetentionDays: ANALYTICS_RETENTION_DEFAULTS.enabledRawEventRetentionDays,
1771
1855
  analyticsMonthlyEventLimit: 0,
1772
1856
  bookingEnabled: true,
1773
1857
  bookingSitesLimit: 3,
1774
- bookingClientManagementEnabled: true,
1858
+ bookingPortalManagementEnabled: true,
1775
1859
  bookingResourcesPerSiteLimit: 10,
1776
1860
  bookingServicesPerSiteLimit: 50,
1777
1861
  bookingMonthlyBookingsLimit: 0,
@@ -1779,7 +1863,7 @@ var EARLY_ACCESS_PLAN = {
1779
1863
  };
1780
1864
 
1781
1865
  // ../shared/dist/readiness.js
1782
- import { z as z20 } from "zod";
1866
+ import { z as z21 } from "zod";
1783
1867
  var READINESS_CHECK_KEYS = [
1784
1868
  "agent_instructions_installed",
1785
1869
  "runtime_package_connected",
@@ -1794,19 +1878,19 @@ var READINESS_STATUSES = [
1794
1878
  "failing",
1795
1879
  "warning"
1796
1880
  ];
1797
- var readinessCheckKeySchema = z20.enum(READINESS_CHECK_KEYS);
1798
- var readinessStatusSchema = z20.enum(READINESS_STATUSES);
1881
+ var readinessCheckKeySchema = z21.enum(READINESS_CHECK_KEYS);
1882
+ var readinessStatusSchema = z21.enum(READINESS_STATUSES);
1799
1883
 
1800
1884
  // ../shared/dist/site.js
1801
- import { z as z21 } from "zod";
1885
+ import { z as z22 } from "zod";
1802
1886
  var SITE_STATUSES = [
1803
1887
  "setup",
1804
- "client_ready",
1888
+ "active",
1805
1889
  "disabled",
1806
1890
  "archived"
1807
1891
  ];
1808
- var siteStatusSchema = z21.enum(SITE_STATUSES);
1809
- var websiteUrlSchema = z21.string().trim().url().refine((value) => value.startsWith("https://") || value.startsWith("http://"), "Website URL must use http or https");
1892
+ var siteStatusSchema = z22.enum(SITE_STATUSES);
1893
+ var websiteUrlSchema = z22.string().trim().url().refine((value) => value.startsWith("https://") || value.startsWith("http://"), "Website URL must use http or https");
1810
1894
 
1811
1895
  // ../cli/dist/analytics/manifest.js
1812
1896
  async function readAnalyticsManifestFile(manifestPath) {
@@ -2611,16 +2695,16 @@ async function analyticsReadinessCommand(input) {
2611
2695
  }
2612
2696
 
2613
2697
  // ../cli/dist/commands/analytics/public-key.js
2614
- import { z as z22 } from "zod";
2615
- var responseSchema = z22.object({
2616
- ok: z22.literal(true),
2617
- data: z22.object({
2618
- rawPublicKey: z22.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
2698
+ import { z as z23 } from "zod";
2699
+ var responseSchema = z23.object({
2700
+ ok: z23.literal(true),
2701
+ data: z23.object({
2702
+ rawPublicKey: z23.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
2619
2703
  })
2620
2704
  });
2621
- var errorResponseSchema = z22.object({
2622
- error: z22.object({
2623
- code: z22.string().regex(/^[a-z][a-z0-9_.-]+$/u)
2705
+ var errorResponseSchema = z23.object({
2706
+ error: z23.object({
2707
+ code: z23.string().regex(/^[a-z][a-z0-9_.-]+$/u)
2624
2708
  })
2625
2709
  });
2626
2710
  async function analyticsPublicKeyCommand(input) {
@@ -2836,18 +2920,22 @@ async function bookingTestCommand(input) {
2836
2920
  });
2837
2921
  }
2838
2922
 
2923
+ // ../cli/dist/commands/connect.js
2924
+ import { randomBytes } from "crypto";
2925
+ import { z as z27 } from "zod";
2926
+
2839
2927
  // ../cli/dist/config/project-config.js
2840
2928
  import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
2841
2929
  import { randomUUID as randomUUID2 } from "crypto";
2842
2930
  import { join as join3 } from "path";
2843
- import { z as z23 } from "zod";
2844
- var siteplaneProjectConfigSchema = z23.object({
2845
- version: z23.literal(1),
2846
- apiBaseUrl: z23.string().url(),
2847
- siteId: z23.string().uuid(),
2848
- publicSiteKeyId: z23.string().uuid(),
2849
- publicSiteKey: z23.string().trim().min(1),
2850
- fieldContractHash: z23.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
2931
+ import { z as z24 } from "zod";
2932
+ var siteplaneProjectConfigSchema = z24.object({
2933
+ version: z24.literal(1),
2934
+ apiBaseUrl: z24.string().url(),
2935
+ siteId: z24.string().uuid(),
2936
+ publicSiteKeyId: z24.string().uuid(),
2937
+ publicSiteKey: z24.string().trim().min(1),
2938
+ fieldContractHash: z24.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
2851
2939
  }).strict();
2852
2940
  async function readProjectPackageJson(projectDir) {
2853
2941
  return JSON.parse(await readFile5(join3(projectDir, "package.json"), "utf8"));
@@ -2907,10 +2995,10 @@ import { randomUUID as randomUUID3 } from "crypto";
2907
2995
  import { chmod as chmod2, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
2908
2996
  import { dirname as dirname5, join as join4, relative } from "path";
2909
2997
  import { promisify } from "util";
2910
- import { z as z24 } from "zod";
2911
- var siteplaneCredentialsSchema = z24.object({
2912
- accessToken: z24.string().trim().min(1),
2913
- siteRevalidationSecret: z24.string().trim().min(1)
2998
+ import { z as z25 } from "zod";
2999
+ var siteplaneCredentialsSchema = z25.object({
3000
+ accessToken: z25.string().trim().min(1),
3001
+ siteRevalidationSecret: z25.string().trim().min(1)
2914
3002
  }).strict();
2915
3003
  async function writeLocalCredentials(projectDir, credentials, options = {}) {
2916
3004
  const path = join4(projectDir, ".siteplane/credentials.json");
@@ -2964,7 +3052,7 @@ async function gitPathMatches(projectDir, path, command) {
2964
3052
 
2965
3053
  // ../cli/dist/commands/init.js
2966
3054
  import { join as join5 } from "path";
2967
- import { z as z25 } from "zod";
3055
+ import { z as z26 } from "zod";
2968
3056
  async function initCommand(input) {
2969
3057
  if (!input.setupToken.trim()) {
2970
3058
  throw new Error("A Siteplane setup token is required.");
@@ -2984,24 +3072,24 @@ async function initCommand(input) {
2984
3072
  ]
2985
3073
  };
2986
3074
  }
2987
- var siteSetupBootstrapDataSchema = z25.object({
2988
- credentialPurpose: z25.literal("site_setup"),
2989
- apiBaseUrl: z25.string().url(),
2990
- siteId: z25.string().uuid(),
2991
- publicSiteKeyId: z25.string().uuid(),
2992
- publicSiteKey: z25.string().trim().min(1),
2993
- accessToken: z25.string().trim().min(1),
2994
- siteRevalidationSecret: z25.string().regex(/^[A-Za-z0-9_-]{43}$/u)
3075
+ var siteSetupBootstrapDataSchema = z26.object({
3076
+ credentialPurpose: z26.literal("site_setup"),
3077
+ apiBaseUrl: z26.string().url(),
3078
+ siteId: z26.string().uuid(),
3079
+ publicSiteKeyId: z26.string().uuid(),
3080
+ publicSiteKey: z26.string().trim().min(1),
3081
+ accessToken: z26.string().trim().min(1),
3082
+ siteRevalidationSecret: z26.string().regex(/^[A-Za-z0-9_-]{43}$/u)
2995
3083
  }).strict();
2996
- var featureBootstrapDataSchema = z25.object({
2997
- credentialPurpose: z25.enum(["analytics", "booking"]),
2998
- apiBaseUrl: z25.string().url(),
2999
- siteId: z25.string().uuid(),
3000
- accessToken: z25.string().trim().min(1)
3084
+ var featureBootstrapDataSchema = z26.object({
3085
+ credentialPurpose: z26.enum(["analytics", "booking"]),
3086
+ apiBaseUrl: z26.string().url(),
3087
+ siteId: z26.string().uuid(),
3088
+ accessToken: z26.string().trim().min(1)
3001
3089
  }).strict();
3002
- var bootstrapResponseSchema = z25.object({
3003
- ok: z25.literal(true),
3004
- data: z25.discriminatedUnion("credentialPurpose", [
3090
+ var bootstrapResponseSchema = z26.object({
3091
+ ok: z26.literal(true),
3092
+ data: z26.discriminatedUnion("credentialPurpose", [
3005
3093
  siteSetupBootstrapDataSchema,
3006
3094
  featureBootstrapDataSchema
3007
3095
  ])
@@ -3099,6 +3187,122 @@ function readErrorMessage(payload) {
3099
3187
  return null;
3100
3188
  }
3101
3189
 
3190
+ // ../cli/dist/commands/connect.js
3191
+ var claimResponseSchema = z27.object({
3192
+ ok: z27.literal(true),
3193
+ data: z27.object({
3194
+ pairingId: z27.string().uuid(),
3195
+ status: z27.literal("approval_required")
3196
+ }).passthrough()
3197
+ }).strict();
3198
+ var waitingResponseSchema = z27.object({
3199
+ ok: z27.literal(true),
3200
+ data: z27.object({ status: z27.literal("approval_required") }).strict()
3201
+ }).strict();
3202
+ var bootstrapResponseSchema2 = z27.object({
3203
+ ok: z27.literal(true),
3204
+ data: siteSetupBootstrapDataSchema
3205
+ }).strict();
3206
+ async function connectCommand(input) {
3207
+ if (!await detectNextProject(input.projectDir)) {
3208
+ throw new Error("Siteplane connect currently supports Next.js projects.");
3209
+ }
3210
+ const fetcher = input.fetcher ?? fetch;
3211
+ const pollSecret = randomBytes(32).toString("base64url");
3212
+ const envelopeKey = randomBytes(32).toString("base64url");
3213
+ const endpoint = `${input.apiBaseUrl.replace(/\/$/, "")}/api/cli/connect`;
3214
+ const headers = createHeaders(input);
3215
+ const claimResponse = await fetcher(endpoint, {
3216
+ method: "POST",
3217
+ headers,
3218
+ body: JSON.stringify({
3219
+ action: "claim",
3220
+ pairingCode: input.pairingCode.trim().toUpperCase(),
3221
+ pollSecret,
3222
+ envelopeKey,
3223
+ agentLabel: input.agentLabel?.trim() || null
3224
+ })
3225
+ });
3226
+ const claimPayload = await readJson(claimResponse);
3227
+ const claim = claimResponseSchema.safeParse(claimPayload);
3228
+ if (!claimResponse.ok || !claim.success) {
3229
+ throw new Error(readErrorMessage2(claimPayload) ?? "Siteplane pairing failed.");
3230
+ }
3231
+ const wait = input.wait ?? ((milliseconds) => new Promise((resolve2) => setTimeout(resolve2, milliseconds)));
3232
+ let bootstrap = null;
3233
+ for (; ; ) {
3234
+ const pollResponse = await fetcher(endpoint, {
3235
+ method: "POST",
3236
+ headers,
3237
+ body: JSON.stringify({
3238
+ action: "poll",
3239
+ pairingId: claim.data.data.pairingId,
3240
+ pollSecret,
3241
+ envelopeKey
3242
+ })
3243
+ });
3244
+ const pollPayload = await readJson(pollResponse);
3245
+ const ready = bootstrapResponseSchema2.safeParse(pollPayload);
3246
+ if (pollResponse.ok && ready.success) {
3247
+ bootstrap = ready.data.data;
3248
+ break;
3249
+ }
3250
+ if (pollResponse.status !== 202 || !waitingResponseSchema.safeParse(pollPayload).success) {
3251
+ throw new Error(readErrorMessage2(pollPayload) ?? "Siteplane pairing was not approved.");
3252
+ }
3253
+ await wait(1500);
3254
+ }
3255
+ const paths = await persistSiteSetupBootstrap({
3256
+ projectDir: input.projectDir,
3257
+ setupToken: "pairing",
3258
+ apiBaseUrl: input.apiBaseUrl,
3259
+ ...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
3260
+ ...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
3261
+ }, bootstrap);
3262
+ const acknowledgement = await fetcher(endpoint, {
3263
+ method: "POST",
3264
+ headers,
3265
+ body: JSON.stringify({
3266
+ action: "acknowledge",
3267
+ pairingId: claim.data.data.pairingId,
3268
+ pollSecret,
3269
+ envelopeKey
3270
+ })
3271
+ });
3272
+ if (!acknowledgement.ok) {
3273
+ throw new Error("Siteplane setup acknowledgement failed.");
3274
+ }
3275
+ return {
3276
+ ...paths,
3277
+ nextSteps: [
3278
+ "npx siteplane setup context",
3279
+ "Instrument the site and create EditorDefinitionV1.",
3280
+ "npx siteplane setup apply --definition /tmp/siteplane-editor.json"
3281
+ ]
3282
+ };
3283
+ }
3284
+ function createHeaders(input) {
3285
+ return new Headers({
3286
+ "content-type": "application/json",
3287
+ ...input.vercelAutomationBypassSecret?.trim() ? { "x-vercel-protection-bypass": input.vercelAutomationBypassSecret.trim() } : {}
3288
+ });
3289
+ }
3290
+ async function readJson(response) {
3291
+ try {
3292
+ return await response.json();
3293
+ } catch {
3294
+ return null;
3295
+ }
3296
+ }
3297
+ function readErrorMessage2(payload) {
3298
+ if (!payload || typeof payload !== "object" || !("error" in payload))
3299
+ return null;
3300
+ const error = payload.error;
3301
+ if (!error || typeof error !== "object" || !("message" in error))
3302
+ return null;
3303
+ return typeof error.message === "string" ? error.message : null;
3304
+ }
3305
+
3102
3306
  // ../cli/dist/commands/scan.js
3103
3307
  import { readdir } from "fs/promises";
3104
3308
  import { extname, join as join6 } from "path";
@@ -3144,7 +3348,7 @@ async function collectSourceFiles(directory) {
3144
3348
  import { execFile as execFile2 } from "child_process";
3145
3349
  import { readFile as readFile7 } from "fs/promises";
3146
3350
  import { promisify as promisify2 } from "util";
3147
- import { z as z26 } from "zod";
3351
+ import { z as z28 } from "zod";
3148
3352
 
3149
3353
  // ../cli/dist/scan/next-source-scan.js
3150
3354
  import ts2 from "typescript";
@@ -3811,49 +4015,52 @@ function isPositionalFieldReference(value) {
3811
4015
 
3812
4016
  // ../cli/dist/commands/site-setup.js
3813
4017
  var execFileAsync2 = promisify2(execFile2);
3814
- var safeErrorSchema = z26.object({
3815
- code: z26.string().trim().min(1),
3816
- message: z26.string().trim().min(1)
4018
+ var safeErrorSchema = z28.object({
4019
+ code: z28.string().trim().min(1),
4020
+ message: z28.string().trim().min(1)
3817
4021
  }).passthrough();
3818
- var errorResponseSchema2 = z26.object({ ok: z26.literal(false), error: safeErrorSchema }).passthrough();
3819
- var contextDataSchema = z26.object({
3820
- site: z26.object({ siteId: z26.string().uuid(), websiteUrl: z26.string().url() }),
3821
- run: z26.object({
3822
- runId: z26.string().uuid(),
3823
- mode: z26.enum(["initial", "update"]),
3824
- status: z26.enum([
4022
+ var errorResponseSchema2 = z28.object({ ok: z28.literal(false), error: safeErrorSchema }).passthrough();
4023
+ var contextDataSchema = z28.object({
4024
+ site: z28.object({ siteId: z28.string().uuid(), websiteUrl: z28.string().url(), portalPath: z28.string() }),
4025
+ run: z28.object({
4026
+ runId: z28.string().uuid(),
4027
+ mode: z28.enum(["initial", "update"]),
4028
+ status: z28.enum([
3825
4029
  "waiting_for_agent",
3826
4030
  "working",
3827
4031
  "action_required",
3828
4032
  "ready_for_review"
3829
4033
  ]),
3830
- fieldContractHash: z26.string().nullable(),
3831
- deploymentOrigin: z26.string().nullable(),
3832
- deploymentRevision: z26.string().nullable(),
3833
- errorCode: z26.string().nullable(),
3834
- errorMessage: z26.string().nullable()
4034
+ fieldContractHash: z28.string().nullable(),
4035
+ deploymentOrigin: z28.string().nullable(),
4036
+ deploymentRevision: z28.string().nullable(),
4037
+ errorCode: z28.string().nullable(),
4038
+ errorMessage: z28.string().nullable()
3835
4039
  }),
3836
- allowedTasks: z26.array(z26.string()),
3837
- requiredEnvironmentNames: z26.array(z26.string())
4040
+ structureHandoff: z28.object({
4041
+ pendingFields: z28.array(setupCorrectionItemSchema).min(1).max(50)
4042
+ }).strict().nullable(),
4043
+ allowedTasks: z28.array(z28.string()),
4044
+ requiredEnvironmentNames: z28.array(z28.string())
3838
4045
  }).strict();
3839
- var contextResponseSchema = z26.object({ ok: z26.literal(true), data: contextDataSchema }).strict();
3840
- var applyDataSchema = z26.object({
3841
- status: z26.enum(["applied", "ready_for_review"]),
3842
- runId: z26.string().uuid().optional(),
3843
- contractVersionId: z26.string().uuid().optional(),
3844
- fieldContractHash: z26.string().regex(/^sha256:[0-9a-f]{64}$/u),
3845
- editorDefinitionHash: z26.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
3846
- fieldCount: z26.number().int().nonnegative().optional(),
3847
- routeCount: z26.number().int().nonnegative().optional()
4046
+ var contextResponseSchema = z28.object({ ok: z28.literal(true), data: contextDataSchema }).strict();
4047
+ var applyDataSchema = z28.object({
4048
+ status: z28.enum(["applied", "ready_for_review"]),
4049
+ runId: z28.string().uuid().optional(),
4050
+ contractVersionId: z28.string().uuid().optional(),
4051
+ fieldContractHash: z28.string().regex(/^sha256:[0-9a-f]{64}$/u),
4052
+ editorDefinitionHash: z28.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
4053
+ fieldCount: z28.number().int().nonnegative().optional(),
4054
+ routeCount: z28.number().int().nonnegative().optional()
3848
4055
  }).strict();
3849
- var applyResponseSchema = z26.object({ ok: z26.literal(true), data: applyDataSchema }).strict();
3850
- var verifyDataSchema = z26.object({
3851
- status: z26.literal("ready_for_review"),
3852
- runId: z26.string().uuid().optional(),
3853
- deploymentOrigin: z26.string().url().optional(),
3854
- deploymentRevision: z26.string().optional()
4056
+ var applyResponseSchema = z28.object({ ok: z28.literal(true), data: applyDataSchema }).strict();
4057
+ var verifyDataSchema = z28.object({
4058
+ status: z28.literal("ready_for_review"),
4059
+ runId: z28.string().uuid().optional(),
4060
+ deploymentOrigin: z28.string().url().optional(),
4061
+ deploymentRevision: z28.string().optional()
3855
4062
  }).strict();
3856
- var verifyResponseSchema = z26.object({ ok: z26.literal(true), data: verifyDataSchema }).strict();
4063
+ var verifyResponseSchema = z28.object({ ok: z28.literal(true), data: verifyDataSchema }).strict();
3857
4064
  async function siteSetupContextCommand(input) {
3858
4065
  const response = await postSiteSetup(input, "context", {});
3859
4066
  const parsed = contextResponseSchema.safeParse(response.payload);
@@ -3963,24 +4170,26 @@ async function readGitRevision(projectDir) {
3963
4170
  // src/bin/run-siteplane.ts
3964
4171
  async function runSiteplaneCli(args, dependencies = createDefaultDependencies()) {
3965
4172
  const [command, ...commandArgs] = args;
3966
- if (command === "init") {
3967
- const setupToken = readOption(commandArgs, "--setup-token");
3968
- const apiBaseUrl = readOption(commandArgs, "--api-base-url") ?? dependencies.env.SITEPLANE_API_BASE_URL ?? "https://app.siteplane.io";
3969
- if (!setupToken) {
3970
- throw new Error("Missing --setup-token.");
4173
+ if (command === "connect") {
4174
+ const pairingCode = commandArgs[0];
4175
+ if (pairingCode === "--help" || pairingCode === "-h") {
4176
+ dependencies.stdout("Usage: siteplane connect <pairing-code>");
4177
+ return { exitCode: 0 };
3971
4178
  }
3972
- const result = await dependencies.commands.initCommand({
4179
+ const apiBaseUrl = readOption(commandArgs, "--api-base-url") ?? dependencies.env.SITEPLANE_API_BASE_URL ?? "https://siteplane.io";
4180
+ if (!pairingCode || pairingCode.startsWith("--")) {
4181
+ throw new Error("Usage: siteplane connect <pairing-code>");
4182
+ }
4183
+ const result = await dependencies.commands.connectCommand({
3973
4184
  projectDir: dependencies.cwd(),
3974
- setupToken,
4185
+ pairingCode,
3975
4186
  apiBaseUrl,
3976
4187
  ...readOptionalVercelAutomationBypassSecret(dependencies.env)
3977
4188
  });
3978
4189
  dependencies.stdout(`Wrote ${result.configPath}`);
3979
4190
  dependencies.stdout(`Wrote ${result.credentialsPath}`);
3980
- dependencies.stdout("Next steps:");
3981
- for (const nextStep of result.nextSteps) {
3982
- dependencies.stdout(`- ${nextStep}`);
3983
- }
4191
+ dependencies.stdout("Siteplane connected. Next steps:");
4192
+ for (const nextStep of result.nextSteps) dependencies.stdout(`- ${nextStep}`);
3984
4193
  return { exitCode: 0 };
3985
4194
  }
3986
4195
  if (command === "booking") {
@@ -3997,10 +4206,10 @@ async function runSiteplaneCli(args, dependencies = createDefaultDependencies())
3997
4206
  return { exitCode: 0 };
3998
4207
  }
3999
4208
  if (command === "--help" || command === "-h") {
4000
- dependencies.stdout("Usage: siteplane <init|setup|analytics|booking>");
4209
+ dependencies.stdout("Usage: siteplane <connect|setup|analytics|booking>");
4001
4210
  return { exitCode: 0 };
4002
4211
  }
4003
- dependencies.stdout("Usage: siteplane <init|setup|analytics|booking>");
4212
+ dependencies.stdout("Usage: siteplane <connect|setup|analytics|booking>");
4004
4213
  return { exitCode: 1 };
4005
4214
  }
4006
4215
  async function runAnalyticsCommand(args, dependencies) {
@@ -4012,6 +4221,17 @@ async function runAnalyticsCommand(args, dependencies) {
4012
4221
  );
4013
4222
  return { exitCode: subcommand ? 0 : 1 };
4014
4223
  }
4224
+ if (subcommand === "init") {
4225
+ const setupToken = readOption(subcommandArgs, "--setup-token");
4226
+ if (setupToken) {
4227
+ await dependencies.commands.initCommand({
4228
+ projectDir,
4229
+ setupToken,
4230
+ apiBaseUrl: readOption(subcommandArgs, "--api-base-url") ?? dependencies.env.SITEPLANE_API_BASE_URL ?? "https://siteplane.io",
4231
+ ...readOptionalVercelAutomationBypassSecret(dependencies.env)
4232
+ });
4233
+ }
4234
+ }
4015
4235
  const [projectConfig, credentials] = await Promise.all([
4016
4236
  dependencies.commands.readProjectConfig(projectDir),
4017
4237
  dependencies.commands.readLocalCredentials(projectDir)
@@ -4286,6 +4506,7 @@ function createDefaultDependencies() {
4286
4506
  siteSetupApplyCommand,
4287
4507
  siteSetupContextCommand,
4288
4508
  siteSetupVerifyCommand,
4509
+ connectCommand,
4289
4510
  initCommand,
4290
4511
  bookingInitCommand,
4291
4512
  bookingCheckCommand,