siteplane 0.1.51 → 0.1.53

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.
@@ -1934,6 +1934,18 @@ var fieldBridgeIdentitySchema = z17.object({
1934
1934
  fieldContractHash: canonicalFieldContractHashSchema,
1935
1935
  deploymentRevision: z17.string().trim().min(1).max(256)
1936
1936
  }).strict();
1937
+ var setupPreviewAccessSchema = z17.object({
1938
+ capability: z17.string().regex(/^v1\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]{43}$/u).max(4096),
1939
+ expiresAt: z17.string().datetime()
1940
+ }).strict();
1941
+ var setupPreviewReadSchema = fieldBridgeIdentitySchema.extend({
1942
+ scope: z17.literal("setup_preview"),
1943
+ siteId: z17.string().uuid(),
1944
+ runId: z17.string().uuid(),
1945
+ bridgeSessionId: z17.string().min(1),
1946
+ expiresAt: z17.string().datetime(),
1947
+ contract: siteFieldContractV1Schema
1948
+ }).strict();
1937
1949
  var fieldBridgeBaseSchema = z17.object({
1938
1950
  version: z17.literal(BRIDGE_PROTOCOL_VERSION),
1939
1951
  type: z17.enum(FIELD_BRIDGE_MESSAGE_TYPES),
@@ -1961,7 +1973,8 @@ var fieldBridgeInitMessageSchema = fieldBridgeBaseSchema.extend({
1961
1973
  payload: z17.object({
1962
1974
  adminOrigin: z17.string().url(),
1963
1975
  customerOrigin: z17.string().url(),
1964
- renderedPath: realRenderedPathSchema
1976
+ renderedPath: realRenderedPathSchema,
1977
+ setupPreview: setupPreviewAccessSchema.optional()
1965
1978
  }).strict()
1966
1979
  });
1967
1980
  var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
@@ -1974,7 +1987,7 @@ var fieldBridgeReadyMessageSchema = fieldBridgeBaseSchema.extend({
1974
1987
  z17.literal("preview_values"),
1975
1988
  z17.literal("field_evidence"),
1976
1989
  z17.literal("visual_field_control")
1977
- ]).rest(z17.literal("analytics_preview_readiness")).refine((capabilities) => capabilities.length <= 5)
1990
+ ]).rest(z17.enum(["analytics_preview_readiness", "setup_preview"])).refine((capabilities) => capabilities.length <= 6)
1978
1991
  }).strict()
1979
1992
  });
1980
1993
  var fieldBridgeFieldsMessageSchema = fieldBridgeBaseSchema.extend({
@@ -2317,6 +2330,47 @@ var setupInstallationRequestSchema = z26.object({
2317
2330
  }).strict()
2318
2331
  }).strict();
2319
2332
 
2333
+ // ../shared/dist/setup-claim.js
2334
+ import { z as z27 } from "zod";
2335
+ var setupClaimCodeSchema = z27.string().regex(/^[0-9A-HJKMNP-TV-Z]{8}$/u);
2336
+ var setupClaimBindingSchema = z27.object({
2337
+ siteId: z27.string().uuid(),
2338
+ runId: z27.string().uuid()
2339
+ });
2340
+ var setupClaimReceiptSchema = setupClaimBindingSchema.extend({
2341
+ status: z27.literal("claimed"),
2342
+ requestId: z27.string().uuid(),
2343
+ workspaceId: z27.string().uuid(),
2344
+ userId: z27.string().uuid(),
2345
+ claimedAt: z27.string().datetime({ offset: true })
2346
+ }).strict();
2347
+ var setupClaimInspectionSchema = setupClaimBindingSchema.extend({
2348
+ status: z27.literal("pending"),
2349
+ requestId: z27.string().uuid(),
2350
+ siteName: z27.string(),
2351
+ userId: z27.string().uuid(),
2352
+ accountEmail: z27.string().email(),
2353
+ workspaceId: z27.string().uuid(),
2354
+ workspaceName: z27.string(),
2355
+ expiresAt: z27.string().datetime({ offset: true })
2356
+ }).strict();
2357
+ var setupClaimDenialSchema = z27.object({
2358
+ status: z27.enum([
2359
+ "invalid_claim_request",
2360
+ "invalid_installation",
2361
+ "already_claimed",
2362
+ "project_expired",
2363
+ "invalid_guest_session",
2364
+ "stale_setup_review",
2365
+ "verified_account_required",
2366
+ "workspace_access_denied",
2367
+ "workspace_entitlement_required",
2368
+ "site_limit_reached",
2369
+ "provisional_relationship_conflict",
2370
+ "rate_limited"
2371
+ ])
2372
+ }).strict();
2373
+
2320
2374
  // ../cli/dist/analytics/manifest.js
