siteplane 0.1.52 → 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.
@@ -2330,6 +2330,47 @@ var setupInstallationRequestSchema = z26.object({
2330
2330
  }).strict()
2331
2331
  }).strict();
2332
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
+
2333
2374
  // ../cli/dist/analytics/manifest.js
2334
2375
  async function readAnalyticsManifestFile(manifestPath) {
2335
2376
  return validateAnalyticsManifestInput(JSON.parse(await readFile(manifestPath, "utf8")));
@@ -3154,16 +3195,16 @@ async function analyticsReadinessCommand(input) {
3154
3195
  }
3155
3196
 
3156
3197
  // ../cli/dist/commands/analytics/public-key.js
3157
- import { z as z27 } from "zod";
3158
- var responseSchema = z27.object({
3159
- ok: z27.literal(true),
3160
- data: z27.object({
3161
- 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}$/)
3162
3203
  })
3163
3204
  });
3164
- var errorResponseSchema = z27.object({
3165
- error: z27.object({
3166
- 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)
3167
3208
  })
3168
3209
  });
3169
3210
  async function analyticsPublicKeyCommand(input) {
@@ -3185,13 +3226,13 @@ async function analyticsPublicKeyCommand(input) {
3185
3226
  }
3186
3227
 
3187
3228
  // ../cli/dist/commands/analytics/prepare.js
3188
- import { z as z28 } from "zod";
3189
- var resultSchema = z28.object({
3190
- ok: z28.literal(true),
3191
- data: z28.object({
3192
- rawPublicKey: z28.string().regex(/^pk_siteplane_[A-Za-z0-9_-]{16}_[A-Za-z0-9_-]{43}$/u),
3193
- generation: z28.number().int().positive(),
3194
- 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([
3195
3236
  "setup_started",
3196
3237
  "test_mode",
3197
3238
  "active",
@@ -3201,8 +3242,8 @@ var resultSchema = z28.object({
3201
3242
  ])
3202
3243
  }).strict()
3203
3244
  }).strict();
3204
- var errorSchema = z28.object({
3205
- 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) })
3206
3247
  });
