siteplane 0.1.40 → 0.1.41

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.
@@ -1286,11 +1286,48 @@ var CONTINUE_SITE_SETUP_LOCATOR_HINT_MAX_BYTES = 512;
1286
1286
  var CONTINUE_SITE_SETUP_REQUESTED_LABEL_MAX_BYTES = 120;
1287
1287
  var CONTINUE_SITE_SETUP_REQUESTED_SECTION_MAX_BYTES = 120;
1288
1288
  var CONTINUE_SITE_SETUP_REQUESTED_SUBSECTION_MAX_BYTES = 120;
1289
+ var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH = 2e3;
1290
+ var SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES = 8e3;
1289
1291
  var CONTINUE_SITE_SETUP_ITEMS_MAX_BYTES = 32 * 1024;
1290
1292
  var CONTINUE_SITE_SETUP_HTTP_BODY_MAX_BYTES = 64 * 1024;
1291
1293
  var siteSetupRunStatusSchema = z14.enum(SITE_SETUP_RUN_STATUSES);
1292
1294
  var siteSetupRunModeSchema = z14.enum(SITE_SETUP_RUN_MODES);
1293
1295
  var siteSetupErrorCodeSchema = z14.enum(SITE_SETUP_ERROR_CODES);
1296
+ var siteSetupTaskSchema = z14.object({
1297
+ contractVersion: z14.literal("siteplane.setup-task.v1"),
1298
+ workflow: z14.enum(["initial_setup", "structure_update"]),
1299
+ goal: z14.string().min(1),
1300
+ modules: z14.tuple([z14.literal("visual_editor")]),
1301
+ packages: z14.object({
1302
+ siteplane: z14.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u),
1303
+ runtimeNext: z14.string().regex(/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/u)
1304
+ }).strict(),
1305
+ communication: z14.object({
1306
+ beforeSourceChanges: z14.string().min(1),
1307
+ updates: z14.array(z14.string().min(1)).min(1),
1308
+ blocker: z14.string().min(1)
1309
+ }).strict(),
1310
+ discovery: z14.object({
1311
+ inspectPublicRoutes: z14.boolean(),
1312
+ contentKinds: z14.array(z14.enum(["text", "longText", "link", "image"])).min(1),
1313
+ rules: z14.array(z14.string().min(1)).min(1)
1314
+ }).strict(),
1315
+ steps: z14.array(z14.object({
1316
+ id: z14.enum([
1317
+ "inspect_repository",
1318
+ "install_packages",
1319
+ "instrument_fields",
1320
+ "apply_contract",
1321
+ "deploy_production",
1322
+ "verify_deployment"
1323
+ ]),
1324
+ instruction: z14.string().min(1)
1325
+ }).strict()).length(6),
1326
+ completion: z14.object({
1327
+ verifiedStatus: z14.literal("ready_for_review"),
1328
+ instruction: z14.string().min(1)
1329
+ }).strict()
1330
+ }).strict();
1294
1331
  var editorFieldSchema = z14.object({
1295
1332
  fieldId: fieldIdSchema,
1296
1333
  label: z14.string().trim().min(1),
@@ -1375,6 +1412,7 @@ var editorDefinitionV1Schema = z14.object({
1375
1412
  }
1376
1413
  });
1377
1414
  var forbiddenControlOrBidi = /[\u0000-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
1415
+ var forbiddenOwnerNoteControlOrBidi = /[\u0000-\u0008\u000b\u000c\u000e-\u001f\u007f-\u009f\u202a-\u202e\u2066-\u2069]/u;
1378
1416
  var unsafeLocator = /<\/?[a-z][^>]*>|\b(?:javascript|data:text\/html)\s*:|\bon[a-z]+\s*=/iu;
1379
1417
  var renderedPathSchema = z14.string().trim().transform((value) => value !== "/" ? value.replace(/\/+$/u, "") : value).superRefine((value, context) => {
1380
1418
  if (!value.startsWith("/") || value === "$global" || value.includes("?") || value.includes("#")) {
@@ -1427,6 +1465,20 @@ var setupCorrectionItemsSchema = z14.array(setupCorrectionItemSchema).max(CONTIN
1427
1465
  });
1428
1466
  }
1429
1467
  });
1468
+ var siteSetupOwnerEditabilityNoteSchema = z14.string().trim().max(SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_LENGTH).superRefine((value, context) => {
1469
+ if (utf8Bytes(value) > SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES) {
1470
+ context.addIssue({
1471
+ code: "custom",
1472
+ message: `ownerEditabilityNote exceeds ${SITE_SETUP_OWNER_EDITABILITY_NOTE_MAX_BYTES} UTF-8 bytes.`
1473
+ });
1474
+ }
1475
+ if (forbiddenOwnerNoteControlOrBidi.test(value)) {
1476
+ context.addIssue({
1477
+ code: "custom",
1478
+ message: "ownerEditabilityNote contains a forbidden control or bidi character."
1479
+ });
1480
+ }
1481
+ });
1430
1482
  var canonicalHashSchema = z14.string().regex(/^sha256:[0-9a-f]{64}$/iu);
1431
1483
  var deploymentRevisionSchema = normalizedSafeTextSchema(256, "deploymentRevision");
1432
1484
  var continueSiteSetupInputSchema = z14.object({
@@ -1434,7 +1486,15 @@ var continueSiteSetupInputSchema = z14.object({
1434
1486
  runId: z14.string().uuid(),
1435
1487
  expectedFieldContractHash: canonicalHashSchema,
1436
1488
  expectedDeploymentRevision: deploymentRevisionSchema,
1437
- correctionItems: setupCorrectionItemsSchema
1489
+ correctionItems: setupCorrectionItemsSchema,
1490
+ ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema.optional()
1491
+ }).strict();
1492
+ var saveSiteSetupOwnerNoteInputSchema = z14.object({
1493
+ siteId: z14.string().uuid(),
1494
+ runId: z14.string().uuid(),
1495
+ expectedFieldContractHash: canonicalHashSchema,
1496
+ expectedDeploymentRevision: deploymentRevisionSchema,
1497
+ ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema
1438
1498
  }).strict();
1439
1499
  var siteSetupContextInputSchema = z14.object({}).strict();
1440
1500
  var siteSetupApplyInputSchema = z14.object({
@@ -1599,6 +1659,7 @@ var FIELD_BRIDGE_MESSAGE_TYPES = [
1599
1659
  "siteplane:field-bridge:preview-ack",
1600
1660
  "siteplane:field-bridge:set-visual-control-state",
1601
1661
  "siteplane:field-bridge:missing-content",
1662
+ "siteplane:field-bridge:preview-scrolled",
1602
1663
  "siteplane:field-bridge:error"
1603
1664
  ];
1604
1665
  var canonicalFieldContractHashSchema = z15.string().regex(/^sha256:[0-9a-f]{64}$/u);
@@ -1729,6 +1790,10 @@ var fieldBridgeMissingContentMessageSchema = fieldBridgeBaseSchema.extend({
1729
1790
  suggestedSection: bridgeSectionSchema.optional()
1730
1791
  }).strict()
1731
1792
  });
1793
+ var fieldBridgePreviewScrolledMessageSchema = fieldBridgeBaseSchema.extend({
1794
+ type: z15.literal("siteplane:field-bridge:preview-scrolled"),
1795
+ payload: z15.object({ renderedPath: realRenderedPathSchema }).strict()
1796
+ });
1732
1797
  var fieldBridgeErrorMessageSchema = fieldBridgeBaseSchema.extend({
1733
1798
  type: z15.literal("siteplane:field-bridge:error"),
1734
1799
  payload: z15.object({
@@ -1748,6 +1813,7 @@ var fieldBridgeMessageSchema = z15.discriminatedUnion("type", [
1748
1813
  fieldBridgePreviewAckMessageSchema,
1749
1814
  fieldBridgeSetVisualControlStateMessageSchema,
1750
1815
  fieldBridgeMissingContentMessageSchema,
1816
+ fieldBridgePreviewScrolledMessageSchema,
1751
1817
  fieldBridgeErrorMessageSchema
1752
1818
  ]);
1753
1819
 
@@ -2920,49 +2986,54 @@ async function bookingTestCommand(input) {
2920
2986
  });
2921
2987
  }
2922
2988
 
2923
- // ../cli/dist/commands/connect.js
2924
- import { spawn } from "child_process";
2925
- import { randomBytes } from "crypto";
2926
- import { z as z27 } from "zod";
2927
-
2928
- // ../cli/dist/config/credentials.js
2929
- import { execFile } from "child_process";
2989
+ // ../cli/dist/config/project-config.js
2990
+ import { access, chmod, open, readFile as readFile5, rename, rm } from "fs/promises";
2930
2991
  import { randomUUID as randomUUID2 } from "crypto";
2931
- import { chmod, mkdir as mkdir5, open, readFile as readFile5, rename, rm } from "fs/promises";
2932
- import { dirname as dirname5, join as join3, relative } from "path";
2933
- import { promisify } from "util";
2992
+ import { join as join3 } from "path";
2934
2993
  import { z as z24 } from "zod";
2935
- var siteplaneCredentialsSchema = z24.object({
2936
- accessToken: z24.string().trim().min(1),
2937
- siteRevalidationSecret: z24.string().trim().min(1)
2994
+ var siteplaneProjectConfigSchema = z24.object({
2995
+ version: z24.literal(1),
2996
+ apiBaseUrl: z24.string().url(),
2997
+ siteId: z24.string().uuid(),
2998
+ publicSiteKeyId: z24.string().uuid(),
2999
+ publicSiteKey: z24.string().trim().min(1),
3000
+ fieldContractHash: z24.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
2938
3001
  }).strict();
2939
- async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
2940
- const path = join3(projectDir, ".siteplane/credentials.json");
2941
- const isTrackedFile = options.isTrackedFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "ls-files"));
2942
- const isIgnoredFile = options.isIgnoredFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "check-ignore"));
2943
- if (await isTrackedFile(path)) {
2944
- throw new Error("Refusing to write Siteplane credentials into a tracked file.");
3002
+ async function readProjectPackageJson(projectDir) {
3003
+ return JSON.parse(await readFile5(join3(projectDir, "package.json"), "utf8"));
3004
+ }
3005
+ async function detectNextProject(projectDir) {
3006
+ const packageJson = await readProjectPackageJson(projectDir).catch(() => null);
3007
+ if (packageJson?.dependencies?.next || packageJson?.devDependencies?.next) {
3008
+ return true;
2945
3009
  }
2946
- if (!await isIgnoredFile(path)) {
2947
- throw new Error("Add .siteplane/credentials.json to .gitignore before running Siteplane connect.");
3010
+ for (const fileName of [
3011
+ "next.config.js",
3012
+ "next.config.mjs",
3013
+ "next.config.ts"
3014
+ ]) {
3015
+ try {
3016
+ await access(join3(projectDir, fileName));
3017
+ return true;
3018
+ } catch {
3019
+ }
2948
3020
  }
2949
- return path;
3021
+ return false;
2950
3022
  }
2951
- async function writeLocalCredentials(projectDir, credentials, options = {}) {
2952
- const path = await assertLocalCredentialsPathSafe(projectDir, options);
2953
- const parsed = siteplaneCredentialsSchema.parse(credentials);
2954
- await mkdir5(dirname5(path), { recursive: true, mode: 448 });
2955
- await writeCredentialsAtomically(path, parsed);
3023
+ async function writeProjectConfig(projectDir, config) {
3024
+ const path = join3(projectDir, "siteplane.config.json");
3025
+ const parsed = siteplaneProjectConfigSchema.parse(config);
3026
+ await writeJsonAtomically(path, parsed, 420);
2956
3027
  return path;
2957
3028
  }
2958
- async function readLocalCredentials(projectDir) {
2959
- return siteplaneCredentialsSchema.parse(JSON.parse(await readFile5(join3(projectDir, ".siteplane/credentials.json"), "utf8")));
3029
+ async function readProjectConfig(projectDir) {
3030
+ return siteplaneProjectConfigSchema.parse(JSON.parse(await readFile5(join3(projectDir, "siteplane.config.json"), "utf8")));
2960
3031
  }
2961
- async function writeCredentialsAtomically(path, credentials) {
3032
+ async function writeJsonAtomically(path, value, mode) {
2962
3033
  const temporaryPath = `${path}.${randomUUID2()}.tmp`;
2963
- const file = await open(temporaryPath, "wx", 384);
3034
+ const file = await open(temporaryPath, "wx", mode);
2964
3035
  try {
2965
- await file.writeFile(`${JSON.stringify(credentials, null, 2)}
3036
+ await file.writeFile(`${JSON.stringify(value, null, 2)}
2966
3037
  `, "utf8");
2967
3038
  await file.sync();
2968
3039
  } catch (error) {
@@ -2973,71 +3044,51 @@ async function writeCredentialsAtomically(path, credentials) {
2973
3044
  await file.close();
2974
3045
  try {
2975
3046
  await rename(temporaryPath, path);
2976
- await chmod(path, 384);
3047
+ await chmod(path, mode);
2977
3048
  } catch (error) {
2978
3049
  await rm(temporaryPath, { force: true });
2979
3050
  throw error;
2980
3051
  }
2981
3052
  }
2982
- var execFileAsync = promisify(execFile);
2983
- async function gitPathMatches(projectDir, path, command) {
2984
- const args = command === "check-ignore" ? ["check-ignore", "--quiet", relative(projectDir, path)] : ["ls-files", "--error-unmatch", relative(projectDir, path)];
2985
- try {
2986
- await execFileAsync("git", args, { cwd: projectDir });
2987
- return true;
2988
- } catch {
2989
- return false;
2990
- }
2991
- }
2992
3053
 
2993
- // ../cli/dist/config/project-config.js
2994
- import { access, chmod as chmod2, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
3054
+ // ../cli/dist/config/credentials.js
3055
+ import { execFile } from "child_process";
2995
3056
  import { randomUUID as randomUUID3 } from "crypto";
2996
- import { join as join4 } from "path";
3057
+ import { chmod as chmod2, mkdir as mkdir5, open as open2, readFile as readFile6, rename as rename2, rm as rm2 } from "fs/promises";
3058
+ import { dirname as dirname5, join as join4, relative } from "path";
3059
+ import { promisify } from "util";
2997
3060
  import { z as z25 } from "zod";
2998
- var siteplaneProjectConfigSchema = z25.object({
2999
- version: z25.literal(1),
3000
- apiBaseUrl: z25.string().url(),
3001
- siteId: z25.string().uuid(),
3002
- publicSiteKeyId: z25.string().uuid(),
3003
- publicSiteKey: z25.string().trim().min(1),
3004
- fieldContractHash: z25.string().regex(/^sha256:[0-9a-f]{64}$/iu).optional()
3061
+ var siteplaneCredentialsSchema = z25.object({
3062
+ accessToken: z25.string().trim().min(1),
3063
+ siteRevalidationSecret: z25.string().trim().min(1)
3005
3064
  }).strict();
3006
- async function readProjectPackageJson(projectDir) {
3007
- return JSON.parse(await readFile6(join4(projectDir, "package.json"), "utf8"));
3008
- }
3009
- async function detectNextProject(projectDir) {
3010
- const packageJson = await readProjectPackageJson(projectDir).catch(() => null);
3011
- if (packageJson?.dependencies?.next || packageJson?.devDependencies?.next) {
3012
- return true;
3065
+ async function assertLocalCredentialsPathSafe(projectDir, options = {}) {
3066
+ const path = join4(projectDir, ".siteplane/credentials.json");
3067
+ const isTrackedFile = options.isTrackedFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "ls-files"));
3068
+ const isIgnoredFile = options.isIgnoredFile ?? ((targetPath) => gitPathMatches(projectDir, targetPath, "check-ignore"));
3069
+ if (await isTrackedFile(path)) {
3070
+ throw new Error("Refusing to write Siteplane credentials into a tracked file.");
3013
3071
  }
3014
- for (const fileName of [
3015
- "next.config.js",
3016
- "next.config.mjs",
3017
- "next.config.ts"
3018
- ]) {
3019
- try {
3020
- await access(join4(projectDir, fileName));
3021
- return true;
3022
- } catch {
3023
- }
3072
+ if (!await isIgnoredFile(path)) {
3073
+ throw new Error("Add .siteplane/credentials.json to .gitignore before running Siteplane init.");
3024
3074
  }
3025
- return false;
3075
+ return path;
3026
3076
  }
3027
- async function writeProjectConfig(projectDir, config) {
3028
- const path = join4(projectDir, "siteplane.config.json");
3029
- const parsed = siteplaneProjectConfigSchema.parse(config);
3030
- await writeJsonAtomically(path, parsed, 420);
3077
+ async function writeLocalCredentials(projectDir, credentials, options = {}) {
3078
+ const path = await assertLocalCredentialsPathSafe(projectDir, options);
3079
+ const parsed = siteplaneCredentialsSchema.parse(credentials);
3080
+ await mkdir5(dirname5(path), { recursive: true, mode: 448 });
3081
+ await writeCredentialsAtomically(path, parsed);
3031
3082
  return path;
3032
3083
  }
3033
- async function readProjectConfig(projectDir) {
3034
- return siteplaneProjectConfigSchema.parse(JSON.parse(await readFile6(join4(projectDir, "siteplane.config.json"), "utf8")));
3084
+ async function readLocalCredentials(projectDir) {
3085
+ return siteplaneCredentialsSchema.parse(JSON.parse(await readFile6(join4(projectDir, ".siteplane/credentials.json"), "utf8")));
3035
3086
  }
3036
- async function writeJsonAtomically(path, value, mode) {
3087
+ async function writeCredentialsAtomically(path, credentials) {
3037
3088
  const temporaryPath = `${path}.${randomUUID3()}.tmp`;
3038
- const file = await open2(temporaryPath, "wx", mode);
3089
+ const file = await open2(temporaryPath, "wx", 384);
3039
3090
  try {
3040
- await file.writeFile(`${JSON.stringify(value, null, 2)}
3091
+ await file.writeFile(`${JSON.stringify(credentials, null, 2)}
3041
3092
  `, "utf8");
3042
3093
  await file.sync();
3043
3094
  } catch (error) {
@@ -3048,12 +3099,22 @@ async function writeJsonAtomically(path, value, mode) {
3048
3099
  await file.close();
3049
3100
  try {
3050
3101
  await rename2(temporaryPath, path);
3051
- await chmod2(path, mode);
3102
+ await chmod2(path, 384);
3052
3103
  } catch (error) {
3053
3104
  await rm2(temporaryPath, { force: true });
3054
3105
  throw error;
3055
3106
  }
3056
3107
  }
3108
+ var execFileAsync = promisify(execFile);
3109
+ async function gitPathMatches(projectDir, path, command) {
3110
+ const args = command === "check-ignore" ? ["check-ignore", "--quiet", relative(projectDir, path)] : ["ls-files", "--error-unmatch", relative(projectDir, path)];
3111
+ try {
3112
+ await execFileAsync("git", args, { cwd: projectDir });
3113
+ return true;
3114
+ } catch {
3115
+ return false;
3116
+ }
3117
+ }
3057
3118
 
3058
3119
  // ../cli/dist/commands/init.js
3059
3120
  import { join as join5 } from "path";
@@ -3071,9 +3132,9 @@ async function initCommand(input) {
3071
3132
  return {
3072
3133
  ...paths,
3073
3134
  nextSteps: [
3074
- "npx siteplane setup context",
3075
- "Instrument the site and create EditorDefinitionV1.",
3076
- "npx siteplane setup apply --definition /tmp/siteplane-editor.json"
3135
+ "Run npx siteplane setup context and read the returned task.",
3136
+ "Before source changes, briefly tell the user what Siteplane requested and what you will do.",
3137
+ "Follow the returned steps through setup verify and stop only at ready_for_review or action_required."
3077
3138
  ]
3078
3139
  };
3079
3140
  }
@@ -3192,149 +3253,6 @@ function readErrorMessage(payload) {
3192
3253
  return null;
3193
3254
  }
3194
3255
 
3195
- // ../cli/dist/commands/connect.js
3196
- var claimResponseSchema = z27.object({
3197
- ok: z27.literal(true),
3198
- data: z27.object({
3199
- pairingId: z27.string().uuid(),
3200
- status: z27.literal("approval_required"),
3201
- approvalUrl: z27.string().url()
3202
- }).passthrough()
3203
- }).strict();
3204
- var waitingResponseSchema = z27.object({
3205
- ok: z27.literal(true),
3206
- data: z27.object({ status: z27.literal("approval_required") }).strict()
3207
- }).strict();
3208
- var bootstrapResponseSchema2 = z27.object({
3209
- ok: z27.literal(true),
3210
- data: siteSetupBootstrapDataSchema
3211
- }).strict();
3212
- async function connectCommand(input) {
3213
- if (!await detectNextProject(input.projectDir)) {
3214
- throw new Error("Siteplane connect currently supports Next.js projects.");
3215
- }
3216
- await assertLocalCredentialsPathSafe(input.projectDir, {
3217
- ...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
3218
- ...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
3219
- });
3220
- const fetcher = input.fetcher ?? fetch;
3221
- const pollSecret = randomBytes(32).toString("base64url");
3222
- const envelopeKey = randomBytes(32).toString("base64url");
3223
- const endpoint = `${input.apiBaseUrl.replace(/\/$/, "")}/api/cli/connect`;
3224
- const headers = createHeaders(input);
3225
- const claimResponse = await fetcher(endpoint, {
3226
- method: "POST",
3227
- headers,
3228
- body: JSON.stringify({
3229
- action: "claim",
3230
- pairingCode: input.pairingCode.trim().toUpperCase(),
3231
- pollSecret,
3232
- envelopeKey,
3233
- agentLabel: input.agentLabel?.trim() || null
3234
- })
3235
- });
3236
- const claimPayload = await readJson(claimResponse);
3237
- const claim = claimResponseSchema.safeParse(claimPayload);
3238
- if (!claimResponse.ok || !claim.success) {
3239
- throw new Error(readErrorMessage2(claimPayload) ?? "Siteplane pairing failed.");
3240
- }
3241
- let browserOpened = false;
3242
- try {
3243
- await (input.openBrowser ?? openInDefaultBrowser)(claim.data.data.approvalUrl);
3244
- browserOpened = true;
3245
- } catch {
3246
- }
3247
- input.onApprovalRequired?.({
3248
- approvalUrl: claim.data.data.approvalUrl,
3249
- browserOpened
3250
- });
3251
- const wait = input.wait ?? ((milliseconds) => new Promise((resolve2) => setTimeout(resolve2, milliseconds)));
3252
- let bootstrap = null;
3253
- for (; ; ) {
3254
- const pollResponse = await fetcher(endpoint, {
3255
- method: "POST",
3256
- headers,
3257
- body: JSON.stringify({
3258
- action: "poll",
3259
- pairingId: claim.data.data.pairingId,
3260
- pollSecret,
3261
- envelopeKey
3262
- })
3263
- });
3264
- const pollPayload = await readJson(pollResponse);
3265
- const ready = bootstrapResponseSchema2.safeParse(pollPayload);
3266
- if (pollResponse.ok && ready.success) {
3267
- bootstrap = ready.data.data;
3268
- break;
3269
- }
3270
- if (pollResponse.status !== 202 || !waitingResponseSchema.safeParse(pollPayload).success) {
3271
- throw new Error(readErrorMessage2(pollPayload) ?? "Siteplane pairing was not approved.");
3272
- }
3273
- await wait(1500);
3274
- }
3275
- const paths = await persistSiteSetupBootstrap({
3276
- projectDir: input.projectDir,
3277
- setupToken: "pairing",
3278
- apiBaseUrl: input.apiBaseUrl,
3279
- ...input.isIgnoredFile ? { isIgnoredFile: input.isIgnoredFile } : {},
3280
- ...input.isTrackedFile ? { isTrackedFile: input.isTrackedFile } : {}
3281
- }, bootstrap);
3282
- const acknowledgement = await fetcher(endpoint, {
3283
- method: "POST",
3284
- headers,
3285
- body: JSON.stringify({
3286
- action: "acknowledge",
3287
- pairingId: claim.data.data.pairingId,
3288
- pollSecret,
3289
- envelopeKey
3290
- })
3291
- });
3292
- if (!acknowledgement.ok) {
3293
- throw new Error("Siteplane setup acknowledgement failed.");
3294
- }
3295
- return {
3296
- ...paths,
3297
- nextSteps: [
3298
- "npx siteplane setup context",
3299
- "Instrument the site and create EditorDefinitionV1.",
3300
- "npx siteplane setup apply --definition /tmp/siteplane-editor.json"
3301
- ]
3302
- };
3303
- }
3304
- async function openInDefaultBrowser(url) {
3305
- const command = process.platform === "darwin" ? "open" : process.platform === "win32" ? "rundll32.exe" : "xdg-open";
3306
- const args = process.platform === "win32" ? ["url.dll,FileProtocolHandler", url] : [url];
3307
- await new Promise((resolve2, reject) => {
3308
- const child = spawn(command, args, { detached: true, stdio: "ignore" });
3309
- child.once("error", reject);
3310
- child.once("spawn", () => {
3311
- child.unref();
3312
- resolve2();
3313
- });
3314
- });
3315
- }
3316
- function createHeaders(input) {
3317
- return new Headers({
3318
- "content-type": "application/json",
3319
- ...input.vercelAutomationBypassSecret?.trim() ? { "x-vercel-protection-bypass": input.vercelAutomationBypassSecret.trim() } : {}
3320
- });
3321
- }
3322
- async function readJson(response) {
3323
- try {
3324
- return await response.json();
3325
- } catch {
3326
- return null;
3327
- }
3328
- }
3329
- function readErrorMessage2(payload) {
3330
- if (!payload || typeof payload !== "object" || !("error" in payload))
3331
- return null;
3332
- const error = payload.error;
3333
- if (!error || typeof error !== "object" || !("message" in error))
3334
- return null;
3335
- return typeof error.message === "string" ? error.message : null;
3336
- }
3337
-
3338
3256
  // ../cli/dist/commands/scan.js
3339
3257
  import { readdir } from "fs/promises";
3340
3258
  import { extname, join as join6 } from "path";
@@ -3380,7 +3298,7 @@ async function collectSourceFiles(directory) {
3380
3298
  import { execFile as execFile2 } from "child_process";
3381
3299
  import { readFile as readFile7 } from "fs/promises";
3382
3300
  import { promisify as promisify2 } from "util";
3383
- import { z as z28 } from "zod";
3301
+ import { z as z27 } from "zod";
3384
3302
 
3385
3303
  // ../cli/dist/scan/next-source-scan.js
3386
3304
  import ts2 from "typescript";
@@ -4047,52 +3965,54 @@ function isPositionalFieldReference(value) {
4047
3965
 
4048
3966
  // ../cli/dist/commands/site-setup.js
4049
3967
  var execFileAsync2 = promisify2(execFile2);
4050
- var safeErrorSchema = z28.object({
4051
- code: z28.string().trim().min(1),
4052
- message: z28.string().trim().min(1)
3968
+ var safeErrorSchema = z27.object({
3969
+ code: z27.string().trim().min(1),
3970
+ message: z27.string().trim().min(1)
4053
3971
  }).passthrough();
4054
- var errorResponseSchema2 = z28.object({ ok: z28.literal(false), error: safeErrorSchema }).passthrough();
4055
- var contextDataSchema = z28.object({
4056
- site: z28.object({ siteId: z28.string().uuid(), portalPath: z28.string() }),
4057
- run: z28.object({
4058
- runId: z28.string().uuid(),
4059
- mode: z28.enum(["initial", "update"]),
4060
- status: z28.enum([
3972
+ var errorResponseSchema2 = z27.object({ ok: z27.literal(false), error: safeErrorSchema }).passthrough();
3973
+ var contextDataSchema = z27.object({
3974
+ task: siteSetupTaskSchema,
3975
+ site: z27.object({ siteId: z27.string().uuid(), portalPath: z27.string() }),
3976
+ run: z27.object({
3977
+ runId: z27.string().uuid(),
3978
+ mode: z27.enum(["initial", "update"]),
3979
+ status: z27.enum([
4061
3980
  "waiting_for_agent",
4062
3981
  "working",
4063
3982
  "action_required",
4064
3983
  "ready_for_review"
4065
3984
  ]),
4066
- fieldContractHash: z28.string().nullable(),
4067
- deploymentOrigin: z28.string().nullable(),
4068
- deploymentRevision: z28.string().nullable(),
4069
- errorCode: z28.string().nullable(),
4070
- errorMessage: z28.string().nullable()
3985
+ fieldContractHash: z27.string().nullable(),
3986
+ deploymentOrigin: z27.string().nullable(),
3987
+ deploymentRevision: z27.string().nullable(),
3988
+ errorCode: z27.string().nullable(),
3989
+ errorMessage: z27.string().nullable()
4071
3990
  }),
4072
- structureHandoff: z28.object({
4073
- pendingFields: z28.array(setupCorrectionItemSchema).min(1).max(50)
3991
+ structureHandoff: z27.object({
3992
+ pendingFields: z27.array(setupCorrectionItemSchema).max(50),
3993
+ ownerEditabilityNote: siteSetupOwnerEditabilityNoteSchema
4074
3994
  }).strict().nullable(),
4075
- allowedTasks: z28.array(z28.string()),
4076
- requiredEnvironmentNames: z28.array(z28.string())
3995
+ allowedTasks: z27.array(z27.string()),
3996
+ requiredEnvironmentNames: z27.array(z27.string())
4077
3997
  }).strict();
4078
- var contextResponseSchema = z28.object({ ok: z28.literal(true), data: contextDataSchema }).strict();
4079
- var applyDataSchema = z28.object({
4080
- status: z28.enum(["applied", "ready_for_review"]),
4081
- runId: z28.string().uuid().optional(),
4082
- contractVersionId: z28.string().uuid().optional(),
4083
- fieldContractHash: z28.string().regex(/^sha256:[0-9a-f]{64}$/u),
4084
- editorDefinitionHash: z28.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
4085
- fieldCount: z28.number().int().nonnegative().optional(),
4086
- routeCount: z28.number().int().nonnegative().optional()
3998
+ var contextResponseSchema = z27.object({ ok: z27.literal(true), data: contextDataSchema }).strict();
3999
+ var applyDataSchema = z27.object({
4000
+ status: z27.enum(["applied", "ready_for_review"]),
4001
+ runId: z27.string().uuid().optional(),
4002
+ contractVersionId: z27.string().uuid().optional(),
4003
+ fieldContractHash: z27.string().regex(/^sha256:[0-9a-f]{64}$/u),
4004
+ editorDefinitionHash: z27.string().regex(/^sha256:[0-9a-f]{64}$/u).optional(),
4005
+ fieldCount: z27.number().int().nonnegative().optional(),
4006
+ routeCount: z27.number().int().nonnegative().optional()
4087
4007
  }).strict();
4088
- var applyResponseSchema = z28.object({ ok: z28.literal(true), data: applyDataSchema }).strict();
4089
- var verifyDataSchema = z28.object({
4090
- status: z28.literal("ready_for_review"),
4091
- runId: z28.string().uuid().optional(),
4092
- deploymentOrigin: z28.string().url().optional(),
4093
- deploymentRevision: z28.string().optional()
4008
+ var applyResponseSchema = z27.object({ ok: z27.literal(true), data: applyDataSchema }).strict();
4009
+ var verifyDataSchema = z27.object({
4010
+ status: z27.literal("ready_for_review"),
4011
+ runId: z27.string().uuid().optional(),
4012
+ deploymentOrigin: z27.string().url().optional(),
4013
+ deploymentRevision: z27.string().optional()
4094
4014
  }).strict();
4095
- var verifyResponseSchema = z28.object({ ok: z28.literal(true), data: verifyDataSchema }).strict();
4015
+ var verifyResponseSchema = z27.object({ ok: z27.literal(true), data: verifyDataSchema }).strict();
4096
4016
  async function siteSetupContextCommand(input) {
4097
4017
  const response = await postSiteSetup(input, "context", {});
4098
4018
  const parsed = contextResponseSchema.safeParse(response.payload);
@@ -4216,32 +4136,25 @@ async function readGitRevision(projectDir) {
4216
4136
  // src/bin/run-siteplane.ts
4217
4137
  async function runSiteplaneCli(args, dependencies = createDefaultDependencies()) {
4218
4138
  const [command, ...commandArgs] = args;
4219
- if (command === "connect") {
4220
- const pairingCode = commandArgs[0];
4221
- if (pairingCode === "--help" || pairingCode === "-h") {
4222
- dependencies.stdout("Usage: siteplane connect <pairing-code>");
4223
- return { exitCode: 0 };
4224
- }
4139
+ if (command === "init") {
4140
+ const setupToken = readOption(commandArgs, "--setup-token");
4225
4141
  const apiBaseUrl = readOption(commandArgs, "--api-base-url") ?? dependencies.env.SITEPLANE_API_BASE_URL ?? "https://siteplane.io";
4226
- if (!pairingCode || pairingCode.startsWith("--")) {
4227
- throw new Error("Usage: siteplane connect <pairing-code>");
4142
+ if (!setupToken) {
4143
+ throw new Error("Usage: siteplane init --setup-token <one-time-grant>");
4228
4144
  }
4229
- const result = await dependencies.commands.connectCommand({
4145
+ const result = await dependencies.commands.initCommand({
4230
4146
  projectDir: dependencies.cwd(),
4231
- pairingCode,
4147
+ setupToken,
4232
4148
  apiBaseUrl,
4233
- onApprovalRequired: ({ approvalUrl, browserOpened }) => {
4234
- dependencies.stdout(
4235
- browserOpened ? "Opened Siteplane in your browser. Approve the connection there:" : "Could not open a browser automatically. Approve the connection here:"
4236
- );
4237
- dependencies.stdout(approvalUrl);
4238
- },
4239
4149
  ...readOptionalVercelAutomationBypassSecret(dependencies.env)
4240
4150
  });
4241
4151
  dependencies.stdout(`Wrote ${result.configPath}`);
4242
4152
  dependencies.stdout(`Wrote ${result.credentialsPath}`);
4243
- dependencies.stdout("Siteplane connected. Next steps:");
4244
- for (const nextStep of result.nextSteps) dependencies.stdout(`- ${nextStep}`);
4153
+ dependencies.stdout(
4154
+ "Siteplane setup connection stored securely. Next steps:"
4155
+ );
4156
+ for (const nextStep of result.nextSteps)
4157
+ dependencies.stdout(`- ${nextStep}`);
4245
4158
  return { exitCode: 0 };
4246
4159
  }
4247
4160
  if (command === "booking") {
@@ -4258,10 +4171,10 @@ async function runSiteplaneCli(args, dependencies = createDefaultDependencies())
4258
4171
  return { exitCode: 0 };
4259
4172
  }
4260
4173
  if (command === "--help" || command === "-h") {
4261
- dependencies.stdout("Usage: siteplane <connect|setup|analytics|booking>");
4174
+ dependencies.stdout("Usage: siteplane <init|setup|analytics|booking>");
4262
4175
  return { exitCode: 0 };
4263
4176
  }
4264
- dependencies.stdout("Usage: siteplane <connect|setup|analytics|booking>");
4177
+ dependencies.stdout("Usage: siteplane <init|setup|analytics|booking>");
4265
4178
  return { exitCode: 1 };
4266
4179
  }
4267
4180
  async function runAnalyticsCommand(args, dependencies) {
@@ -4301,7 +4214,9 @@ async function runAnalyticsCommand(args, dependencies) {
4301
4214
  });
4302
4215
  const siteKeyLookup = getAnalyticsKeyLookup(rawPublicKey);
4303
4216
  if (!siteKeyLookup) {
4304
- throw new Error("Project config contains an invalid Analytics public site key.");
4217
+ throw new Error(
4218
+ "Project config contains an invalid Analytics public site key."
4219
+ );
4305
4220
  }
4306
4221
  const agentClient = readAnalyticsAgentClient(subcommandArgs);
4307
4222
  const result = await dependencies.commands.analyticsInitCommand({
@@ -4318,9 +4233,12 @@ async function runAnalyticsCommand(args, dependencies) {
4318
4233
  return { exitCode: 0 };
4319
4234
  }
4320
4235
  if (subcommand === "check" || subcommand === "sync") {
4321
- const sourceFilePaths = await dependencies.commands.resolveScanFilePaths([], {
4322
- projectDir
4323
- });
4236
+ const sourceFilePaths = await dependencies.commands.resolveScanFilePaths(
4237
+ [],
4238
+ {
4239
+ projectDir
4240
+ }
4241
+ );
4324
4242
  const artifactFilePaths = [join7(projectDir, ".siteplane/analytics.md")];
4325
4243
  const cspFilePaths = await existingPaths([
4326
4244
  join7(projectDir, "next.config.js"),
@@ -4378,7 +4296,12 @@ async function runAnalyticsCommand(args, dependencies) {
4378
4296
  config,
4379
4297
  payload,
4380
4298
  apply: subcommandArgs.includes("--apply"),
4381
- ...readOption(subcommandArgs, "--confirm-hash") ? { confirmHash: readOption(subcommandArgs, "--confirm-hash") } : {},
4299
+ ...readOption(subcommandArgs, "--confirm-hash") ? {
4300
+ confirmHash: readOption(
4301
+ subcommandArgs,
4302
+ "--confirm-hash"
4303
+ )
4304
+ } : {},
4382
4305
  yes: subcommandArgs.includes("--yes")
4383
4306
  }),
4384
4307
  dependencies
@@ -4425,9 +4348,7 @@ async function runSetupCommand(args, dependencies) {
4425
4348
  dependencies.stdout(JSON.stringify(result, null, 2));
4426
4349
  return { exitCode: result.status === "ready_for_review" ? 0 : 1 };
4427
4350
  }
4428
- dependencies.stdout(
4429
- "Usage: siteplane setup <context|apply|verify>"
4430
- );
4351
+ dependencies.stdout("Usage: siteplane setup <context|apply|verify>");
4431
4352
  return { exitCode: 1 };
4432
4353
  }
4433
4354
  async function runBookingCommand(args, dependencies) {
@@ -4461,9 +4382,12 @@ async function runBookingCommand(args, dependencies) {
4461
4382
  return { exitCode: 0 };
4462
4383
  }
4463
4384
  if (subcommand === "check") {
4464
- const sourceFilePaths = await dependencies.commands.resolveScanFilePaths(subcommandArgs, {
4465
- projectDir
4466
- });
4385
+ const sourceFilePaths = await dependencies.commands.resolveScanFilePaths(
4386
+ subcommandArgs,
4387
+ {
4388
+ projectDir
4389
+ }
4390
+ );
4467
4391
  const result = await dependencies.commands.bookingCheckCommand({
4468
4392
  manifestPath,
4469
4393
  sourceFilePaths
@@ -4516,9 +4440,7 @@ async function runBookingCommand(args, dependencies) {
4516
4440
  dependencies.stdout(await response.text());
4517
4441
  return { exitCode: response.ok ? 0 : 1 };
4518
4442
  }
4519
- dependencies.stdout(
4520
- "Usage: siteplane booking <init|check|sync|test>"
4521
- );
4443
+ dependencies.stdout("Usage: siteplane booking <init|check|sync|test>");
4522
4444
  return { exitCode: 1 };
4523
4445
  }
4524
4446
  async function readBookingProjectState(projectDir, manifestPath, dependencies) {
@@ -4547,7 +4469,9 @@ function createDefaultDependencies() {
4547
4469
  env: process.env,
4548
4470
  stdout: (line) => console.log(line),
4549
4471
  stderr: (line) => console.error(line),
4550
- readJsonFile: async (path) => JSON.parse(await readFile8(resolve(process.cwd(), path), "utf8")),
4472
+ readJsonFile: async (path) => JSON.parse(
4473
+ await readFile8(resolve(process.cwd(), path), "utf8")
4474
+ ),
4551
4475
  readPackageVersion: async () => {
4552
4476
  const packageJson = JSON.parse(
4553
4477
  await readFile8(new URL("../../package.json", import.meta.url), "utf8")
@@ -4558,7 +4482,6 @@ function createDefaultDependencies() {
4558
4482
  siteSetupApplyCommand,
4559
4483
  siteSetupContextCommand,
4560
4484
  siteSetupVerifyCommand,
4561
- connectCommand,
4562
4485
  initCommand,
4563
4486
  bookingInitCommand,
4564
4487
  bookingCheckCommand,