2321
2375
  async function readAnalyticsManifestFile(manifestPath) {
2322
2376
  return validateAnalyticsManifestInput(JSON.parse(await readFile(manifestPath, "utf8")));
@@ -3141,16 +3195,16 @@ async function analyticsReadinessCommand(input) {
3141
3195
  }
3142
3196
 
3143
3197
  // ../cli/dist/commands/analytics/public-key.js
3144
- import { z as z27 } from "zod";
3145
- var responseSchema = z27.object({
3146
- ok: z27.literal(true),
3147
- data: z27.object({
3148
- rawPublicKey: z27.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
3198
+ import { z as z28 } from "zod";
3199
+ var responseSchema = z28.object({
3200
+ ok: z28.literal(true),
3201
+ data: z28.object({
3202
+ rawPublicKey: z28.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/)
3149
3203
  })
3150
3204
  });
3151
- var errorResponseSchema = z27.object({
3152
- error: z27.object({
3153
- code: z27.string().regex(/^[a-z][a-z0-9_.-]+$/u)
3205
+ var errorResponseSchema = z28.object({
3206
+ error: z28.object({
3207
+ code: z28.string().regex(/^[a-z][a-z0-9_.-]+$/u)
3154
3208
  })
3155
3209
  });
3156
3210
  async function analyticsPublicKeyCommand(input) {
@@ -3172,13 +3226,13 @@ async function analyticsPublicKeyCommand(input) {
3172
3226
  }
3173
3227
 
3174
3228
  // ../cli/dist/commands/analytics/prepare.js
3175
- import { z as z28 } from "zod";
3176
- var resultSchema = z28.object({
3177
- ok: z28.literal(true),
3178
- data: z28.object({
3179
- rawPublicKey: z28.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/u),
3180
- generation: z28.number().int().positive(),
3181
- status: z28.enum([
3229
+ import { z as z29 } from "zod";
3230
+ var resultSchema = z29.object({
3231
+ ok: z29.literal(true),
3232
+ data: z29.object({
3233
+ rawPublicKey: z29.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/u),
3234
+ generation: z29.number().int().positive(),
3235
+ status: z29.enum([
3182
3236
  "setup_started",
3183
3237
  "test_mode",
3184
3238
  "active",
@@ -3188,8 +3242,8 @@ var resultSchema = z28.object({
3188
3242
  ])
3189
3243
  }).strict()
3190
3244
  }).strict();
3191
- var errorSchema = z28.object({
3192
- error: z28.object({ code: z28.string().regex(/^[a-z][a-z0-9_.-]+$/u) })
3245
+ var errorSchema = z29.object({
3246
+ error: z29.object({ code: z29.string().regex(/^[a-z][a-z0-9_.-]+$/u) })
3193
3247
  });
3194
3248
  async function analyticsPrepareCommand(input) {
3195
3249
  const response = await (input.fetchImpl ?? fetch)(`${input.config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/analytics/prepare`, {
@@ -3409,19 +3463,19 @@ async function bookingTestCommand(input) {
3409
3463
  import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
3410
3464
  import { randomUUID as randomUUID2 } from "crypto";
3411
3465
  import { join as join3 } from "path";
3412
- import { z as z29 } from "zod";
3413
- var siteplaneProjectConfigSchema = z29.object({
3414
- version: z29.literal(2),
3415
- apiBaseUrl: z29.string().url(),
3416
- siteId: z29.string().uuid(),
3417
- publicSiteKeyId: z29.string().uuid(),
3418
- publicSiteKey: z29.string().trim().min(1),
3419
- runId: z29.string().uuid(),
3420
- appDirectory: z29.string().min(1),
3421
- taskContractVersion: z29.literal("siteplane.setup-task.v2"),
3422
- adminProtocolVersion: z29.literal(2),
3466
+ import { z as z30 } from "zod";
3467
+ var siteplaneProjectConfigSchema = z30.object({
3468
+ version: z30.literal(2),
3469
+ apiBaseUrl: z30.string().url(),
3470
+ siteId: z30.string().uuid(),
3471
+ publicSiteKeyId: z30.string().uuid(),
3472
+ publicSiteKey: z30.string().trim().min(1),
3473
+ runId: z30.string().uuid(),
3474
+ appDirectory: z30.string().min(1),
3475
+ taskContractVersion: z30.literal("siteplane.setup-task.v2"),
3476
+ adminProtocolVersion: z30.literal(2),
3423
3477
  packages: siteSetupPackagesSchema,
3424
- fieldContractHash: z29.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
3478
+ fieldContractHash: z30.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
3425
3479
  }).strict();
3426
3480
  async function readProjectPackageJson(projectDir) {
3427
3481
  return JSON.parse(await readFile5(join3(projectDir, "package.json"), "utf8"));
@@ -3481,26 +3535,27 @@ import { randomUUID as randomUUID3 } from "crypto";
3481
3535
  import { chmod as chmod2, lstat, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
3482
3536
  import { dirname as dirname5, join as join4, relative } from "path";
3483
3537
  import { promisify } from "util";
3484
- import { z as z30 } from "zod";
3485
- var localSetupInstallationSchema = z30.object({
3486
- key: z30.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3487
- idempotencyKey: z30.string().uuid(),
3488
- apiBaseUrl: z30.string().url(),
3538
+ import { z as z31 } from "zod";
3539
+ var localSetupInstallationSchema = z31.object({
3540
+ key: z31.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3541
+ idempotencyKey: z31.string().uuid(),
3542
+ apiBaseUrl: z31.string().url(),
3489
3543
  request: setupInstallationRequestSchema,
3490
- bootstrapAcknowledged: z30.boolean()
3544
+ bootstrapAcknowledged: z31.boolean()
3491
3545
  }).strict();
3492
- var siteplaneCredentialsSchema = z30.object({
3493
- accessToken: z30.string().trim().min(1),
3494
- siteRevalidationSecret: z30.string().trim().min(1),
3546
+ var siteplaneCredentialsSchema = z31.object({
3547
+ accessToken: z31.string().trim().min(1),
3548
+ siteRevalidationSecret: z31.string().trim().min(1),
3495
3549
  installation: localSetupInstallationSchema.optional(),
3496
- adminSession: z30.object({
3497
- secret: z30.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3498
- generation: z30.string().uuid()
3550
+ claimReceipt: setupClaimReceiptSchema.optional(),
3551
+ adminSession: z31.object({
3552
+ secret: z31.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3553
+ generation: z31.string().uuid()
3499
3554
  }).strict().optional()
3500
3555
  }).strict();
3501
- var localSetupCredentialsSchema = z30.union([
3556
+ var localSetupCredentialsSchema = z31.union([
3502
3557
  siteplaneCredentialsSchema,
3503
- z30.object({ installation: localSetupInstallationSchema }).strict()
3558
+ z31.object({ installation: localSetupInstallationSchema }).strict()
3504
3559
  ]);
3505
3560
  async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
3506
3561
  const path = join4(projectDir, ".siteplane/credentials.json");
@@ -3573,6 +3628,12 @@ async function writeCredentialsAtomically(path, credentials) {
3573
3628
  try {
3574
3629
  await rename2(temporaryPath, path);
3575
3630
  await chmod2(path, 384);
3631
+ const directory = await open2(dirname5(path), "r");
3632
+ try {
3633
+ await directory.sync();
3634
+ } finally {
3635
+ await directory.close();
3636
+ }
3576
3637
  } catch (error) {
3577
3638
  await rm2(temporaryPath, { force: true });
3578
3639
  throw error;
@@ -3592,7 +3653,7 @@ async function gitPathMatches(projectDir, path, command) {
3592
3653
  // ../cli/dist/commands/init.js
3593
3654
  import { access as access3 } from "fs/promises";
3594
3655
  import { join as join7, relative as relative3 } from "path";
3595
- import { z as z33 } from "zod";
3656
+ import { z as z34 } from "zod";
3596
3657
 
3597
3658
  // ../cli/dist/commands/setup-preflight.js
3598
3659
  import { createHash as createHash2 } from "crypto";
@@ -3604,11 +3665,11 @@ import { parse as parseYaml } from "yaml";
3604
3665
  import { createRequire } from "module";
3605
3666
  import { readFile as readFile7 } from "fs/promises";
3606
3667
  import { join as join5 } from "path";
3607
- import { z as z31 } from "zod";
3608
- var packageSchema = z31.object({
3609
- name: z31.string().optional(),
3610
- version: z31.string(),
3611
- peerDependencies: z31.record(z31.string(), z31.string()).optional()
3668
+ import { z as z32 } from "zod";
3669
+ var packageSchema = z32.object({
3670
+ name: z32.string().optional(),
3671
+ version: z32.string(),
3672
+ peerDependencies: z32.record(z32.string(), z32.string()).optional()
3612
3673
  });
3613
3674
  async function readInstalledPackage(projectDir, name2) {
3614
3675
  const require2 = createRequire(join5(projectDir, "package.json"));
@@ -3623,9 +3684,9 @@ async function readInstalledPackage(projectDir, name2) {
3623
3684
  throw new Error(`Install ${name2} with the canonical package manager before setup.`);
3624
3685
  }
3625
3686
  async function assertExactSetupPackages(projectDir, packages) {
3626
- const manifest = z31.object({
3627
- dependencies: z31.record(z31.string(), z31.string()).optional(),
3628
- devDependencies: z31.record(z31.string(), z31.string()).optional()
3687
+ const manifest = z32.object({
3688
+ dependencies: z32.record(z32.string(), z32.string()).optional(),
3689
+ devDependencies: z32.record(z32.string(), z32.string()).optional()
3629
3690
  }).parse(JSON.parse(await readFile7(join5(projectDir, "package.json"), "utf8")));
3630
3691
  for (const [name2, version2] of [
3631
3692
  ["siteplane", packages.siteplane],
@@ -3642,7 +3703,7 @@ async function assertExactSetupPackages(projectDir, packages) {
3642
3703
  // ../cli/dist/commands/setup-preflight.js
3643
3704
  import { access as access2, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
3644
3705
  import { dirname as dirname6, join as join6, relative as relative2, resolve, sep } from "path";
3645
- import { z as z32 } from "zod";
3706
+ import { z as z33 } from "zod";
3646
3707
 
3647
3708
  // ../cli/dist/commands/setup-process.js
3648
3709
  import { spawn } from "child_process";
@@ -3743,29 +3804,29 @@ async function setupVercelApi(cwd, endpoint, body, method, options) {
3743
3804
  }
3744
3805
 
3745
3806
  // ../cli/dist/commands/setup-preflight.js
3746
- var manifestSchema = z32.object({
3747
- packageManager: z32.string().optional(),
3748
- engines: z32.object({ node: z32.string().optional() }).optional(),
3749
- dependencies: z32.record(z32.string(), z32.string()).optional(),
3750
- devDependencies: z32.record(z32.string(), z32.string()).optional(),
3751
- scripts: z32.record(z32.string(), z32.string()).optional(),
3752
- workspaces: z32.unknown().optional()
3807
+ var manifestSchema = z33.object({
3808
+ packageManager: z33.string().optional(),
3809
+ engines: z33.object({ node: z33.string().optional() }).optional(),
3810
+ dependencies: z33.record(z33.string(), z33.string()).optional(),
3811
+ devDependencies: z33.record(z33.string(), z33.string()).optional(),
3812
+ scripts: z33.record(z33.string(), z33.string()).optional(),
3813
+ workspaces: z33.unknown().optional()
3753
3814
  });
3754
- var vercelProjectSchema = z32.object({
3755
- id: z32.string(),
3756
- accountId: z32.string(),
3757
- name: z32.string(),
3758
- nodeVersion: z32.string().nullable().optional(),
3759
- rootDirectory: z32.string().nullable().optional(),
3760
- framework: z32.string().nullable().optional(),
3761
- installCommand: z32.string().nullable().optional(),
3762
- buildCommand: z32.string().nullable().optional(),
3763
- link: z32.object({
3764
- type: z32.string(),
3765
- repo: z32.string().optional(),
3766
- repoId: z32.union([z32.string(), z32.number()]).optional(),
3767
- org: z32.string().optional(),
3768
- productionBranch: z32.string().optional()
3815
+ var vercelProjectSchema = z33.object({
3816
+ id: z33.string(),
3817
+ accountId: z33.string(),
3818
+ name: z33.string(),
3819
+ nodeVersion: z33.string().nullable().optional(),
3820
+ rootDirectory: z33.string().nullable().optional(),
3821
+ framework: z33.string().nullable().optional(),
3822
+ installCommand: z33.string().nullable().optional(),
3823
+ buildCommand: z33.string().nullable().optional(),
3824
+ link: z33.object({
3825
+ type: z33.string(),
3826
+ repo: z33.string().optional(),
3827
+ repoId: z33.union([z33.string(), z33.number()]).optional(),
3828
+ org: z33.string().optional(),
3829
+ productionBranch: z33.string().optional()
3769
3830
  }).nullable().optional()
3770
3831
  });
3771
3832
  var exists = async (path) => access2(path).then(() => true, () => false);
@@ -3822,9 +3883,9 @@ async function inspectSetupLocalProject(projectDir) {
3822
3883
  const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join6(lockfileRoot, "package.json"), "utf8")));
3823
3884
  if (lockfileRoot !== projectDirectory) {
3824
3885
  const workspaceFile = join6(lockfileRoot, "pnpm-workspace.yaml");
3825
- const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z32.object({ packages: z32.array(z32.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z32.union([
3826
- z32.array(z32.string()),
3827
- z32.object({ packages: z32.array(z32.string()) }).transform((value) => value.packages)
3886
+ const workspace = lockName === "pnpm-lock.yaml" && await exists(workspaceFile) ? z33.object({ packages: z33.array(z33.string()) }).parse(parseYaml(await readFile8(workspaceFile, "utf8"))).packages : z33.union([
3887
+ z33.array(z33.string()),
3888
+ z33.object({ packages: z33.array(z33.string()) }).transform((value) => value.packages)
3828
3889
  ]).parse(rootManifest.workspaces);
3829
3890
  const selected = relative2(lockfileRoot, projectDirectory).split(sep).join("/");
3830
3891
  if (!workspace.some((pattern) => !pattern.startsWith("!") && minimatch(selected, pattern)) || workspace.some((pattern) => pattern.startsWith("!") && minimatch(selected, pattern.slice(1))))
@@ -3838,11 +3899,11 @@ async function inspectSetupLocalProject(projectDir) {
3838
3899
  break;
3839
3900
  }
3840
3901
  const lockText = await readFile8(join6(lockfileRoot, lockName), "utf8");
3841
- const npmLock = lockName === "package-lock.json" ? z32.object({
3842
- lockfileVersion: z32.number(),
3843
- packages: z32.record(z32.string(), z32.object({
3844
- version: z32.string().optional(),
3845
- peerDependencies: z32.record(z32.string(), z32.string()).optional()
3902
+ const npmLock = lockName === "package-lock.json" ? z33.object({
3903
+ lockfileVersion: z33.number(),
3904
+ packages: z33.record(z33.string(), z33.object({
3905
+ version: z33.string().optional(),
3906
+ peerDependencies: z33.record(z33.string(), z33.string()).optional()
3846
3907
  })).optional()
3847
3908
  }).parse(JSON.parse(lockText)) : null;
3848
3909
  async function version2(name3) {
@@ -3982,9 +4043,9 @@ async function setupPreflightCommand(input) {
3982
4043
  linkDirectory = dirname6(linkDirectory);
3983
4044
  if (!await exists(join6(linkDirectory, ".vercel/project.json")))
3984
4045
  fail("vercel_project_not_linked", "Link this application to its intended Vercel project before setup; Siteplane will not guess a target.");
3985
- const linked = z32.object({
3986
- projectId: z32.string().regex(/^prj_[A-Za-z0-9]+$/u),
3987
- orgId: z32.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
4046
+ const linked = z33.object({
4047
+ projectId: z33.string().regex(/^prj_[A-Za-z0-9]+$/u),
4048
+ orgId: z33.string().regex(/^(?:team|user)_[A-Za-z0-9]+$/u)
3988
4049
  }).parse(JSON.parse(await readFile8(join6(linkDirectory, ".vercel/project.json"), "utf8")));
3989
4050
  const project = vercelProjectSchema.parse(await setupVercelApi(linkDirectory, `/v9/projects/${linked.projectId}?teamId=${linked.orgId}`));
3990
4051
  if (project.id !== linked.projectId || project.accountId !== linked.orgId)
@@ -3998,11 +4059,11 @@ async function setupPreflightCommand(input) {
3998
4059
  fail("vercel_production_branch_conflict", "The local branch differs from the bound Vercel Production branch.");
3999
4060
  if (project.link?.repo && project.link.org && !local.git.remote?.replace(/\.git$/u, "").endsWith(`${project.link.org}/${project.link.repo}`))
4000
4061
  fail("vercel_git_conflict", "The local origin repository differs from the Vercel Git connection.");
4001
- const env = z32.object({
4002
- envs: z32.array(z32.object({
4003
- key: z32.string(),
4004
- value: z32.string().optional(),
4005
- target: z32.array(z32.string()).optional()
4062
+ const env = z33.object({
4063
+ envs: z33.array(z33.object({
4064
+ key: z33.string(),
4065
+ value: z33.string().optional(),
4066
+ target: z33.array(z33.string()).optional()
4006
4067
  }))
4007
4068
  }).parse(await setupVercelApi(linkDirectory, `/v10/projects/${linked.projectId}/env?teamId=${linked.orgId}`));
4008
4069
  const corepack = env.envs.some((item) => item.key === "ENABLE_EXPERIMENTAL_COREPACK" && item.value === "1" && item.target?.includes("production"));
@@ -4092,26 +4153,26 @@ async function initCommand(input) {
4092
4153
  ]
4093
4154
  };
4094
4155
  }
4095
- var siteSetupBootstrapDataSchema = z33.object({
4096
- credentialPurpose: z33.literal("site_setup"),
4097
- apiBaseUrl: z33.string().url(),
4098
- siteId: z33.string().uuid(),
4099
- publicSiteKeyId: z33.string().uuid(),
4100
- publicSiteKey: z33.string().trim().min(1),
4101
- accessToken: z33.string().trim().min(1),
4102
- siteRevalidationSecret: z33.string().regex(/^[A-Za-z0-9_-]{43}$/u),
4103
- runId: z33.string().uuid(),
4156
+ var siteSetupBootstrapDataSchema = z34.object({
4157
+ credentialPurpose: z34.literal("site_setup"),
4158
+ apiBaseUrl: z34.string().url(),
4159
+ siteId: z34.string().uuid(),
4160
+ publicSiteKeyId: z34.string().uuid(),
4161
+ publicSiteKey: z34.string().trim().min(1),
4162
+ accessToken: z34.string().trim().min(1),
4163
+ siteRevalidationSecret: z34.string().regex(/^[A-Za-z0-9_-]{43}$/u),
4164
+ runId: z34.string().uuid(),
4104
4165
  packages: siteSetupPackagesSchema
4105
4166
  }).strict();
4106
- var featureBootstrapDataSchema = z33.object({
4107
- credentialPurpose: z33.enum(["analytics", "booking"]),
4108
- apiBaseUrl: z33.string().url(),
4109
- siteId: z33.string().uuid(),
4110
- accessToken: z33.string().trim().min(1)
4167
+ var featureBootstrapDataSchema = z34.object({
4168
+ credentialPurpose: z34.enum(["analytics", "booking"]),
4169
+ apiBaseUrl: z34.string().url(),
4170
+ siteId: z34.string().uuid(),
4171
+ accessToken: z34.string().trim().min(1)
4111
4172
  }).strict();
4112
- var bootstrapResponseSchema = z33.object({
4113
- ok: z33.literal(true),
4114
- data: z33.discriminatedUnion("credentialPurpose", [
4173
+ var bootstrapResponseSchema = z34.object({
4174
+ ok: z34.literal(true),
4175
+ data: z34.discriminatedUnion("credentialPurpose", [
4115
4176
  siteSetupBootstrapDataSchema,
4116
4177
  featureBootstrapDataSchema
4117
4178
  ])
@@ -4155,6 +4216,7 @@ async function persistSiteSetupBootstrap(input, bootstrap, appDirectory, install
4155
4216
  const previousCredentials = previous ? await access3(join7(input.projectDir, ".siteplane/credentials.json")).then(() => readLocalSetupCredentials(input.projectDir), () => null) : null;
4156
4217
  const credentialsPath = await writeLocalCredentials(input.projectDir, {
4157
4218
  ...previousCredentials && "adminSession" in previousCredentials && previousCredentials.adminSession ? { adminSession: previousCredentials.adminSession } : {},
4219
+ ...previousCredentials && "claimReceipt" in previousCredentials && previousCredentials.claimReceipt ? { claimReceipt: previousCredentials.claimReceipt } : {},
4158
4220
  accessToken: bootstrap.accessToken,
4159
4221
  siteRevalidationSecret: bootstrap.siteRevalidationSecret,
4160
4222
  ...installation ?? previousCredentials?.installation ? { installation: installation ?? previousCredentials?.installation } : {}
@@ -4270,7 +4332,7 @@ async function collectSourceFiles(directory) {
4270
4332
  import { execFile as execFile2 } from "child_process";
4271
4333
  import { readFile as readFile9 } from "fs/promises";
4272
4334
  import { promisify as promisify2 } from "util";
4273
- import { z as z34 } from "zod";
4335
+ import { z as z35 } from "zod";
4274
4336
 
4275
4337
  // ../cli/dist/scan/next-source-scan.js
4276
4338
  import ts2 from "typescript";
@@ -4967,32 +5029,32 @@ function isPositionalFieldReference(value) {
4967
5029
 
4968
5030
  // ../cli/dist/commands/site-setup.js
4969
5031
  var execFileAsync2 = promisify2(execFile2);
4970
- var safeErrorSchema = z34.object({
4971
- code: z34.string().trim().min(1),
4972
- message: z34.string().trim().min(1)
5032
+ var safeErrorSchema = z35.object({
5033
+ code: z35.string().trim().min(1),
5034
+ message: z35.string().trim().min(1)
4973
5035
  }).passthrough();
4974
- var errorResponseSchema2 = z34.object({ ok: z34.literal(false), error: safeErrorSchema }).passthrough();
4975
- var contextDataSchema = z34.object({
5036
+ var errorResponseSchema2 = z35.object({ ok: z35.literal(false), error: safeErrorSchema }).passthrough();
5037
+ var contextDataSchema = z35.object({
4976
5038
  task: siteSetupTaskSchema.refine((task) => task.run !== null)
4977
5039
  }).strict();
4978
- var contextResponseSchema = z34.object({ ok: z34.literal(true), data: contextDataSchema }).strict();
4979
- var applyDataSchema = z34.object({
4980
- status: z34.enum(["applied", "ready_for_review"]),
4981
- runId: z34.string().uuid().optional(),
4982
- contractVersionId: z34.string().uuid().optional(),
4983
- fieldContractHash: z34.string().regex(/^sha256:[0-9a-f]{64}$/u),
4984
- editorDefinitionHash: z34.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
4985
- fieldCount: z34.number().int().nonnegative().optional(),
4986
- routeCount: z34.number().int().nonnegative().optional()
5040
+ var contextResponseSchema = z35.object({ ok: z35.literal(true), data: contextDataSchema }).strict();
5041
+ var applyDataSchema = z35.object({
5042
+ status: z35.enum(["applied", "ready_for_review"]),
5043
+ runId: z35.string().uuid().optional(),
5044
+ contractVersionId: z35.string().uuid().optional(),
5045
+ fieldContractHash: z35.string().regex(/^sha256:[0-9a-f]{64}$/u),
5046
+ editorDefinitionHash: z35.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
5047
+ fieldCount: z35.number().int().nonnegative().optional(),
5048
+ routeCount: z35.number().int().nonnegative().optional()
4987
5049
  }).strict();
4988
- var applyResponseSchema = z34.object({ ok: z34.literal(true), data: applyDataSchema }).strict();
4989
- var verifyDataSchema = z34.object({
4990
- status: z34.literal("ready_for_review"),
4991
- runId: z34.string().uuid().optional(),
4992
- deploymentOrigin: z34.string().url().optional(),
4993
- deploymentRevision: z34.string().optional()
5050
+ var applyResponseSchema = z35.object({ ok: z35.literal(true), data: applyDataSchema }).strict();
5051
+ var verifyDataSchema = z35.object({
5052
+ status: z35.literal("ready_for_review"),
5053
+ runId: z35.string().uuid().optional(),
5054
+ deploymentOrigin: z35.string().url().optional(),
5055
+ deploymentRevision: z35.string().optional()
4994
5056
  }).strict();
4995
- var verifyResponseSchema = z34.object({ ok: z34.literal(true), data: verifyDataSchema }).strict();
5057
+ var verifyResponseSchema = z35.object({ ok: z35.literal(true), data: verifyDataSchema }).strict();
4996
5058
  async function siteSetupContextCommand(input) {
4997
5059
  const response = await postSiteSetup(input, "context", {});
4998
5060
  const parsed = contextResponseSchema.safeParse(response.payload);
@@ -5156,9 +5218,9 @@ async function siteSetupActivityCommand(input) {
5156
5218
  message: "Choose inspecting, integrating, deploying, verifying or repairing."
5157
5219
  };
5158
5220
  const response = await postSiteSetup(input, "activity", activity.data);
5159
- const parsed = z34.object({
5160
- ok: z34.literal(true),
5161
- data: z34.object({ status: z34.enum(["recorded", "rate_limited"]) }).strict()
5221
+ const parsed = z35.object({
5222
+ ok: z35.literal(true),
5223
+ data: z35.object({ status: z35.enum(["recorded", "rate_limited"]) }).strict()
5162
5224
  }).strict().safeParse(response.payload);
5163
5225
  return response.ok && parsed.success ? parsed.data.data : actionRequired(response.payload, "Setup activity could not be recorded.");
5164
5226
  }
@@ -5167,9 +5229,9 @@ async function siteSetupActivityCommand(input) {
5167
5229
  import { randomBytes, randomUUID as randomUUID4 } from "crypto";
5168
5230
  import { access as access4 } from "fs/promises";
5169
5231
  import { join as join9, relative as relative5 } from "path";
5170
- import { z as z35 } from "zod";
5171
- var bootstrapResponseSchema2 = z35.object({
5172
- ok: z35.literal(true),
5232
+ import { z as z36 } from "zod";
5233
+ var bootstrapResponseSchema2 = z36.object({
5234
+ ok: z36.literal(true),
5173
5235
  data: siteSetupBootstrapDataSchema
5174
5236
  }).strict();
5175
5237
  async function setupStartCommand(input) {
@@ -5243,9 +5305,9 @@ async function acknowledge(input, credentials) {
5243
5305
  if (!installation || !("accessToken" in credentials))
5244
5306
  throw new Error("Incomplete installation exchange.");
5245
5307
  const payload = await installationRequest(input, installation, "acknowledge");
5246
- z35.object({
5247
- ok: z35.literal(true),
5248
- data: z35.object({ acknowledged: z35.literal(true) }).strict()
5308
+ z36.object({
5309
+ ok: z36.literal(true),
5310
+ data: z36.object({ acknowledged: z36.literal(true) }).strict()
5249
5311
  }).strict().parse(payload);
5250
5312
  await writeLocalSetupCredentials(input.projectDir, {
5251
5313
  ...credentials,
@@ -5266,9 +5328,9 @@ async function installationRequest(input, installation, action) {
5266
5328
  });
5267
5329
  const payload = await response.json();
5268
5330
  if (!response.ok) {
5269
- const error = z35.object({
5270
- error: z35.object({
5271
- code: z35.string().regex(/^[a-z][a-z0-9_.]{0,100}$/u)
5331
+ const error = z36.object({
5332
+ error: z36.object({
5333
+ code: z36.string().regex(/^[a-z][a-z0-9_.]{0,100}$/u)
5272
5334
  })
5273
5335
  }).safeParse(payload);
5274
5336
  throw new SetupFailure(error.success ? error.data.error.code : "setup_start_failed", "Siteplane could not complete this installation request. The saved local key and request are unchanged; retry after resolving the reported boundary.");
@@ -5296,6 +5358,91 @@ async function exists2(path) {
5296
5358
  }
5297
5359
  }
5298
5360
 
5361
+ // ../cli/dist/commands/setup-review.js
5362
+ import { z as z37 } from "zod";
5363
+ var responseSchema2 = z37.object({
5364
+ ok: z37.literal(true),
5365
+ data: z37.object({
5366
+ reviewUrl: z37.string().url(),
5367
+ expiresAt: z37.string().datetime({ offset: true })
5368
+ }).strict()
5369
+ }).strict();
5370
+ async function setupReviewCommand(input) {
5371
+ const [config, credentials] = await Promise.all([
5372
+ readProjectConfig(input.projectDir),
5373
+ readLocalCredentials(input.projectDir).catch((error) => {
5374
+ if (error.code === "ENOENT")
5375
+ return null;
5376
+ throw error;
5377
+ })
5378
+ ]);
5379
+ if (credentials?.claimReceipt) {
5380
+ if (credentials.claimReceipt.siteId !== config.siteId || credentials.claimReceipt.runId !== config.runId)
5381
+ return { status: "action_required", code: "claim_binding_mismatch", message: "Restore the matching project configuration and credentials." };
5382
+ const reviewUrl = new URL("/setup/review", config.apiBaseUrl);
5383
+ reviewUrl.searchParams.set("siteId", config.siteId);
5384
+ return { status: "ready", reviewUrl: reviewUrl.toString(), expiresAt: null };
5385
+ }
5386
+ if (!credentials?.installation)
5387
+ return {
5388
+ status: "action_required",
5389
+ code: "local_credentials_missing",
5390
+ message: "Open this project's review from your Siteplane workspace. Guest review requires the original local installation credentials."
5391
+ };
5392
+ if (new URL(config.apiBaseUrl).origin !== new URL(credentials.installation.apiBaseUrl).origin)
5393
+ return {
5394
+ status: "action_required",
5395
+ code: "installation_origin_mismatch",
5396
+ message: "The project and its local installation refer to different Siteplane origins. Restore the matching local configuration."
5397
+ };
5398
+ try {
5399
+ const response = await (input.fetcher ?? fetch)(new URL("/api/cli/setup/review", config.apiBaseUrl), {
5400
+ method: "POST",
5401
+ signal: AbortSignal.timeout(2e4),
5402
+ headers: {
5403
+ authorization: `Bearer ${credentials.installation.key}`,
5404
+ "content-type": "application/json",
5405
+ ...input.vercelAutomationBypassSecret ? {
5406
+ "x-vercel-protection-bypass": input.vercelAutomationBypassSecret
5407
+ } : {}
5408
+ },
5409
+ body: JSON.stringify({ siteId: config.siteId, runId: config.runId })
5410
+ });
5411
+ const payload = await response.json();
5412
+ const parsed = responseSchema2.safeParse(payload);
5413
+ if (response.ok && parsed.success) {
5414
+ const url = new URL(parsed.data.data.reviewUrl);
5415
+ if (url.origin !== new URL(config.apiBaseUrl).origin || url.pathname !== "/setup/review" || url.search || !/^#token=[A-Za-z0-9_-]{43}$/u.test(url.hash))
5416
+ throw new Error("Invalid review destination.");
5417
+ return { status: "ready", ...parsed.data.data };
5418
+ }
5419
+ const denied = z37.object({
5420
+ error: z37.object({
5421
+ code: z37.enum([
5422
+ "invalid_installation",
5423
+ "already_claimed",
5424
+ "project_expired",
5425
+ "revoked",
5426
+ "review_not_ready",
5427
+ "rate_limited",
5428
+ "review_access_unavailable"
5429
+ ])
5430
+ })
5431
+ }).safeParse(payload);
5432
+ return {
5433
+ status: "action_required",
5434
+ code: denied.success ? denied.data.error.code : "review_access_unavailable",
5435
+ message: denied.success && denied.data.error.code === "project_expired" ? "This provisional project has expired. Its review can no longer be claimed. Your website code and deployment remain unchanged." : denied.success && denied.data.error.code === "already_claimed" ? "This website is already in an account. Open it from your Siteplane workspace." : denied.success && denied.data.error.code === "revoked" ? "This installation's access was revoked. Open the website from its owning Siteplane workspace." : "The review link is unavailable. Check the existing setup status; do not create another project."
5436
+ };
5437
+ } catch {
5438
+ return {
5439
+ status: "action_required",
5440
+ code: "review_access_unavailable",
5441
+ message: "The review link request was not acknowledged. Run setup review again when the connection is available."
5442
+ };
5443
+ }
5444
+ }
5445
+
5299
5446
  // ../cli/dist/commands/setup-prepare.js
5300
5447
  import { access as access5, lstat as lstat2, mkdir as mkdir6, open as open3, readFile as readFile10, rename as rename3, rm as rm3 } from "fs/promises";
5301
5448
  import { randomUUID as randomUUID5 } from "crypto";
@@ -5570,8 +5717,8 @@ async function assertSourcePath(root, target) {
5570
5717
  import { randomUUID as randomUUID6 } from "crypto";
5571
5718
  import { lstat as lstat3, mkdir as mkdir7, open as open4, readFile as readFile11, rm as rm4, rmdir } from "fs/promises";
5572
5719
  import { resolve as resolve2 } from "path";
5573
- import { z as z36 } from "zod";
5574
- var ownerSchema = z36.object({ pid: z36.number().int().positive(), nonce: z36.string().uuid() }).strict();
5720
+ import { z as z38 } from "zod";
5721
+ var ownerSchema = z38.object({ pid: z38.number().int().positive(), nonce: z38.string().uuid() }).strict();
5575
5722
  async function withSetupLock(projectDir, work) {
5576
5723
  const gitPath = (await setupProcess("git", ["rev-parse", "--git-path", "siteplane-setup.lock"], { cwd: projectDir })).trim();
5577
5724
  const path = resolve2(projectDir, gitPath);
@@ -5635,23 +5782,23 @@ import { execFile as execFile3 } from "child_process";
5635
5782
  import { lstat as lstat4, readFile as readFile12, writeFile as writeFile5, mkdir as mkdir8 } from "fs/promises";
5636
5783
  import { dirname as dirname8, isAbsolute as isAbsolute2, join as join11, relative as relative7, resolve as resolve3, sep as sep3 } from "path";
5637
5784
  import { isDeepStrictEqual, promisify as promisify3 } from "util";
5638
- import { z as z37 } from "zod";
5785
+ import { z as z39 } from "zod";
5639
5786
  var execute = promisify3(execFile3);
5640
5787
  var name = ".siteplane/build-source.json";
5641
- var oid = z37.string().regex(/^[0-9a-f]{40}$/u);
5642
- var entrySchema = z37.object({
5643
- path: z37.string().min(1).max(4096),
5644
- mode: z37.enum(["100644", "100755", "120000"]),
5788
+ var oid = z39.string().regex(/^[0-9a-f]{40}$/u);
5789
+ var entrySchema = z39.object({
5790
+ path: z39.string().min(1).max(4096),
5791
+ mode: z39.enum(["100644", "100755", "120000"]),
5645
5792
  oid
5646
5793
  }).strict();
5647
- var schema = z37.object({
5648
- version: z37.literal(2),
5794
+ var schema = z39.object({
5795
+ version: z39.literal(2),
5649
5796
  revision: oid,
5650
- commit: z37.string().min(1).max(1048576),
5651
- entries: z37.array(entrySchema).min(1).max(1e5),
5652
- providerConfigurations: z37.array(z37.object({
5653
- path: z37.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
5654
- source: z37.string().max(1048576)
5797
+ commit: z39.string().min(1).max(1048576),
5798
+ entries: z39.array(entrySchema).min(1).max(1e5),
5799
+ providerConfigurations: z39.array(z39.object({
5800
+ path: z39.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
5801
+ source: z39.string().max(1048576)
5655
5802
  }).strict()).max(1e3)
5656
5803
  }).strict();
5657
5804
  async function writeBuildProvenance(checkout, revision) {
@@ -5700,38 +5847,38 @@ import { createHash as createHash4, randomBytes as randomBytes2, randomUUID as r
5700
5847
  import { access as access6, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
5701
5848
  import { tmpdir } from "os";
5702
5849
  import { join as join12 } from "path";
5703
- import { z as z38 } from "zod";
5704
- var envSchema = z38.object({
5705
- id: z38.string(),
5706
- key: z38.string(),
5707
- target: z38.array(z38.string()),
5708
- type: z38.string(),
5709
- comment: z38.string().optional(),
5710
- updatedAt: z38.number().optional()
5850
+ import { z as z40 } from "zod";
5851
+ var envSchema = z40.object({
5852
+ id: z40.string(),
5853
+ key: z40.string(),
5854
+ target: z40.array(z40.string()),
5855
+ type: z40.string(),
5856
+ comment: z40.string().optional(),
5857
+ updatedAt: z40.number().optional()
5711
5858
  });
5712
- var deploymentSchema = z38.object({
5713
- id: z38.string(),
5714
- projectId: z38.string(),
5715
- ownerId: z38.string().optional(),
5716
- target: z38.string().nullable(),
5717
- readyState: z38.string(),
5718
- createdAt: z38.number(),
5719
- url: z38.string(),
5720
- meta: z38.record(z38.string(), z38.unknown()).optional(),
5721
- gitSource: z38.object({ sha: z38.string().optional() }).nullable().optional()
5859
+ var deploymentSchema = z40.object({
5860
+ id: z40.string(),
5861
+ projectId: z40.string(),
5862
+ ownerId: z40.string().optional(),
5863
+ target: z40.string().nullable(),
5864
+ readyState: z40.string(),
5865
+ createdAt: z40.number(),
5866
+ url: z40.string(),
5867
+ meta: z40.record(z40.string(), z40.unknown()).optional(),
5868
+ gitSource: z40.object({ sha: z40.string().optional() }).nullable().optional()
5722
5869
  });
5723
- var buildProofSchema = z38.object({
5724
- node: z38.string(),
5725
- packageManager: z38.enum(["npm", "pnpm"]),
5726
- packageManagerVersion: z38.string(),
5727
- lockfileHash: z38.string(),
5728
- revision: z38.string(),
5729
- fieldContractHash: z38.string(),
5730
- siteplane: z38.string(),
5731
- runtimeNext: z38.string(),
5732
- analytics: z38.string().optional(),
5733
- next: z38.string(),
5734
- react: z38.string()
5870
+ var buildProofSchema = z40.object({
5871
+ node: z40.string(),
5872
+ packageManager: z40.enum(["npm", "pnpm"]),
5873
+ packageManagerVersion: z40.string(),
5874
+ lockfileHash: z40.string(),
5875
+ revision: z40.string(),
5876
+ fieldContractHash: z40.string(),
5877
+ siteplane: z40.string(),
5878
+ runtimeNext: z40.string(),
5879
+ analytics: z40.string().optional(),
5880
+ next: z40.string(),
5881
+ react: z40.string()
5735
5882
  }).strict();
5736
5883
  var digest = (value) => `sha256:${createHash4("sha256").update(stableJsonStringify(value)).digest("hex")}`;
5737
5884
  function fail2(code, message) {
@@ -5816,12 +5963,12 @@ async function setupDeployCommand(input, deps = defaults) {
5816
5963
  remaining();
5817
5964
  return result2;
5818
5965
  };
5819
- const domains = z38.object({
5820
- domains: z38.array(z38.object({
5821
- name: z38.string(),
5822
- verified: z38.boolean(),
5823
- redirect: z38.string().nullable().optional(),
5824
- gitBranch: z38.string().nullable().optional()
5966
+ const domains = z40.object({
5967
+ domains: z40.array(z40.object({
5968
+ name: z40.string(),
5969
+ verified: z40.boolean(),
5970
+ redirect: z40.string().nullable().optional(),
5971
+ gitBranch: z40.string().nullable().optional()
5825
5972
  }))
5826
5973
  }).parse(await api(`/v9/projects/${provider.projectId}/domains?${scope}`)).domains.filter((domain) => domain.verified && !domain.redirect && !domain.gitBranch);
5827
5974
  const origin = record?.origin ?? (domains.length === 1 ? `https://${domains[0].name}` : null);
@@ -5829,7 +5976,7 @@ async function setupDeployCommand(input, deps = defaults) {
5829
5976
  fail2("production_origin_ambiguous", "The linked project needs one verified canonical Production domain, or the existing setup domain must still belong to it.");
5830
5977
  if (record && (record.projectId !== provider.projectId || record.teamId !== provider.teamId))
5831
5978
  fail2("deployment_target_conflict", "This setup already belongs to a different provider project/team. Restore its original local link.");
5832
- const listEnv = async () => z38.object({ envs: z38.array(envSchema) }).parse(await api(`/v10/projects/${provider.projectId}/env?${scope}`)).envs;
5979
+ const listEnv = async () => z40.object({ envs: z40.array(envSchema) }).parse(await api(`/v10/projects/${provider.projectId}/env?${scope}`)).envs;
5833
5980
  let env = await listEnv();
5834
5981
  const owned = (key) => {
5835
5982
  const matches2 = env.filter((item) => item.key === key && item.target.includes("production"));
@@ -5902,9 +6049,9 @@ async function setupDeployCommand(input, deps = defaults) {
5902
6049
  expectedOperationId: record?.operationId ?? null,
5903
6050
  record: next
5904
6051
  });
5905
- const parsed = z38.object({
5906
- ok: z38.literal(true),
5907
- data: z38.object({ record: setupDeploymentRecordSchema }).strict()
6052
+ const parsed = z40.object({
6053
+ ok: z40.literal(true),
6054
+ data: z40.object({ record: setupDeploymentRecordSchema }).strict()
5908
6055
  }).strict().safeParse(result2.payload);
5909
6056
  if (!result2.ok || !parsed.success || stableJsonStringify(parsed.data.data.record) !== stableJsonStringify(next))
5910
6057
  fail2("deployment_record_unconfirmed", "The setup deployment record was not acknowledged. Reload context before continuing; no deployment is blindly repeated.");
@@ -5954,7 +6101,7 @@ async function setupDeployCommand(input, deps = defaults) {
5954
6101
  const item = owned(key);
5955
6102
  if (key === "SITEPLANE_ADMIN_SESSION_SECRET" && item && record.phase === "verified")
5956
6103
  continue;
5957
- const current = item ? z38.object({ key: z38.literal(key), value: z38.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`)).value : null;
6104
+ const current = item ? z40.object({ key: z40.literal(key), value: z40.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`)).value : null;
5958
6105
  if (current !== value)
5959
6106
  pending.push({
5960
6107
  key,
@@ -5979,7 +6126,7 @@ async function setupDeployCommand(input, deps = defaults) {
5979
6126
  const item = owned(key);
5980
6127
  if (!item)
5981
6128
  fail2("environment_write_unconfirmed", "A Siteplane Production binding was not persisted; retry the same configuration.");
5982
- const observed = z38.object({ key: z38.literal(key), value: z38.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`));
6129
+ const observed = z40.object({ key: z40.literal(key), value: z40.string() }).parse(await api(`/v1/projects/${provider.projectId}/env/${encodeURIComponent(item.id)}?${scope}`));
5983
6130
  if (observed.value !== value)
5984
6131
  fail2("environment_write_unconfirmed", "The provider readback does not match the authorized Siteplane value; no deployment was started.");
5985
6132
  }
@@ -5992,7 +6139,7 @@ async function setupDeployCommand(input, deps = defaults) {
5992
6139
  const detail = async (id) => deploymentSchema.parse(await api(`/v13/deployments/${encodeURIComponent(id)}?${scope}&withGitRepoInfo=true`));
5993
6140
  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);
5994
6141
  const discover = async () => {
5995
- const result2 = z38.object({ deployments: z38.array(z38.object({ uid: z38.string() })) }).parse(await api(`/v6/deployments?${scope}&projectId=${provider.projectId}&target=production&since=${Date.parse(record.environmentWrittenAt)}&limit=100`));
6142
+ const result2 = z40.object({ deployments: z40.array(z40.object({ uid: z40.string() })) }).parse(await api(`/v6/deployments?${scope}&projectId=${provider.projectId}&target=production&since=${Date.parse(record.environmentWrittenAt)}&limit=100`));
5996
6143
  const candidates = [];
5997
6144
  for (const item of result2.deployments) {
5998
6145
  const found = await detail(item.uid);
@@ -6149,6 +6296,7 @@ async function setupDeployCommand(input, deps = defaults) {
6149
6296
  });
6150
6297
  return {
6151
6298
  status: "ready_for_review",
6299
+ ...task.assignment === "provisional" ? { reviewCommand: `npx -y siteplane@${task.packages.siteplane} setup review` } : {},
6152
6300
  deploymentId: deployment.id,
6153
6301
  origin,
6154
6302
  configurationFingerprint: fingerprint,
@@ -6165,9 +6313,91 @@ async function setupDeployCommand(input, deps = defaults) {
6165
6313
  }
6166
6314
  }
6167
6315
 
6316
+ // ../cli/dist/commands/setup-claim.js
6317
+ import { z as z41 } from "zod";
6318
+ async function setupClaimCommand(input) {
6319
+ const code = setupClaimCodeSchema.safeParse(input.code);
6320
+ const requestId = z41.string().uuid().safeParse(input.claimRequestId);
6321
+ if (!code.success || input.action === "confirm" && !requestId.success)
6322
+ return required("invalid_claim_request", "Inspect the code from your review, then confirm that concrete request with --code and --request after the user's explicit approval.");
6323
+ const [config, credentials] = await Promise.all([readProjectConfig(input.projectDir), readLocalCredentials(input.projectDir)]);
6324
+ const stored = credentials.claimReceipt;
6325
+ if (stored && (stored.siteId !== config.siteId || stored.runId !== config.runId))
6326
+ return required("claim_binding_mismatch", "Restore the matching local project configuration and credentials.");
6327
+ if (stored && (input.action !== "confirm" || stored.requestId !== input.claimRequestId))
6328
+ return required("already_claimed", "This installation already has a saved claim receipt. Continue the existing setup.");
6329
+ if (stored && !credentials.installation)
6330
+ return { status: "claimed", receipt: stored, acknowledgementPending: false };
6331
+ if (!credentials.installation)
6332
+ return required("local_installation_missing", "Claim requires this project's original local installation credentials.");
6333
+ if (new URL(config.apiBaseUrl).origin !== new URL(credentials.installation.apiBaseUrl).origin)
6334
+ return required("installation_origin_mismatch", "Restore the matching local project configuration and credentials.");
6335
+ const send = async (body) => {
6336
+ const response = await (input.fetcher ?? fetch)(new URL("/api/cli/setup/claim", config.apiBaseUrl), {
6337
+ method: "POST",
6338
+ signal: AbortSignal.timeout(2e4),
6339
+ headers: {
6340
+ authorization: `Bearer ${credentials.installation.key}`,
6341
+ "content-type": "application/json",
6342
+ ...input.vercelAutomationBypassSecret ? { "x-vercel-protection-bypass": input.vercelAutomationBypassSecret } : {}
6343
+ },
6344
+ body: JSON.stringify({ siteId: config.siteId, runId: config.runId, ...body })
6345
+ });
6346
+ return { response, payload: await response.json() };
6347
+ };
6348
+ let receipt = stored;
6349
+ if (!receipt) {
6350
+ if (input.action === "confirm")
6351
+ await assertLocalCredentialsPathSafe(input.projectDir);
6352
+ try {
6353
+ const { response, payload } = await send({
6354
+ action: input.action,
6355
+ code: code.data,
6356
+ ...input.action === "confirm" ? { claimRequestId: input.claimRequestId } : {}
6357
+ });
6358
+ if (!response.ok) {
6359
+ const denied = z41.object({ error: z41.object({ code: setupClaimDenialSchema.shape.status }) }).safeParse(payload);
6360
+ return required(denied.success ? denied.data.error.code : "claim_unavailable", "Claim was not acknowledged. Check the review and retry the same request; do not create another project.");
6361
+ }
6362
+ if (input.action === "inspect") {
6363
+ const inspected = z41.object({ ok: z41.literal(true), data: setupClaimInspectionSchema }).strict().parse(payload).data;
6364
+ if (inspected.siteId !== config.siteId || inspected.runId !== config.runId)
6365
+ throw new Error("Claim binding mismatch.");
6366
+ return {
6367
+ status: "pending",
6368
+ request: inspected,
6369
+ nextAction: "Show this account, workspace and website to the user. Only after their explicit approval, run setup claim confirm with the same code and this requestId."
6370
+ };
6371
+ }
6372
+ receipt = z41.object({ ok: z41.literal(true), data: setupClaimReceiptSchema }).strict().parse(payload).data;
6373
+ if (receipt.siteId !== config.siteId || receipt.runId !== config.runId || receipt.requestId !== input.claimRequestId)
6374
+ throw new Error("Claim receipt binding mismatch.");
6375
+ } catch {
6376
+ return required("claim_unavailable", "Claim was not acknowledged. Retry the same code and request so the committed receipt can be recovered.");
6377
+ }
6378
+ await writeLocalCredentials(input.projectDir, { ...credentials, claimReceipt: receipt });
6379
+ }
6380
+ let acknowledgementSettled = false;
6381
+ try {
6382
+ const { response, payload } = await send({ action: "acknowledge", claimRequestId: receipt.requestId });
6383
+ const result2 = z41.object({ ok: z41.literal(true), data: z41.object({ acknowledged: z41.boolean() }).strict() }).strict().safeParse(payload);
6384
+ acknowledgementSettled = response.ok && result2.success;
6385
+ } catch {
6386
+ }
6387
+ if (acknowledgementSettled) {
6388
+ const retained = { ...credentials };
6389
+ delete retained.installation;
6390
+ await writeLocalCredentials(input.projectDir, { ...retained, claimReceipt: receipt });
6391
+ }
6392
+ return { status: "claimed", receipt, acknowledgementPending: !acknowledgementSettled };
6393
+ }
6394
+ function required(code, message) {
6395
+ return { status: "action_required", code, message };
6396
+ }
6397
+
6168
6398
  // src/bin/run-siteplane.ts
6169
6399
  async function runSiteplaneCli(args, dependencies = createDefaultDependencies()) {
6170
- const writes = args[0] === "init" || args[0] === "analytics" && args[1] === "init" || args[0] === "setup" && ["start", "apply", "prepare", "deploy"].includes(args[1] ?? "");
6400
+ const writes = args[0] === "init" || args[0] === "analytics" && args[1] === "init" || args[0] === "setup" && (["start", "apply", "prepare", "deploy"].includes(args[1] ?? "") || args[1] === "claim" && args[2] === "confirm");
6171
6401
  const missingDeploy = args[0] === "setup" && args[1] === "deploy" && !await access7(join13(dependencies.cwd(), "siteplane.config.json")).then(
6172
6402
  () => true,
6173
6403
  () => false
@@ -6399,6 +6629,25 @@ async function runSetupCommand(args, dependencies) {
6399
6629
  dependencies.stdout(JSON.stringify(result2, null, 2));
6400
6630
  return { exitCode: result2.status === "action_required" ? 1 : 0 };
6401
6631
  }
6632
+ if (area === "review") {
6633
+ const result2 = await dependencies.commands.setupReviewCommand({ projectDir, ...connectionOptions });
6634
+ dependencies.stdout(JSON.stringify(result2, null, 2));
6635
+ return { exitCode: result2.status === "ready" ? 0 : 1 };
6636
+ }
6637
+ if (area === "claim") {
6638
+ const action = areaArgs[0];
6639
+ if (action !== "inspect" && action !== "confirm")
6640
+ throw new Error("Use setup claim inspect --code <code>, then setup claim confirm --code <code> --request <requestId> after the user's explicit approval.");
6641
+ const result2 = await dependencies.commands.setupClaimCommand({
6642
+ projectDir,
6643
+ action,
6644
+ code: readOption(areaArgs, "--code") ?? "",
6645
+ ...readOption(areaArgs, "--request") ? { claimRequestId: readOption(areaArgs, "--request") } : {},
6646
+ ...connectionOptions
6647
+ });
6648
+ dependencies.stdout(JSON.stringify(result2, null, 2));
6649
+ return { exitCode: result2.status === "action_required" ? 1 : 0 };
6650
+ }
6402
6651
  if (area === "context") {
6403
6652
  const result2 = await dependencies.commands.siteSetupContextCommand({
6404
6653
  projectDir,
@@ -6445,7 +6694,7 @@ async function runSetupCommand(args, dependencies) {
6445
6694
  return { exitCode: result2.status === "ready_for_review" ? 0 : 1 };
6446
6695
  }
6447
6696
  dependencies.stdout(
6448
- "Usage: siteplane setup <start|preflight|prepare|context|activity|apply|deploy|verify>"
6697
+ "Usage: siteplane setup <start|preflight|prepare|context|activity|apply|deploy|verify|review|claim>"
6449
6698
  );
6450
6699
  return { exitCode: 1 };
6451
6700
  }
@@ -6585,6 +6834,8 @@ function createDefaultDependencies() {
6585
6834
  siteSetupVerifyCommand,
6586
6835
  setupPreflightCommand,
6587
6836
  setupStartCommand,
6837
+ setupReviewCommand,
6838
+ setupClaimCommand,
6588
6839
  setupPrepareCommand,
6589
6840
  setupDeployCommand,
6590
6841
  initCommand,