3207
3248
  async function analyticsPrepareCommand(input) {
3208
3249
  const response = await (input.fetchImpl ?? fetch)(`${input.config.apiBaseUrl.replace(/\/$/u, "")}/api/cli/analytics/prepare`, {
@@ -3422,19 +3463,19 @@ async function bookingTestCommand(input) {
3422
3463
  import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
3423
3464
  import { randomUUID as randomUUID2 } from "crypto";
3424
3465
  import { join as join3 } from "path";
3425
- import { z as z29 } from "zod";
3426
- var siteplaneProjectConfigSchema = z29.object({
3427
- version: z29.literal(2),
3428
- apiBaseUrl: z29.string().url(),
3429
- siteId: z29.string().uuid(),
3430
- publicSiteKeyId: z29.string().uuid(),
3431
- publicSiteKey: z29.string().trim().min(1),
3432
- runId: z29.string().uuid(),
3433
- appDirectory: z29.string().min(1),
3434
- taskContractVersion: z29.literal("siteplane.setup-task.v2"),
3435
- 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),
3436
3477
  packages: siteSetupPackagesSchema,
3437
- fieldContractHash: z29.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
3478
+ fieldContractHash: z30.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
3438
3479
  }).strict();
3439
3480
  async function readProjectPackageJson(projectDir) {
3440
3481
  return JSON.parse(await readFile5(join3(projectDir, "package.json"), "utf8"));
@@ -3494,26 +3535,27 @@ import { randomUUID as randomUUID3 } from "crypto";
3494
3535
  import { chmod as chmod2, lstat, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
3495
3536
  import { dirname as dirname5, join as join4, relative } from "path";
3496
3537
  import { promisify } from "util";
3497
- import { z as z30 } from "zod";
3498
- var localSetupInstallationSchema = z30.object({
3499
- key: z30.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3500
- idempotencyKey: z30.string().uuid(),
3501
- 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(),
3502
3543
  request: setupInstallationRequestSchema,
3503
- bootstrapAcknowledged: z30.boolean()
3544
+ bootstrapAcknowledged: z31.boolean()
3504
3545
  }).strict();
3505
- var siteplaneCredentialsSchema = z30.object({
3506
- accessToken: z30.string().trim().min(1),
3507
- 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),
3508
3549
  installation: localSetupInstallationSchema.optional(),
3509
- adminSession: z30.object({
3510
- secret: z30.string().regex(/^[A-Za-z0-9_-]{43}$/u),
3511
- 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()
3512
3554
  }).strict().optional()
3513
3555
  }).strict();
3514
- var localSetupCredentialsSchema = z30.union([
3556
+ var localSetupCredentialsSchema = z31.union([
3515
3557
  siteplaneCredentialsSchema,
3516
- z30.object({ installation: localSetupInstallationSchema }).strict()
3558
+ z31.object({ installation: localSetupInstallationSchema }).strict()
3517
3559
  ]);
3518
3560
  async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
3519
3561
  const path = join4(projectDir, ".siteplane/credentials.json");
@@ -3586,6 +3628,12 @@ async function writeCredentialsAtomically(path, credentials) {
3586
3628
  try {
3587
3629
  await rename2(temporaryPath, path);
3588
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
+ }
3589
3637
  } catch (error) {
3590
3638
  await rm2(temporaryPath, { force: true });
3591
3639
  throw error;
@@ -3605,7 +3653,7 @@ async function gitPathMatches(projectDir, path, command) {
3605
3653
  // ../cli/dist/commands/init.js
3606
3654
  import { access as access3 } from "fs/promises";
3607
3655
  import { join as join7, relative as relative3 } from "path";
3608
- import { z as z33 } from "zod";
3656
+ import { z as z34 } from "zod";
3609
3657
 
3610
3658
  // ../cli/dist/commands/setup-preflight.js
3611
3659
  import { createHash as createHash2 } from "crypto";
@@ -3617,11 +3665,11 @@ import { parse as parseYaml } from "yaml";
3617
3665
  import { createRequire } from "module";
3618
3666
  import { readFile as readFile7 } from "fs/promises";
3619
3667
  import { join as join5 } from "path";
3620
- import { z as z31 } from "zod";
3621
- var packageSchema = z31.object({
3622
- name: z31.string().optional(),
3623
- version: z31.string(),
3624
- 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()
3625
3673
  });
3626
3674
  async function readInstalledPackage(projectDir, name2) {
3627
3675
  const require2 = createRequire(join5(projectDir, "package.json"));
@@ -3636,9 +3684,9 @@ async function readInstalledPackage(projectDir, name2) {
3636
3684
  throw new Error(`Install ${name2} with the canonical package manager before setup.`);
3637
3685
  }
3638
3686
  async function assertExactSetupPackages(projectDir, packages) {
3639
- const manifest = z31.object({
3640
- dependencies: z31.record(z31.string(), z31.string()).optional(),
3641
- 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()
3642
3690
  }).parse(JSON.parse(await readFile7(join5(projectDir, "package.json"), "utf8")));
3643
3691
  for (const [name2, version2] of [
3644
3692
  ["siteplane", packages.siteplane],
@@ -3655,7 +3703,7 @@ async function assertExactSetupPackages(projectDir, packages) {
3655
3703
  // ../cli/dist/commands/setup-preflight.js
3656
3704
  import { access as access2, readFile as readFile8, realpath, readdir, readlink } from "fs/promises";
3657
3705
  import { dirname as dirname6, join as join6, relative as relative2, resolve, sep } from "path";
3658
- import { z as z32 } from "zod";
3706
+ import { z as z33 } from "zod";
3659
3707
 
3660
3708
  // ../cli/dist/commands/setup-process.js
3661
3709
  import { spawn } from "child_process";
@@ -3756,29 +3804,29 @@ async function setupVercelApi(cwd, endpoint, body, method, options) {
3756
3804
  }
3757
3805
 
3758
3806
  // ../cli/dist/commands/setup-preflight.js
3759
- var manifestSchema = z32.object({
3760
- packageManager: z32.string().optional(),
3761
- engines: z32.object({ node: z32.string().optional() }).optional(),
3762
- dependencies: z32.record(z32.string(), z32.string()).optional(),
3763
- devDependencies: z32.record(z32.string(), z32.string()).optional(),
3764
- scripts: z32.record(z32.string(), z32.string()).optional(),
3765
- 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()
3766
3814
  });
3767
- var vercelProjectSchema = z32.object({
3768
- id: z32.string(),
3769
- accountId: z32.string(),
3770
- name: z32.string(),
3771
- nodeVersion: z32.string().nullable().optional(),
3772
- rootDirectory: z32.string().nullable().optional(),
3773
- framework: z32.string().nullable().optional(),
3774
- installCommand: z32.string().nullable().optional(),
3775
- buildCommand: z32.string().nullable().optional(),
3776
- link: z32.object({
3777
- type: z32.string(),
3778
- repo: z32.string().optional(),
3779
- repoId: z32.union([z32.string(), z32.number()]).optional(),
3780
- org: z32.string().optional(),
3781
- 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()
3782
3830
  }).nullable().optional()
3783
3831
  });
3784
3832
  var exists = async (path) => access2(path).then(() => true, () => false);
@@ -3835,9 +3883,9 @@ async function inspectSetupLocalProject(projectDir) {
3835
3883
  const rootManifest = manifestSchema.parse(JSON.parse(await readFile8(join6(lockfileRoot, "package.json"), "utf8")));
3836
3884
  if (lockfileRoot !== projectDirectory) {
3837
3885
  const workspaceFile = join6(lockfileRoot, "pnpm-workspace.yaml");
3838
- 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([
3839
- z32.array(z32.string()),
3840
- 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)
3841
3889
  ]).parse(rootManifest.workspaces);
3842
3890
  const selected = relative2(lockfileRoot, projectDirectory).split(sep).join("/");
3843
3891
  if (!workspace.some((pattern) => !pattern.startsWith("!") && minimatch(selected, pattern)) || workspace.some((pattern) => pattern.startsWith("!") && minimatch(selected, pattern.slice(1))))
@@ -3851,11 +3899,11 @@ async function inspectSetupLocalProject(projectDir) {
3851
3899
  break;
3852
3900
  }
3853
3901
  const lockText = await readFile8(join6(lockfileRoot, lockName), "utf8");
3854
- const npmLock = lockName === "package-lock.json" ? z32.object({
3855
- lockfileVersion: z32.number(),
3856
- packages: z32.record(z32.string(), z32.object({
3857
- version: z32.string().optional(),
3858
- 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()
3859
3907
  })).optional()
3860
3908
  }).parse(JSON.parse(lockText)) : null;
3861
3909
  async function version2(name3) {
@@ -3995,9 +4043,9 @@ async function setupPreflightCommand(input) {
3995
4043
  linkDirectory = dirname6(linkDirectory);
3996
4044
  if (!await exists(join6(linkDirectory, ".vercel/project.json")))
3997
4045
  fail("vercel_project_not_linked", "Link this application to its intended Vercel project before setup; Siteplane will not guess a target.");
3998
- const linked = z32.object({
3999
- projectId: z32.string().regex(/^prj_[A-Za-z0-9]+$/u),
4000
- 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)
4001
4049
  }).parse(JSON.parse(await readFile8(join6(linkDirectory, ".vercel/project.json"), "utf8")));
4002
4050
  const project = vercelProjectSchema.parse(await setupVercelApi(linkDirectory, `/v9/projects/${linked.projectId}?teamId=${linked.orgId}`));
4003
4051
  if (project.id !== linked.projectId || project.accountId !== linked.orgId)
@@ -4011,11 +4059,11 @@ async function setupPreflightCommand(input) {
4011
4059
  fail("vercel_production_branch_conflict", "The local branch differs from the bound Vercel Production branch.");
4012
4060
  if (project.link?.repo && project.link.org && !local.git.remote?.replace(/\.git$/u, "").endsWith(`${project.link.org}/${project.link.repo}`))
4013
4061
  fail("vercel_git_conflict", "The local origin repository differs from the Vercel Git connection.");
4014
- const env = z32.object({
4015
- envs: z32.array(z32.object({
4016
- key: z32.string(),
4017
- value: z32.string().optional(),
4018
- 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()
4019
4067
  }))
4020
4068
  }).parse(await setupVercelApi(linkDirectory, `/v10/projects/${linked.projectId}/env?teamId=${linked.orgId}`));
4021
4069
  const corepack = env.envs.some((item) => item.key === "ENABLE_EXPERIMENTAL_COREPACK" && item.value === "1" && item.target?.includes("production"));
@@ -4105,26 +4153,26 @@ async function initCommand(input) {
4105
4153
  ]
4106
4154
  };
4107
4155
  }
4108
- var siteSetupBootstrapDataSchema = z33.object({
4109
- credentialPurpose: z33.literal("site_setup"),
4110
- apiBaseUrl: z33.string().url(),
4111
- siteId: z33.string().uuid(),
4112
- publicSiteKeyId: z33.string().uuid(),
4113
- publicSiteKey: z33.string().trim().min(1),
4114
- accessToken: z33.string().trim().min(1),
4115
- siteRevalidationSecret: z33.string().regex(/^[A-Za-z0-9_-]{43}$/u),
4116
- 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(),
4117
4165
  packages: siteSetupPackagesSchema
4118
4166
  }).strict();
4119
- var featureBootstrapDataSchema = z33.object({
4120
- credentialPurpose: z33.enum(["analytics", "booking"]),
4121
- apiBaseUrl: z33.string().url(),
4122
- siteId: z33.string().uuid(),
4123
- 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)
4124
4172
  }).strict();
4125
- var bootstrapResponseSchema = z33.object({
4126
- ok: z33.literal(true),
4127
- data: z33.discriminatedUnion("credentialPurpose", [
4173
+ var bootstrapResponseSchema = z34.object({
4174
+ ok: z34.literal(true),
4175
+ data: z34.discriminatedUnion("credentialPurpose", [
4128
4176
  siteSetupBootstrapDataSchema,
4129
4177
  featureBootstrapDataSchema
4130
4178
  ])
@@ -4168,6 +4216,7 @@ async function persistSiteSetupBootstrap(input, bootstrap, appDirectory, install
4168
4216
  const previousCredentials = previous ? await access3(join7(input.projectDir, ".siteplane/credentials.json")).then(() => readLocalSetupCredentials(input.projectDir), () => null) : null;
4169
4217
  const credentialsPath = await writeLocalCredentials(input.projectDir, {
4170
4218
  ...previousCredentials && "adminSession" in previousCredentials && previousCredentials.adminSession ? { adminSession: previousCredentials.adminSession } : {},
4219
+ ...previousCredentials && "claimReceipt" in previousCredentials && previousCredentials.claimReceipt ? { claimReceipt: previousCredentials.claimReceipt } : {},
4171
4220
  accessToken: bootstrap.accessToken,
4172
4221
  siteRevalidationSecret: bootstrap.siteRevalidationSecret,
4173
4222
  ...installation ?? previousCredentials?.installation ? { installation: installation ?? previousCredentials?.installation } : {}
@@ -4283,7 +4332,7 @@ async function collectSourceFiles(directory) {
4283
4332
  import { execFile as execFile2 } from "child_process";
4284
4333
  import { readFile as readFile9 } from "fs/promises";
4285
4334
  import { promisify as promisify2 } from "util";
4286
- import { z as z34 } from "zod";
4335
+ import { z as z35 } from "zod";
4287
4336
 
4288
4337
  // ../cli/dist/scan/next-source-scan.js
4289
4338
  import ts2 from "typescript";
@@ -4980,32 +5029,32 @@ function isPositionalFieldReference(value) {
4980
5029
 
4981
5030
  // ../cli/dist/commands/site-setup.js
4982
5031
  var execFileAsync2 = promisify2(execFile2);
4983
- var safeErrorSchema = z34.object({
4984
- code: z34.string().trim().min(1),
4985
- 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)
4986
5035
  }).passthrough();
4987
- var errorResponseSchema2 = z34.object({ ok: z34.literal(false), error: safeErrorSchema }).passthrough();
4988
- var contextDataSchema = z34.object({
5036
+ var errorResponseSchema2 = z35.object({ ok: z35.literal(false), error: safeErrorSchema }).passthrough();
5037
+ var contextDataSchema = z35.object({
4989
5038
  task: siteSetupTaskSchema.refine((task) => task.run !== null)
4990
5039
  }).strict();
4991
- var contextResponseSchema = z34.object({ ok: z34.literal(true), data: contextDataSchema }).strict();
4992
- var applyDataSchema = z34.object({
4993
- status: z34.enum(["applied", "ready_for_review"]),
4994
- runId: z34.string().uuid().optional(),
4995
- contractVersionId: z34.string().uuid().optional(),
4996
- fieldContractHash: z34.string().regex(/^sha256:[0-9a-f]{64}$/u),
4997
- editorDefinitionHash: z34.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
4998
- fieldCount: z34.number().int().nonnegative().optional(),
4999
- 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()
5000
5049
  }).strict();
5001
- var applyResponseSchema = z34.object({ ok: z34.literal(true), data: applyDataSchema }).strict();
5002
- var verifyDataSchema = z34.object({
5003
- status: z34.literal("ready_for_review"),
5004
- runId: z34.string().uuid().optional(),
5005
- deploymentOrigin: z34.string().url().optional(),
5006
- 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()
5007
5056
  }).strict();
5008
- var verifyResponseSchema = z34.object({ ok: z34.literal(true), data: verifyDataSchema }).strict();
5057
+ var verifyResponseSchema = z35.object({ ok: z35.literal(true), data: verifyDataSchema }).strict();
5009
5058
  async function siteSetupContextCommand(input) {
5010
5059
  const response = await postSiteSetup(input, "context", {});
5011
5060
  const parsed = contextResponseSchema.safeParse(response.payload);
@@ -5169,9 +5218,9 @@ async function siteSetupActivityCommand(input) {
5169
5218
  message: "Choose inspecting, integrating, deploying, verifying or repairing."
5170
5219
  };
5171
5220
  const response = await postSiteSetup(input, "activity", activity.data);
5172
- const parsed = z34.object({
5173
- ok: z34.literal(true),
5174
- 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()
5175
5224
  }).strict().safeParse(response.payload);
5176
5225
  return response.ok && parsed.success ? parsed.data.data : actionRequired(response.payload, "Setup activity could not be recorded.");
5177
5226
  }
@@ -5180,9 +5229,9 @@ async function siteSetupActivityCommand(input) {
5180
5229
  import { randomBytes, randomUUID as randomUUID4 } from "crypto";
5181
5230
  import { access as access4 } from "fs/promises";
5182
5231
  import { join as join9, relative as relative5 } from "path";
5183
- import { z as z35 } from "zod";
5184
- var bootstrapResponseSchema2 = z35.object({
5185
- ok: z35.literal(true),
5232
+ import { z as z36 } from "zod";
5233
+ var bootstrapResponseSchema2 = z36.object({
5234
+ ok: z36.literal(true),
5186
5235
  data: siteSetupBootstrapDataSchema
5187
5236
  }).strict();
5188
5237
  async function setupStartCommand(input) {
@@ -5256,9 +5305,9 @@ async function acknowledge(input, credentials) {
5256
5305
  if (!installation || !("accessToken" in credentials))
5257
5306
  throw new Error("Incomplete installation exchange.");
5258
5307
  const payload = await installationRequest(input, installation, "acknowledge");
5259
- z35.object({
5260
- ok: z35.literal(true),
5261
- 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()
5262
5311
  }).strict().parse(payload);
5263
5312
  await writeLocalSetupCredentials(input.projectDir, {
5264
5313
  ...credentials,
@@ -5279,9 +5328,9 @@ async function installationRequest(input, installation, action) {
5279
5328
  });
5280
5329
  const payload = await response.json();
5281
5330
  if (!response.ok) {
5282
- const error = z35.object({
5283
- error: z35.object({
5284
- 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)
5285
5334
  })
5286
5335
  }).safeParse(payload);
5287
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.");
@@ -5310,23 +5359,34 @@ async function exists2(path) {
5310
5359
  }
5311
5360
 
5312
5361
  // ../cli/dist/commands/setup-review.js
5313
- import { z as z36 } from "zod";
5314
- var responseSchema2 = z36.object({
5315
- ok: z36.literal(true),
5316
- data: z36.object({
5317
- reviewUrl: z36.string().url(),
5318
- expiresAt: z36.string().datetime({ offset: true })
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 })
5319
5368
  }).strict()
5320
5369
  }).strict();
5321
5370
  async function setupReviewCommand(input) {
5322
5371
  const [config, credentials] = await Promise.all([
5323
5372
  readProjectConfig(input.projectDir),
5324
- readLocalCredentials(input.projectDir)
5373
+ readLocalCredentials(input.projectDir).catch((error) => {
5374
+ if (error.code === "ENOENT")
5375
+ return null;
5376
+ throw error;
5377
+ })
5325
5378
  ]);
5326
- if (!credentials.installation)
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)
5327
5387
  return {
5328
5388
  status: "action_required",
5329
- code: "local_installation_missing",
5389
+ code: "local_credentials_missing",
5330
5390
  message: "Open this project's review from your Siteplane workspace. Guest review requires the original local installation credentials."
5331
5391
  };
5332
5392
  if (new URL(config.apiBaseUrl).origin !== new URL(credentials.installation.apiBaseUrl).origin)
@@ -5356,12 +5416,13 @@ async function setupReviewCommand(input) {
5356
5416
  throw new Error("Invalid review destination.");
5357
5417
  return { status: "ready", ...parsed.data.data };
5358
5418
  }
5359
- const denied = z36.object({
5360
- error: z36.object({
5361
- code: z36.enum([
5419
+ const denied = z37.object({
5420
+ error: z37.object({
5421
+ code: z37.enum([
5362
5422
  "invalid_installation",
5363
5423
  "already_claimed",
5364
5424
  "project_expired",
5425
+ "revoked",
5365
5426
  "review_not_ready",
5366
5427
  "rate_limited",
5367
5428
  "review_access_unavailable"
@@ -5371,7 +5432,7 @@ async function setupReviewCommand(input) {
5371
5432
  return {
5372
5433
  status: "action_required",
5373
5434
  code: denied.success ? denied.data.error.code : "review_access_unavailable",
5374
- message: "The review link is unavailable. Check the existing setup status; do not create another project."
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."
5375
5436
  };
5376
5437
  } catch {
5377
5438
  return {
@@ -5656,8 +5717,8 @@ async function assertSourcePath(root, target) {
5656
5717
  import { randomUUID as randomUUID6 } from "crypto";
5657
5718
  import { lstat as lstat3, mkdir as mkdir7, open as open4, readFile as readFile11, rm as rm4, rmdir } from "fs/promises";
5658
5719
  import { resolve as resolve2 } from "path";
5659
- import { z as z37 } from "zod";
5660
- var ownerSchema = z37.object({ pid: z37.number().int().positive(), nonce: z37.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();
5661
5722
  async function withSetupLock(projectDir, work) {
5662
5723
  const gitPath = (await setupProcess("git", ["rev-parse", "--git-path", "siteplane-setup.lock"], { cwd: projectDir })).trim();
5663
5724
  const path = resolve2(projectDir, gitPath);
@@ -5721,23 +5782,23 @@ import { execFile as execFile3 } from "child_process";
5721
5782
  import { lstat as lstat4, readFile as readFile12, writeFile as writeFile5, mkdir as mkdir8 } from "fs/promises";
5722
5783
  import { dirname as dirname8, isAbsolute as isAbsolute2, join as join11, relative as relative7, resolve as resolve3, sep as sep3 } from "path";
5723
5784
  import { isDeepStrictEqual, promisify as promisify3 } from "util";
5724
- import { z as z38 } from "zod";
5785
+ import { z as z39 } from "zod";
5725
5786
  var execute = promisify3(execFile3);
5726
5787
  var name = ".siteplane/build-source.json";
5727
- var oid = z38.string().regex(/^[0-9a-f]{40}$/u);
5728
- var entrySchema = z38.object({
5729
- path: z38.string().min(1).max(4096),
5730
- mode: z38.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"]),
5731
5792
  oid
5732
5793
  }).strict();
5733
- var schema = z38.object({
5734
- version: z38.literal(2),
5794
+ var schema = z39.object({
5795
+ version: z39.literal(2),
5735
5796
  revision: oid,
5736
- commit: z38.string().min(1).max(1048576),
5737
- entries: z38.array(entrySchema).min(1).max(1e5),
5738
- providerConfigurations: z38.array(z38.object({
5739
- path: z38.string().max(4096).regex(/(?:^|\/)vercel\.json$/u),
5740
- source: z38.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)
5741
5802
  }).strict()).max(1e3)
5742
5803
  }).strict();
5743
5804
  async function writeBuildProvenance(checkout, revision) {
@@ -5786,38 +5847,38 @@ import { createHash as createHash4, randomBytes as randomBytes2, randomUUID as r
5786
5847
  import { access as access6, mkdir as mkdir9, mkdtemp, rm as rm5, writeFile as writeFile6 } from "fs/promises";
5787
5848
  import { tmpdir } from "os";
5788
5849
  import { join as join12 } from "path";
5789
- import { z as z39 } from "zod";
5790
- var envSchema = z39.object({
5791
- id: z39.string(),
5792
- key: z39.string(),
5793
- target: z39.array(z39.string()),
5794
- type: z39.string(),
5795
- comment: z39.string().optional(),
5796
- updatedAt: z39.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()
5797
5858
  });
5798
- var deploymentSchema = z39.object({
5799
- id: z39.string(),
5800
- projectId: z39.string(),
5801
- ownerId: z39.string().optional(),
5802
- target: z39.string().nullable(),
5803
- readyState: z39.string(),
5804
- createdAt: z39.number(),
5805
- url: z39.string(),
5806
- meta: z39.record(z39.string(), z39.unknown()).optional(),
5807
- gitSource: z39.object({ sha: z39.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()
5808
5869
  });
5809
- var buildProofSchema = z39.object({
5810
- node: z39.string(),
5811
- packageManager: z39.enum(["npm", "pnpm"]),
5812
- packageManagerVersion: z39.string(),
5813
- lockfileHash: z39.string(),
5814
- revision: z39.string(),
5815
- fieldContractHash: z39.string(),
5816
- siteplane: z39.string(),
5817
- runtimeNext: z39.string(),
5818
- analytics: z39.string().optional(),
5819
- next: z39.string(),
5820
- react: z39.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()
5821
5882
  }).strict();
5822
5883
  var digest = (value) => `sha256:${createHash4("sha256").update(stableJsonStringify(value)).digest("hex")}`;
5823
5884
  function fail2(code, message) {
@@ -5902,12 +5963,12 @@ async function setupDeployCommand(input, deps = defaults) {
5902
5963
  remaining();
5903
5964
  return result2;
5904
5965
  };
5905
- const domains = z39.object({
5906
- domains: z39.array(z39.object({
5907
- name: z39.string(),
5908
- verified: z39.boolean(),
5909
- redirect: z39.string().nullable().optional(),
5910
- gitBranch: z39.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()
5911
5972
  }))
5912
5973
  }).parse(await api(`/v9/projects/${provider.projectId}/domains?${scope}`)).domains.filter((domain) => domain.verified && !domain.redirect && !domain.gitBranch);
5913
5974
  const origin = record?.origin ?? (domains.length === 1 ? `https://${domains[0].name}` : null);
@@ -5915,7 +5976,7 @@ async function setupDeployCommand(input, deps = defaults) {
5915
5976
  fail2("production_origin_ambiguous", "The linked project needs one verified canonical Production domain, or the existing setup domain must still belong to it.");
5916
5977
  if (record && (record.projectId !== provider.projectId || record.teamId !== provider.teamId))
5917
5978
  fail2("deployment_target_conflict", "This setup already belongs to a different provider project/team. Restore its original local link.");
5918
- const listEnv = async () => z39.object({ envs: z39.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;
5919
5980
  let env = await listEnv();
5920
5981
  const owned = (key) => {
5921
5982
  const matches2 = env.filter((item) => item.key === key && item.target.includes("production"));
@@ -5988,9 +6049,9 @@ async function setupDeployCommand(input, deps = defaults) {
5988
6049
  expectedOperationId: record?.operationId ?? null,
5989
6050
  record: next
5990
6051
  });
5991
- const parsed = z39.object({
5992
- ok: z39.literal(true),
5993
- data: z39.object({ record: setupDeploymentRecordSchema }).strict()
6052
+ const parsed = z40.object({
6053
+ ok: z40.literal(true),
6054
+ data: z40.object({ record: setupDeploymentRecordSchema }).strict()
5994
6055
  }).strict().safeParse(result2.payload);
5995
6056
  if (!result2.ok || !parsed.success || stableJsonStringify(parsed.data.data.record) !== stableJsonStringify(next))
5996
6057
  fail2("deployment_record_unconfirmed", "The setup deployment record was not acknowledged. Reload context before continuing; no deployment is blindly repeated.");
@@ -6040,7 +6101,7 @@ async function setupDeployCommand(input, deps = defaults) {
6040
6101
  const item = owned(key);
6041
6102
  if (key === "SITEPLANE_ADMIN_SESSION_SECRET" && item && record.phase === "verified")
6042
6103
  continue;
6043
- const current = item ? z39.object({ key: z39.literal(key), value: z39.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;
6044
6105
  if (current !== value)
6045
6106
  pending.push({
6046
6107
  key,
@@ -6065,7 +6126,7 @@ async function setupDeployCommand(input, deps = defaults) {
6065
6126
  const item = owned(key);
6066
6127
  if (!item)
6067
6128
  fail2("environment_write_unconfirmed", "A Siteplane Production binding was not persisted; retry the same configuration.");
6068
- const observed = z39.object({ key: z39.literal(key), value: z39.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}`));
6069
6130
  if (observed.value !== value)
6070
6131
  fail2("environment_write_unconfirmed", "The provider readback does not match the authorized Siteplane value; no deployment was started.");
6071
6132
  }
@@ -6078,7 +6139,7 @@ async function setupDeployCommand(input, deps = defaults) {
6078
6139
  const detail = async (id) => deploymentSchema.parse(await api(`/v13/deployments/${encodeURIComponent(id)}?${scope}&withGitRepoInfo=true`));
6079
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);
6080
6141
  const discover = async () => {
6081
- const result2 = z39.object({ deployments: z39.array(z39.object({ uid: z39.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`));
6082
6143
  const candidates = [];
6083
6144
  for (const item of result2.deployments) {
6084
6145
  const found = await detail(item.uid);
@@ -6252,9 +6313,91 @@ async function setupDeployCommand(input, deps = defaults) {
6252
6313
  }
6253
6314
  }
6254
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
+
6255
6398
  // src/bin/run-siteplane.ts
6256
6399
  async function runSiteplaneCli(args, dependencies = createDefaultDependencies()) {
6257
- 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");
6258
6401
  const missingDeploy = args[0] === "setup" && args[1] === "deploy" && !await access7(join13(dependencies.cwd(), "siteplane.config.json")).then(
6259
6402
  () => true,
6260
6403
  () => false
@@ -6491,6 +6634,20 @@ async function runSetupCommand(args, dependencies) {
6491
6634
  dependencies.stdout(JSON.stringify(result2, null, 2));
6492
6635
  return { exitCode: result2.status === "ready" ? 0 : 1 };
6493
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
+ }
6494
6651
  if (area === "context") {
6495
6652
  const result2 = await dependencies.commands.siteSetupContextCommand({
6496
6653
  projectDir,
@@ -6537,7 +6694,7 @@ async function runSetupCommand(args, dependencies) {
6537
6694
  return { exitCode: result2.status === "ready_for_review" ? 0 : 1 };
6538
6695
  }
6539
6696
  dependencies.stdout(
6540
- "Usage: siteplane setup <start|preflight|prepare|context|activity|apply|deploy|verify|review>"
6697
+ "Usage: siteplane setup <start|preflight|prepare|context|activity|apply|deploy|verify|review|claim>"
6541
6698
  );
6542
6699
  return { exitCode: 1 };
6543
6700
  }
@@ -6678,6 +6835,7 @@ function createDefaultDependencies() {
6678
6835
  setupPreflightCommand,
6679
6836
  setupStartCommand,
6680
6837
  setupReviewCommand,
6838
+ setupClaimCommand,
6681
6839
  setupPrepareCommand,
6682
6840
  setupDeployCommand,
6683
6841
  initCommand,