@treeseed/sdk 0.12.26 → 0.12.28

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.
Files changed (47) hide show
  1. package/README.md +1 -1
  2. package/dist/guarantees/index.js +15 -1
  3. package/dist/hosting/builtins.js +4 -4
  4. package/dist/hosting/contracts.d.ts +3 -3
  5. package/dist/hosting/graph.d.ts +4 -4
  6. package/dist/hosting/graph.js +17 -17
  7. package/dist/operations/agent-tools.d.ts +1 -1
  8. package/dist/operations/agent-tools.js +1 -1
  9. package/dist/operations/providers/default.js +2 -2
  10. package/dist/operations/services/config-runtime.d.ts +9 -9
  11. package/dist/operations/services/config-runtime.js +10 -10
  12. package/dist/operations/services/deploy.d.ts +8 -8
  13. package/dist/operations/services/deploy.js +151 -151
  14. package/dist/operations/services/github-automation.d.ts +6 -6
  15. package/dist/operations/services/github-automation.js +8 -8
  16. package/dist/operations/services/hub-launch.d.ts +1 -1
  17. package/dist/operations/services/hub-launch.js +1 -1
  18. package/dist/operations/services/package-adapters.d.ts +2 -2
  19. package/dist/operations/services/package-adapters.js +2 -2
  20. package/dist/operations/services/project-host-operations.d.ts +1 -1
  21. package/dist/operations/services/project-host-operations.js +1 -1
  22. package/dist/operations/services/project-platform.d.ts +8 -8
  23. package/dist/operations/services/project-platform.js +31 -31
  24. package/dist/operations/services/project-web-monitor.d.ts +1 -1
  25. package/dist/operations/services/project-web-monitor.js +4 -4
  26. package/dist/operations/services/railway-deploy.d.ts +4 -4
  27. package/dist/operations/services/railway-deploy.js +7 -7
  28. package/dist/operations/services/repository-save-orchestrator.js +3 -3
  29. package/dist/operations/services/template-secret-sync.d.ts +1 -1
  30. package/dist/operations/services/template-secret-sync.js +3 -3
  31. package/dist/reconcile/builtin-adapters.js +86 -40
  32. package/dist/reconcile/contracts.d.ts +1 -1
  33. package/dist/reconcile/engine.d.ts +4 -4
  34. package/dist/reconcile/engine.js +12 -12
  35. package/dist/reconcile/providers/release-private.d.ts +1 -1
  36. package/dist/scripts/tenant-deploy.js +9 -9
  37. package/dist/scripts/tenant-destroy.js +7 -7
  38. package/dist/scripts/tenant-workflow-action.js +4 -4
  39. package/dist/scripts/test-scaffold.js +2 -2
  40. package/dist/scripts/workspace-command-e2e.js +4 -4
  41. package/dist/sdk-types.d.ts +2 -2
  42. package/dist/treedx/generated/openapi-types.d.ts +11 -11
  43. package/dist/treedx/types.d.ts +15 -15
  44. package/dist/workflow/operations.d.ts +6 -4
  45. package/dist/workflow/operations.js +46 -23
  46. package/dist/workflow.d.ts +0 -9
  47. package/package.json +1 -1
@@ -501,16 +501,16 @@ function defaultStateFromConfig(deployConfig, target) {
501
501
  FORM_GUARD_KV: {
502
502
  name: environmentScopedIdentityName(identity, "form-guard", target),
503
503
  binding: "FORM_GUARD_KV",
504
- id: `dryrun-${suffix}-form-guard`,
505
- previewId: `dryrun-${suffix}-form-guard-preview`
504
+ id: `plan-${suffix}-form-guard`,
505
+ previewId: `plan-${suffix}-form-guard-preview`
506
506
  }
507
507
  },
508
508
  d1Databases: {
509
509
  SITE_DATA_DB: {
510
510
  databaseName: environmentScopedIdentityName(identity, "site-data", target),
511
511
  binding: "SITE_DATA_DB",
512
- databaseId: `dryrun-${suffix}-site-data`,
513
- previewDatabaseId: `dryrun-${suffix}-site-data-preview`
512
+ databaseId: `plan-${suffix}-site-data`,
513
+ previewDatabaseId: `plan-${suffix}-site-data-preview`
514
514
  }
515
515
  },
516
516
  queues: {},
@@ -1164,7 +1164,7 @@ function isPlaceholderResourceId(value) {
1164
1164
  if (!value || typeof value !== "string") {
1165
1165
  return true;
1166
1166
  }
1167
- return value.startsWith("local-") || value.startsWith("dryrun-") || value.endsWith("-id") || value.endsWith("-preview-id");
1167
+ return value.startsWith("local-") || value.startsWith("plan-") || value.endsWith("-id") || value.endsWith("-preview-id");
1168
1168
  }
1169
1169
  function buildProvisioningSummary(deployConfig, state, target) {
1170
1170
  const webCachePolicy = resolveTreeseedWebCachePolicy(deployConfig);
@@ -1533,7 +1533,7 @@ function buildTreeseedManagedCloudflareCacheRules(deployConfig, cacheTarget, kin
1533
1533
  );
1534
1534
  return rules;
1535
1535
  }
1536
- function reconcileCloudflareCacheRulesForTarget(role, deployConfig, state, cacheTarget, env, { dryRun = false } = {}) {
1536
+ function reconcileCloudflareCacheRulesForTarget(role, deployConfig, state, cacheTarget, env, { planOnly = false } = {}) {
1537
1537
  const roleKey = role === "web" ? "Web" : "Content";
1538
1538
  if (!cacheTarget?.host) {
1539
1539
  return { managed: false, skipped: true, reason: "missing_host" };
@@ -1545,8 +1545,8 @@ function reconcileCloudflareCacheRulesForTarget(role, deployConfig, state, cache
1545
1545
  const desiredRules = buildTreeseedManagedCloudflareCacheRules(deployConfig, cacheTarget, role);
1546
1546
  state.webCache[role === "web" ? "webHost" : "contentHost"] = cacheTarget.host;
1547
1547
  state.webCache[role === "web" ? "webZoneId" : "contentZoneId"] = zoneId;
1548
- if (dryRun) {
1549
- return { managed: true, dryRun: true, zoneId, host: cacheTarget.host, rules: desiredRules };
1548
+ if (planOnly) {
1549
+ return { managed: true, planOnly: true, zoneId, host: cacheTarget.host, rules: desiredRules };
1550
1550
  }
1551
1551
  const rulesets = listCloudflareZoneRulesets(zoneId, env);
1552
1552
  const existing = rulesets.find((ruleset) => ruleset?.phase === "http_request_cache_settings") ?? null;
@@ -1574,7 +1574,7 @@ function reconcileCloudflareCacheRulesForTarget(role, deployConfig, state, cache
1574
1574
  state.webCache[role === "web" ? "webRulesetId" : "contentRulesetId"] = rulesetId;
1575
1575
  return { managed: true, zoneId, host: cacheTarget.host, rulesetId };
1576
1576
  }
1577
- function reconcileCloudflareWebCacheRules(tenantRoot, deployConfig, state, target, { dryRun = false, env: providedEnv } = {}) {
1577
+ function reconcileCloudflareWebCacheRules(tenantRoot, deployConfig, state, target, { planOnly = false, env: providedEnv } = {}) {
1578
1578
  if (!shouldManageCloudflareWebCacheRules(deployConfig, target)) {
1579
1579
  const webTarget2 = resolvePublicWebCacheTarget(deployConfig);
1580
1580
  const contentTarget2 = resolvePublicContentCacheTarget(deployConfig);
@@ -1599,10 +1599,10 @@ function reconcileCloudflareWebCacheRules(tenantRoot, deployConfig, state, targe
1599
1599
  try {
1600
1600
  const results = [];
1601
1601
  if (webTarget?.host) {
1602
- results.push(reconcileCloudflareCacheRulesForTarget("web", deployConfig, state, webTarget, env, { dryRun }));
1602
+ results.push(reconcileCloudflareCacheRulesForTarget("web", deployConfig, state, webTarget, env, { planOnly }));
1603
1603
  }
1604
1604
  if (contentTarget?.host) {
1605
- results.push(reconcileCloudflareCacheRulesForTarget("content", deployConfig, state, contentTarget, env, { dryRun }));
1605
+ results.push(reconcileCloudflareCacheRulesForTarget("content", deployConfig, state, contentTarget, env, { planOnly }));
1606
1606
  }
1607
1607
  state.webCache.rulesManaged = true;
1608
1608
  state.webCache.lastSyncedAt = (/* @__PURE__ */ new Date()).toISOString();
@@ -1694,12 +1694,12 @@ function purgeSourcePageCaches(tenantRoot, options = {}) {
1694
1694
  const state = loadDeployState(tenantRoot, deployConfig, { target });
1695
1695
  const urls = resolveSourcePagePurgeUrls(deployConfig);
1696
1696
  const env = resolveCloudflareCachePurgeEnv(options);
1697
- if ((options.dryRun ?? false) || urls.length === 0 || !env) {
1697
+ if ((options.planOnly ?? false) || urls.length === 0 || !env) {
1698
1698
  recordCachePurgeResult(state.webCache.deployPurge, urls.map((url) => ({ count: url ? 1 : 0 })));
1699
1699
  writeDeployState(tenantRoot, state, { target });
1700
1700
  return {
1701
1701
  skipped: true,
1702
- reason: options.dryRun ? "dry_run" : urls.length === 0 ? "no_urls" : "missing_cloudflare_token",
1702
+ reason: options.planOnly ? "plan" : urls.length === 0 ? "no_urls" : "missing_cloudflare_token",
1703
1703
  urls,
1704
1704
  results: []
1705
1705
  };
@@ -1722,12 +1722,12 @@ function purgePublishedContentCaches(tenantRoot, urls, options = {}) {
1722
1722
  const deployConfig = loadTenantDeployConfig(tenantRoot);
1723
1723
  const state = loadDeployState(tenantRoot, deployConfig, { target });
1724
1724
  const env = resolveCloudflareCachePurgeEnv(options);
1725
- if ((options.dryRun ?? false) || !urls?.length || !env) {
1725
+ if ((options.planOnly ?? false) || !urls?.length || !env) {
1726
1726
  recordCachePurgeResult(state.webCache.contentPurge, (urls ?? []).map((url) => ({ count: url ? 1 : 0 })));
1727
1727
  writeDeployState(tenantRoot, state, { target });
1728
1728
  return {
1729
1729
  skipped: true,
1730
- reason: options.dryRun ? "dry_run" : !urls?.length ? "no_urls" : "missing_cloudflare_token",
1730
+ reason: options.planOnly ? "plan" : !urls?.length ? "no_urls" : "missing_cloudflare_token",
1731
1731
  urls: urls ?? [],
1732
1732
  results: []
1733
1733
  };
@@ -1958,60 +1958,60 @@ function resolveExistingD1ByName(d1Databases, expectedName, current) {
1958
1958
  function looksLikeMissingResource(output) {
1959
1959
  return /not found|does not exist|could(?: not|n't) find|couldnt find|already deleted|deleted widget|access a deleted/i.test(output);
1960
1960
  }
1961
- function deleteKvNamespace(tenantRoot, namespaceId, { env, dryRun, preview = false }) {
1961
+ function deleteKvNamespace(tenantRoot, namespaceId, { env, planOnly, preview = false }) {
1962
1962
  if (!namespaceId || isPlaceholderResourceId(namespaceId)) {
1963
1963
  return { status: "missing", id: namespaceId };
1964
1964
  }
1965
- if (dryRun) {
1965
+ if (planOnly) {
1966
1966
  return { status: "planned", id: namespaceId, preview };
1967
1967
  }
1968
1968
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
1969
1969
  const path = accountId ? `/accounts/${encodeURIComponent(accountId)}/storage/kv/namespaces/${encodeURIComponent(namespaceId)}` : null;
1970
- const deleted = deleteCloudflareApiResource(path, { env, dryRun: false, name: namespaceId, type: "kv-namespace" });
1970
+ const deleted = deleteCloudflareApiResource(path, { env, planOnly: false, name: namespaceId, type: "kv-namespace" });
1971
1971
  return { status: deleted.status, id: namespaceId, preview };
1972
1972
  }
1973
- function deleteTurnstileWidget(sitekey, { env, dryRun, name = null }) {
1973
+ function deleteTurnstileWidget(sitekey, { env, planOnly, name = null }) {
1974
1974
  if (!sitekey || isPlaceholderResourceId(sitekey)) {
1975
1975
  return { status: "missing", sitekey, name };
1976
1976
  }
1977
- if (dryRun) {
1977
+ if (planOnly) {
1978
1978
  return { status: "planned", sitekey, name };
1979
1979
  }
1980
1980
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
1981
1981
  const path = accountId ? `/accounts/${encodeURIComponent(accountId)}/challenges/widgets/${encodeURIComponent(sitekey)}` : null;
1982
1982
  let deleted;
1983
1983
  try {
1984
- deleted = deleteCloudflareApiResource(path, { env, dryRun: false, name: name ?? sitekey, type: "turnstile-widget" });
1984
+ deleted = deleteCloudflareApiResource(path, { env, planOnly: false, name: name ?? sitekey, type: "turnstile-widget" });
1985
1985
  } catch (error) {
1986
1986
  const detail = error instanceof Error ? error.message : String(error);
1987
1987
  throw new Error(`Cloudflare Turnstile widget deletion failed. Ensure the API token has Turnstile Sites Write permission: ${detail}`);
1988
1988
  }
1989
1989
  return { status: deleted.status, sitekey, name };
1990
1990
  }
1991
- function deleteD1Database(tenantRoot, databaseName, { env, dryRun }) {
1991
+ function deleteD1Database(tenantRoot, databaseName, { env, planOnly }) {
1992
1992
  if (!databaseName) {
1993
1993
  return { status: "missing", name: databaseName };
1994
1994
  }
1995
- if (dryRun) {
1995
+ if (planOnly) {
1996
1996
  return { status: "planned", name: databaseName };
1997
1997
  }
1998
1998
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
1999
1999
  const database = accountId ? listD1Databases(tenantRoot, env).find((entry) => entry?.name === databaseName) : null;
2000
2000
  const databaseId = database?.uuid ?? database?.id ?? null;
2001
2001
  const path = accountId && databaseId ? `/accounts/${encodeURIComponent(accountId)}/d1/database/${encodeURIComponent(databaseId)}` : null;
2002
- const deleted = deleteCloudflareApiResource(path, { env, dryRun: false, name: databaseName, type: "d1-database" });
2002
+ const deleted = deleteCloudflareApiResource(path, { env, planOnly: false, name: databaseName, type: "d1-database" });
2003
2003
  return { status: deleted.status, name: databaseName, id: databaseId };
2004
2004
  }
2005
- function deleteWorker(tenantRoot, workerName, { env, dryRun, force = false }) {
2005
+ function deleteWorker(tenantRoot, workerName, { env, planOnly, force = false }) {
2006
2006
  if (!workerName) {
2007
2007
  return { status: "missing", name: workerName };
2008
2008
  }
2009
- if (dryRun) {
2009
+ if (planOnly) {
2010
2010
  return { status: "planned", name: workerName };
2011
2011
  }
2012
2012
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
2013
2013
  const path = accountId ? `/accounts/${encodeURIComponent(accountId)}/workers/services/${encodeURIComponent(workerName)}` : null;
2014
- const deleted = deleteCloudflareApiResource(path, { env, dryRun: false, name: workerName, type: "worker" });
2014
+ const deleted = deleteCloudflareApiResource(path, { env, planOnly: false, name: workerName, type: "worker" });
2015
2015
  return { status: deleted.status, name: workerName };
2016
2016
  }
2017
2017
  function resourceOperation(provider, type, name, status, extra = {}) {
@@ -2023,11 +2023,11 @@ function resourceOperation(provider, type, name, status, extra = {}) {
2023
2023
  ...extra
2024
2024
  };
2025
2025
  }
2026
- function deleteCloudflareApiResource(path, { env, dryRun, name, type }) {
2026
+ function deleteCloudflareApiResource(path, { env, planOnly, name, type }) {
2027
2027
  if (!path) {
2028
2028
  return resourceOperation("cloudflare", type, name, "missing");
2029
2029
  }
2030
- if (dryRun) {
2030
+ if (planOnly) {
2031
2031
  return resourceOperation("cloudflare", type, name, "planned", { path });
2032
2032
  }
2033
2033
  const result = cloudflareApiRequest(path, { method: "DELETE", env, allowFailure: true });
@@ -2039,13 +2039,13 @@ function deleteCloudflareApiResource(path, { env, dryRun, name, type }) {
2039
2039
  function formatCloudflareErrors(payload) {
2040
2040
  return Array.isArray(payload?.errors) ? payload.errors.map((entry) => entry?.message ?? JSON.stringify(entry)).filter(Boolean).join("; ") : "";
2041
2041
  }
2042
- function deleteQueueByName(tenantRoot, queue, { env, dryRun }) {
2042
+ function deleteQueueByName(tenantRoot, queue, { env, planOnly }) {
2043
2043
  const name = queueName(queue) ?? queue?.name ?? null;
2044
2044
  let id = queueId(queue);
2045
2045
  if (!name) {
2046
2046
  return resourceOperation("cloudflare", "queue", name, "missing");
2047
2047
  }
2048
- if (dryRun) {
2048
+ if (planOnly) {
2049
2049
  return resourceOperation("cloudflare", "queue", name, "planned", { id });
2050
2050
  }
2051
2051
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
@@ -2055,7 +2055,7 @@ function deleteQueueByName(tenantRoot, queue, { env, dryRun }) {
2055
2055
  }
2056
2056
  const path = id ? `/accounts/${encodeURIComponent(accountId)}/queues/${encodeURIComponent(id)}` : null;
2057
2057
  if (path) {
2058
- const deleted = deleteCloudflareApiResource(path, { env, dryRun: false, name, type: "queue" });
2058
+ const deleted = deleteCloudflareApiResource(path, { env, planOnly: false, name, type: "queue" });
2059
2059
  if (deleted.status === "deleted" || deleted.status === "missing") {
2060
2060
  return { ...deleted, id };
2061
2061
  }
@@ -2065,20 +2065,20 @@ function deleteQueueByName(tenantRoot, queue, { env, dryRun }) {
2065
2065
  }
2066
2066
  throw new Error(`Failed to delete queue ${name}: CLOUDFLARE_ACCOUNT_ID is not configured.`);
2067
2067
  }
2068
- function deleteR2Bucket(tenantRoot, bucketName, { env, dryRun, deleteData }) {
2068
+ function deleteR2Bucket(tenantRoot, bucketName, { env, planOnly, deleteData }) {
2069
2069
  if (!bucketName) {
2070
2070
  return resourceOperation("cloudflare", "r2-bucket", bucketName, "missing");
2071
2071
  }
2072
2072
  if (!deleteData) {
2073
2073
  return resourceOperation("cloudflare", "r2-bucket", bucketName, "skipped", { reason: "data_preserved" });
2074
2074
  }
2075
- if (dryRun) {
2075
+ if (planOnly) {
2076
2076
  return resourceOperation("cloudflare", "r2-bucket", bucketName, "planned");
2077
2077
  }
2078
2078
  const drained = drainR2Bucket(bucketName, { env });
2079
2079
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
2080
2080
  const path = accountId ? `/accounts/${encodeURIComponent(accountId)}/r2/buckets/${encodeURIComponent(bucketName)}` : null;
2081
- const deleted = deleteCloudflareApiResource(path, { env, dryRun: false, name: bucketName, type: "r2-bucket" });
2081
+ const deleted = deleteCloudflareApiResource(path, { env, planOnly: false, name: bucketName, type: "r2-bucket" });
2082
2082
  return resourceOperation("cloudflare", "r2-bucket", bucketName, deleted.status, drained);
2083
2083
  }
2084
2084
  function r2ObjectKey(entry) {
@@ -2257,11 +2257,11 @@ process.stdout.write(JSON.stringify({ deleted, missing, deferred, failed }));
2257
2257
  objectsDeferred: Number(parsed.deferred) || 0
2258
2258
  };
2259
2259
  }
2260
- function deleteD1DatabaseForDestroy(tenantRoot, databaseName, { env, dryRun, deleteData }) {
2260
+ function deleteD1DatabaseForDestroy(tenantRoot, databaseName, { env, planOnly, deleteData }) {
2261
2261
  if (!deleteData) {
2262
2262
  return resourceOperation("cloudflare", "d1-database", databaseName, "skipped", { reason: "data_preserved" });
2263
2263
  }
2264
- const result = deleteD1Database(tenantRoot, databaseName, { env, dryRun });
2264
+ const result = deleteD1Database(tenantRoot, databaseName, { env, planOnly });
2265
2265
  return resourceOperation("cloudflare", "d1-database", databaseName, result.status, result);
2266
2266
  }
2267
2267
  function pagesDomainName(domain) {
@@ -2311,12 +2311,12 @@ function listPagesCustomDomainsWithWrangler(tenantRoot, projectName, { env }) {
2311
2311
  return [];
2312
2312
  }
2313
2313
  }
2314
- function deletePagesCustomDomains(tenantRoot, projectName, knownNames, { env, dryRun, knownOnly = false }) {
2314
+ function deletePagesCustomDomains(tenantRoot, projectName, knownNames, { env, planOnly, knownOnly = false }) {
2315
2315
  if (!projectName) {
2316
2316
  return [resourceOperation("cloudflare", "pages-custom-domain", projectName, "missing")];
2317
2317
  }
2318
2318
  const desiredNames = [...new Set((knownNames ?? []).filter(Boolean))];
2319
- if (dryRun) {
2319
+ if (planOnly) {
2320
2320
  return desiredNames.length > 0 ? desiredNames.map((name) => resourceOperation("cloudflare", "pages-custom-domain", name, "planned", { projectName, knownOnly })) : [resourceOperation("cloudflare", "pages-custom-domain", projectName, knownOnly ? "skipped" : "planned", { reason: knownOnly ? "no_target_scoped_domain" : "project_delete_prerequisite" })];
2321
2321
  }
2322
2322
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
@@ -2331,7 +2331,7 @@ function deletePagesCustomDomains(tenantRoot, projectName, knownNames, { env, dr
2331
2331
  }
2332
2332
  return domainNames.map((name) => deleteCloudflareApiResource(
2333
2333
  `/accounts/${encodeURIComponent(accountId)}/pages/projects/${encodeURIComponent(projectName)}/domains/${encodeURIComponent(name)}`,
2334
- { env, dryRun: false, name, type: "pages-custom-domain" }
2334
+ { env, planOnly: false, name, type: "pages-custom-domain" }
2335
2335
  ));
2336
2336
  }
2337
2337
  function normalizePagesDeploymentId(deployment) {
@@ -2391,11 +2391,11 @@ function listPagesDeployments(tenantRoot, projectName, { env, environment = "all
2391
2391
  }
2392
2392
  return listPagesDeploymentsWithApi(projectName, { env, environment });
2393
2393
  }
2394
- function deletePagesDeployments(tenantRoot, projectName, { env, dryRun, environment = "all" }) {
2394
+ function deletePagesDeployments(tenantRoot, projectName, { env, planOnly, environment = "all" }) {
2395
2395
  if (!projectName) {
2396
2396
  return resourceOperation("cloudflare", "pages-deployments", projectName, "missing");
2397
2397
  }
2398
- if (dryRun) {
2398
+ if (planOnly) {
2399
2399
  return resourceOperation("cloudflare", "pages-deployments", projectName, "planned", { reason: "project_delete_prerequisite", environment });
2400
2400
  }
2401
2401
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
@@ -2451,14 +2451,14 @@ function deletePagesDeployments(tenantRoot, projectName, { env, dryRun, environm
2451
2451
  total
2452
2452
  });
2453
2453
  }
2454
- function deletePagesProject(projectName, { env, dryRun }) {
2454
+ function deletePagesProject(projectName, { env, planOnly }) {
2455
2455
  const accountId = env?.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "";
2456
2456
  if (!projectName || !accountId) {
2457
2457
  return resourceOperation("cloudflare", "pages-project", projectName, "missing");
2458
2458
  }
2459
2459
  return deleteCloudflareApiResource(
2460
2460
  `/accounts/${encodeURIComponent(accountId)}/pages/projects/${encodeURIComponent(projectName)}`,
2461
- { env, dryRun, name: projectName, type: "pages-project" }
2461
+ { env, planOnly, name: projectName, type: "pages-project" }
2462
2462
  );
2463
2463
  }
2464
2464
  function listDnsRecordsForName(zoneId, name, env) {
@@ -2468,11 +2468,11 @@ function listDnsRecordsForName(zoneId, name, env) {
2468
2468
  const result = cloudflareApiRequest(`/zones/${encodeURIComponent(zoneId)}/dns_records?name=${encodeURIComponent(name)}&per_page=100`, { env, allowFailure: true });
2469
2469
  return Array.isArray(result?.result) ? result.result : [];
2470
2470
  }
2471
- function deleteDnsRecordsForName(deployConfig, name, { env, dryRun }) {
2471
+ function deleteDnsRecordsForName(deployConfig, name, { env, planOnly }) {
2472
2472
  if (!name) {
2473
2473
  return [resourceOperation("cloudflare", "dns-record", name, "missing")];
2474
2474
  }
2475
- if (dryRun) {
2475
+ if (planOnly) {
2476
2476
  return [resourceOperation("cloudflare", "dns-record", name, "planned")];
2477
2477
  }
2478
2478
  const zoneId = resolveCloudflareZoneIdForHost(deployConfig, name, env);
@@ -2487,11 +2487,11 @@ function deleteDnsRecordsForName(deployConfig, name, { env, dryRun }) {
2487
2487
  const recordName = record?.name ?? name;
2488
2488
  return deleteCloudflareApiResource(
2489
2489
  `/zones/${encodeURIComponent(zoneId)}/dns_records/${encodeURIComponent(record.id)}`,
2490
- { env, dryRun: false, name: recordName, type: "dns-record" }
2490
+ { env, planOnly: false, name: recordName, type: "dns-record" }
2491
2491
  );
2492
2492
  });
2493
2493
  }
2494
- function deleteTreeseedCacheRules(deployConfig, state, { env, dryRun }) {
2494
+ function deleteTreeseedCacheRules(deployConfig, state, { env, planOnly }) {
2495
2495
  const targets = [
2496
2496
  { role: "web", zoneId: state.webCache?.webZoneId, host: state.webCache?.webHost },
2497
2497
  { role: "content", zoneId: state.webCache?.contentZoneId, host: state.webCache?.contentHost }
@@ -2504,7 +2504,7 @@ function deleteTreeseedCacheRules(deployConfig, state, { env, dryRun }) {
2504
2504
  if (!zoneId) {
2505
2505
  return resourceOperation("cloudflare", "cache-rules", target.host, "blocked", { reason: "zone_unresolved" });
2506
2506
  }
2507
- if (dryRun) {
2507
+ if (planOnly) {
2508
2508
  return resourceOperation("cloudflare", "cache-rules", target.host, "planned", { zoneId });
2509
2509
  }
2510
2510
  const rulesets = listCloudflareZoneRulesets(zoneId, env);
@@ -2569,7 +2569,7 @@ function configuredRailwayDestroyTargets(tenantRoot, deployConfig, scope) {
2569
2569
  }
2570
2570
  return services;
2571
2571
  }
2572
- async function destroyRailwayResources(tenantRoot, deployConfig, target, { dryRun = false, deleteData = false, env = process.env } = {}) {
2572
+ async function destroyRailwayResources(tenantRoot, deployConfig, target, { planOnly = false, deleteData = false, env = process.env } = {}) {
2573
2573
  const scope = target.kind === "persistent" ? target.scope : target.branchName;
2574
2574
  const services = configuredRailwayDestroyTargets(tenantRoot, deployConfig, scope);
2575
2575
  if (services.length === 0) {
@@ -2599,7 +2599,7 @@ async function destroyRailwayResources(tenantRoot, deployConfig, target, { dryRu
2599
2599
  for (const service of serviceTargets) {
2600
2600
  const railwayService = project.services.find((entry) => entry.name === service.serviceName || entry.id === service.serviceName) ?? null;
2601
2601
  const shouldDeleteData = service.dataStore ? deleteData : true;
2602
- operations.push(resourceOperation("railway", service.dataStore ? "postgres-service" : "service", service.serviceName, railwayService ? dryRun ? "planned" : "planned" : "missing", {
2602
+ operations.push(resourceOperation("railway", service.dataStore ? "postgres-service" : "service", service.serviceName, railwayService ? planOnly ? "planned" : "planned" : "missing", {
2603
2603
  projectId: project.id,
2604
2604
  serviceId: railwayService?.id ?? null,
2605
2605
  ...service.dataStore && !shouldDeleteData ? { status: "skipped", reason: "data_preserved" } : {}
@@ -2615,7 +2615,7 @@ async function destroyRailwayResources(tenantRoot, deployConfig, target, { dryRu
2615
2615
  env
2616
2616
  });
2617
2617
  for (const variableName of Object.keys(variables).sort()) {
2618
- operations.push(resourceOperation("railway", "variable", `${service.serviceName}:${variableName}`, dryRun ? "planned" : "deleted", {
2618
+ operations.push(resourceOperation("railway", "variable", `${service.serviceName}:${variableName}`, planOnly ? "planned" : "deleted", {
2619
2619
  projectId: project.id,
2620
2620
  serviceId: railwayService.id,
2621
2621
  environmentId: environment.id,
@@ -2625,7 +2625,7 @@ async function destroyRailwayResources(tenantRoot, deployConfig, target, { dryRu
2625
2625
  }
2626
2626
  const instance = await getRailwayServiceInstance({ serviceId: railwayService.id, environmentId: environment.id, env });
2627
2627
  if (instance.cronSchedule) {
2628
- operations.push(resourceOperation("railway", "schedule", `${service.serviceName}:${instance.cronSchedule}`, dryRun ? "planned" : "deleted", {
2628
+ operations.push(resourceOperation("railway", "schedule", `${service.serviceName}:${instance.cronSchedule}`, planOnly ? "planned" : "deleted", {
2629
2629
  projectId: project.id,
2630
2630
  serviceId: railwayService.id,
2631
2631
  environmentId: environment.id,
@@ -2635,7 +2635,7 @@ async function destroyRailwayResources(tenantRoot, deployConfig, target, { dryRu
2635
2635
  if (!service.dataStore && service.domain) {
2636
2636
  const domains = await listRailwayCustomDomains({ projectId: project.id, environmentId: environment.id, serviceId: railwayService.id, env });
2637
2637
  for (const domain of domains.filter((entry) => entry.domain === service.domain)) {
2638
- if (dryRun) {
2638
+ if (planOnly) {
2639
2639
  operations.push(resourceOperation("railway", "custom-domain", domain.domain, "planned", { id: domain.id }));
2640
2640
  } else {
2641
2641
  const result = await deleteRailwayCustomDomain({ domainId: domain.id, env });
@@ -2651,7 +2651,7 @@ async function destroyRailwayResources(tenantRoot, deployConfig, target, { dryRu
2651
2651
  if (!matchingInstance) {
2652
2652
  continue;
2653
2653
  }
2654
- if (dryRun) {
2654
+ if (planOnly) {
2655
2655
  operations.push(resourceOperation("railway", "volume", volume.name, "planned", { id: volume.id, projectId: project.id }));
2656
2656
  } else {
2657
2657
  const result = await deleteRailwayVolume({ volumeId: volume.id, env });
@@ -2661,7 +2661,7 @@ async function destroyRailwayResources(tenantRoot, deployConfig, target, { dryRu
2661
2661
  }
2662
2662
  const shouldDeleteProject = shouldDeleteRailwayProjectAfterEnvironmentDestroy(project, scope, deleteData, environment?.id ?? null);
2663
2663
  if (scope === "prod" && deleteData || shouldDeleteProject) {
2664
- if (dryRun) {
2664
+ if (planOnly) {
2665
2665
  operations.push(resourceOperation("railway", "project", project.name, "planned", {
2666
2666
  id: project.id,
2667
2667
  reason: scope === "prod" ? "prod_delete_data_cleanup" : "no_managed_persistent_environments"
@@ -2670,7 +2670,7 @@ async function destroyRailwayResources(tenantRoot, deployConfig, target, { dryRu
2670
2670
  throw new Error("Railway project deletion is reconciler-owned. Use trsd reconcile destroy or live acceptance cleanup for project-scoped deletion.");
2671
2671
  }
2672
2672
  } else if (environment) {
2673
- if (dryRun) {
2673
+ if (planOnly) {
2674
2674
  operations.push(resourceOperation("railway", "environment", environment.name, "planned", { id: environment.id, projectId: project.id }));
2675
2675
  } else {
2676
2676
  const result = await deleteRailwayEnvironment({ environmentId: environment.id, env });
@@ -2689,12 +2689,12 @@ function shouldDeleteRailwayProjectAfterEnvironmentDestroy(project, scope, delet
2689
2689
  const remainingManagedEnvironments = (project?.environments ?? []).filter((environment) => environment?.id !== deletedEnvironmentId).filter((environment) => environment?.name !== targetEnvironmentName).filter((environment) => managedPersistentNames.has(environment?.name));
2690
2690
  return remainingManagedEnvironments.length === 0;
2691
2691
  }
2692
- function killPidFromFile(filePath, { dryRun }) {
2692
+ function killPidFromFile(filePath, { planOnly }) {
2693
2693
  const pid = Number.parseInt(readFileSync(filePath, "utf8").trim(), 10);
2694
2694
  if (!Number.isFinite(pid) || pid <= 0) {
2695
2695
  return resourceOperation("local", "dev-process", filePath, "missing");
2696
2696
  }
2697
- if (dryRun) {
2697
+ if (planOnly) {
2698
2698
  return resourceOperation("local", "dev-process", String(pid), "planned", { pidFile: filePath });
2699
2699
  }
2700
2700
  try {
@@ -2747,7 +2747,7 @@ function removeDockerResource(kind, id, name) {
2747
2747
  reason: result.stderr?.trim() || result.stdout?.trim() || "docker_remove_failed"
2748
2748
  });
2749
2749
  }
2750
- function dockerLocalRuntimeResourceOperations({ dryRun = false } = {}) {
2750
+ function dockerLocalRuntimeResourceOperations({ planOnly = false } = {}) {
2751
2751
  if (!dockerAvailable()) {
2752
2752
  return [resourceOperation("local", "docker-cleanup", "docker", "skipped", { reason: "docker_unavailable" })];
2753
2753
  }
@@ -2769,7 +2769,7 @@ function dockerLocalRuntimeResourceOperations({ dryRun = false } = {}) {
2769
2769
  return id && name ? { id, name } : null;
2770
2770
  }
2771
2771
  ).filter((entry) => !["bridge", "host", "none"].includes(entry.name));
2772
- if (dryRun) {
2772
+ if (planOnly) {
2773
2773
  return [
2774
2774
  ...containers.map((entry) => resourceOperation("local", "docker-container", entry.name, "planned", { id: entry.id })),
2775
2775
  ...volumes.map((entry) => resourceOperation("local", "docker-volume", entry.name, "planned", { id: entry.id })),
@@ -2792,13 +2792,13 @@ function dockerLocalRuntimeResourceOperations({ dryRun = false } = {}) {
2792
2792
  }
2793
2793
  return operations;
2794
2794
  }
2795
- function destroyLocalRuntimeResources(tenantRoot, { dryRun = false, deleteData = false } = {}) {
2795
+ function destroyLocalRuntimeResources(tenantRoot, { planOnly = false, deleteData = false } = {}) {
2796
2796
  const operations = [];
2797
2797
  const pidDir = resolve(tenantRoot, ".treeseed/dev-pids");
2798
2798
  if (existsSync(pidDir)) {
2799
2799
  for (const entry of readdirSync(pidDir)) {
2800
2800
  if (entry.endsWith(".pid")) {
2801
- operations.push(killPidFromFile(resolve(pidDir, entry), { dryRun }));
2801
+ operations.push(killPidFromFile(resolve(pidDir, entry), { planOnly }));
2802
2802
  }
2803
2803
  }
2804
2804
  } else {
@@ -2816,14 +2816,14 @@ function destroyLocalRuntimeResources(tenantRoot, { dryRun = false, deleteData =
2816
2816
  operations.push(resourceOperation("local", "data-path", relativePath, "missing"));
2817
2817
  continue;
2818
2818
  }
2819
- if (dryRun) {
2819
+ if (planOnly) {
2820
2820
  operations.push(resourceOperation("local", "data-path", relativePath, "planned"));
2821
2821
  continue;
2822
2822
  }
2823
2823
  rmSync(absolutePath, { recursive: true, force: true });
2824
2824
  operations.push(resourceOperation("local", "data-path", relativePath, "deleted"));
2825
2825
  }
2826
- operations.push(...dockerLocalRuntimeResourceOperations({ dryRun }));
2826
+ operations.push(...dockerLocalRuntimeResourceOperations({ planOnly }));
2827
2827
  } else {
2828
2828
  operations.push(resourceOperation("local", "data-path", ".treeseed/generated/environments/local", "skipped", { reason: "data_preserved" }));
2829
2829
  }
@@ -2883,12 +2883,12 @@ function cloudflareNameCandidates(entry) {
2883
2883
  function cloudflareEntryMatchesTreeSeed(entry, tokens) {
2884
2884
  return cloudflareNameCandidates(entry).some((candidate) => matchesTreeSeedSweep(candidate, tokens));
2885
2885
  }
2886
- function deleteDnsRecord(zoneId, record, { env, dryRun }) {
2886
+ function deleteDnsRecord(zoneId, record, { env, planOnly }) {
2887
2887
  const name = record?.name ?? record?.content ?? record?.id ?? null;
2888
2888
  if (!zoneId || !record?.id) {
2889
2889
  return resourceOperation("cloudflare", "dns-record", name, "missing", { zoneId });
2890
2890
  }
2891
- if (dryRun) {
2891
+ if (planOnly) {
2892
2892
  return resourceOperation("cloudflare", "dns-record", name, "planned", {
2893
2893
  zoneId,
2894
2894
  id: record.id,
@@ -2898,44 +2898,44 @@ function deleteDnsRecord(zoneId, record, { env, dryRun }) {
2898
2898
  }
2899
2899
  return deleteCloudflareApiResource(
2900
2900
  `/zones/${encodeURIComponent(zoneId)}/dns_records/${encodeURIComponent(record.id)}`,
2901
- { env, dryRun: false, name, type: "dns-record" }
2901
+ { env, planOnly: false, name, type: "dns-record" }
2902
2902
  );
2903
2903
  }
2904
- function sweepTreeSeedCloudflareResources(tenantRoot, deployConfig, state, { env, dryRun, deleteData }) {
2904
+ function sweepTreeSeedCloudflareResources(tenantRoot, deployConfig, state, { env, planOnly, deleteData }) {
2905
2905
  const tokens = treeSeedSweepTokens(deployConfig, state);
2906
2906
  const operations = [];
2907
2907
  const pagesProjects = listPagesProjects(tenantRoot, env).filter((entry) => cloudflareEntryMatchesTreeSeed(entry, tokens));
2908
2908
  for (const project of pagesProjects) {
2909
2909
  const projectName = project?.name ?? project?.id ?? null;
2910
- operations.push(...deletePagesCustomDomains(tenantRoot, projectName, [], { env, dryRun, knownOnly: false }));
2911
- operations.push(deletePagesDeployments(tenantRoot, projectName, { env, dryRun, environment: "all" }));
2912
- operations.push(deletePagesProject(projectName, { env, dryRun }));
2910
+ operations.push(...deletePagesCustomDomains(tenantRoot, projectName, [], { env, planOnly, knownOnly: false }));
2911
+ operations.push(deletePagesDeployments(tenantRoot, projectName, { env, planOnly, environment: "all" }));
2912
+ operations.push(deletePagesProject(projectName, { env, planOnly }));
2913
2913
  }
2914
2914
  for (const worker of listWorkers(tenantRoot, env).filter((entry) => cloudflareEntryMatchesTreeSeed(entry, tokens))) {
2915
2915
  const name = worker?.id ?? worker?.name ?? worker?.script ?? null;
2916
- const deleted = deleteWorker(tenantRoot, name, { env, dryRun, force: true });
2916
+ const deleted = deleteWorker(tenantRoot, name, { env, planOnly, force: true });
2917
2917
  operations.push(resourceOperation("cloudflare", "worker", name, deleted.status, { ...deleted, sweep: true }));
2918
2918
  }
2919
2919
  for (const namespace of listKvNamespaces(tenantRoot, env).filter((entry) => cloudflareEntryMatchesTreeSeed(entry, tokens))) {
2920
- const deleted = deleteKvNamespace(tenantRoot, namespace.id, { env, dryRun });
2920
+ const deleted = deleteKvNamespace(tenantRoot, namespace.id, { env, planOnly });
2921
2921
  operations.push(resourceOperation("cloudflare", "kv-namespace", namespace.title ?? namespace.id, deleted.status, { ...deleted, sweep: true }));
2922
2922
  }
2923
2923
  for (const queue of listQueues(tenantRoot, env).filter((entry) => cloudflareEntryMatchesTreeSeed(entry, tokens))) {
2924
- operations.push({ ...deleteQueueByName(tenantRoot, queue, { env, dryRun }), sweep: true });
2924
+ operations.push({ ...deleteQueueByName(tenantRoot, queue, { env, planOnly }), sweep: true });
2925
2925
  }
2926
2926
  for (const database of listD1Databases(tenantRoot, env).filter((entry) => cloudflareEntryMatchesTreeSeed(entry, tokens))) {
2927
2927
  const name = database?.name ?? database?.uuid ?? database?.id ?? null;
2928
- const deleted = deleteData ? deleteD1Database(tenantRoot, name, { env, dryRun }) : null;
2928
+ const deleted = deleteData ? deleteD1Database(tenantRoot, name, { env, planOnly }) : null;
2929
2929
  operations.push(resourceOperation("cloudflare", "d1-database", name, deleteData ? deleted?.status : "skipped", {
2930
2930
  ...deleteData ? deleted : { reason: "data_preserved" },
2931
2931
  sweep: true
2932
2932
  }));
2933
2933
  }
2934
2934
  for (const bucket of listR2Buckets(tenantRoot, env).filter((entry) => cloudflareEntryMatchesTreeSeed(entry, tokens))) {
2935
- operations.push({ ...deleteR2Bucket(tenantRoot, bucket.name, { env, dryRun, deleteData }), sweep: true });
2935
+ operations.push({ ...deleteR2Bucket(tenantRoot, bucket.name, { env, planOnly, deleteData }), sweep: true });
2936
2936
  }
2937
2937
  for (const widget of listTurnstileWidgets(tenantRoot, env).filter((entry) => cloudflareEntryMatchesTreeSeed(entry, tokens))) {
2938
- const deleted = deleteTurnstileWidget(widget.sitekey, { env, dryRun, name: widget.name });
2938
+ const deleted = deleteTurnstileWidget(widget.sitekey, { env, planOnly, name: widget.name });
2939
2939
  operations.push(resourceOperation("cloudflare", "turnstile-widget", widget.name ?? widget.sitekey, deleted.status, { ...deleted, sweep: true }));
2940
2940
  }
2941
2941
  for (const zone of listDnsZones(env)) {
@@ -2947,7 +2947,7 @@ function sweepTreeSeedCloudflareResources(tenantRoot, deployConfig, state, { env
2947
2947
  if (!cloudflareEntryMatchesTreeSeed(record, tokens)) {
2948
2948
  continue;
2949
2949
  }
2950
- operations.push({ ...deleteDnsRecord(zoneId, record, { env, dryRun }), zoneName: zone?.name ?? null, sweep: true });
2950
+ operations.push({ ...deleteDnsRecord(zoneId, record, { env, planOnly }), zoneName: zone?.name ?? null, sweep: true });
2951
2951
  }
2952
2952
  }
2953
2953
  return operations.length > 0 ? operations : [resourceOperation("cloudflare", "treeseed-sweep", "cloudflare", "missing", { reason: "no_matching_resources" })];
@@ -3036,7 +3036,7 @@ function localDockerDestroyVerification() {
3036
3036
  totalRemaining
3037
3037
  };
3038
3038
  }
3039
- async function sweepTreeSeedRailwayResources(deployConfig, state, { env, dryRun }) {
3039
+ async function sweepTreeSeedRailwayResources(deployConfig, state, { env, planOnly }) {
3040
3040
  if (!resolveRailwayApiToken(env)) {
3041
3041
  return [resourceOperation("railway", "treeseed-sweep", "railway", "blocked", { reason: "missing_railway_api_token" })];
3042
3042
  }
@@ -3048,7 +3048,7 @@ async function sweepTreeSeedRailwayResources(deployConfig, state, { env, dryRun
3048
3048
  if (project.deletedAt || !matchesTreeSeedSweep(project.name, tokens)) {
3049
3049
  continue;
3050
3050
  }
3051
- if (dryRun) {
3051
+ if (planOnly) {
3052
3052
  operations.push(resourceOperation("railway", "project", project.name, "planned", {
3053
3053
  id: project.id,
3054
3054
  workspaceId: workspace.id,
@@ -3068,17 +3068,17 @@ async function destroyTreeseedEnvironmentResources(tenantRoot, options = {}) {
3068
3068
  const env = {
3069
3069
  CLOUDFLARE_ACCOUNT_ID: resolveConfiguredCloudflareAccountId(deployConfig)
3070
3070
  };
3071
- const dryRun = options.dryRun ?? false;
3071
+ const planOnly = options.planOnly ?? false;
3072
3072
  const deleteData = options.deleteData === true;
3073
3073
  const force = options.force ?? false;
3074
3074
  const sweepTreeseed = options.sweepTreeseed === true;
3075
3075
  const destroysSharedWebSurface = target.kind === "persistent" && target.scope === "prod" && deleteData;
3076
- const kvNamespaces = dryRun ? [] : listKvNamespaces(tenantRoot, env);
3077
- const d1Databases = dryRun ? [] : listD1Databases(tenantRoot, env);
3078
- const queues = dryRun ? [] : listQueues(tenantRoot, env);
3079
- const buckets = dryRun ? [] : listR2Buckets(tenantRoot, env);
3080
- const pagesProjects = dryRun ? [] : listPagesProjects(tenantRoot, env);
3081
- const turnstileWidgets = dryRun ? [] : listTurnstileWidgets(tenantRoot, env);
3076
+ const kvNamespaces = planOnly ? [] : listKvNamespaces(tenantRoot, env);
3077
+ const d1Databases = planOnly ? [] : listD1Databases(tenantRoot, env);
3078
+ const queues = planOnly ? [] : listQueues(tenantRoot, env);
3079
+ const buckets = planOnly ? [] : listR2Buckets(tenantRoot, env);
3080
+ const pagesProjects = planOnly ? [] : listPagesProjects(tenantRoot, env);
3081
+ const turnstileWidgets = planOnly ? [] : listTurnstileWidgets(tenantRoot, env);
3082
3082
  state.kvNamespaces.FORM_GUARD_KV.id = resolveExistingKvIdByName(
3083
3083
  kvNamespaces,
3084
3084
  state.kvNamespaces.FORM_GUARD_KV.name,
@@ -3099,16 +3099,16 @@ async function destroyTreeseedEnvironmentResources(tenantRoot, options = {}) {
3099
3099
  state.turnstileWidgets.formGuard = resolveExistingTurnstileWidget(turnstileWidgets, state.turnstileWidgets?.formGuard);
3100
3100
  const pagesProject = pagesProjects.find((entry) => entry?.name === state.pages?.projectName);
3101
3101
  const bucket = buckets.find((entry) => entry?.name === state.content?.bucketName);
3102
- const workerResult = deleteWorker(tenantRoot, state.workerName, { env, dryRun, force });
3102
+ const workerResult = deleteWorker(tenantRoot, state.workerName, { env, planOnly, force });
3103
3103
  const turnstileWidget = deleteTurnstileWidget(state.turnstileWidgets?.formGuard?.sitekey, {
3104
3104
  env,
3105
- dryRun,
3105
+ planOnly,
3106
3106
  name: state.turnstileWidgets?.formGuard?.name
3107
3107
  });
3108
- const formGuard = deleteKvNamespace(tenantRoot, state.kvNamespaces.FORM_GUARD_KV.id, { env, dryRun });
3109
- const formGuardPreview = state.kvNamespaces.FORM_GUARD_KV.previewId && state.kvNamespaces.FORM_GUARD_KV.previewId !== state.kvNamespaces.FORM_GUARD_KV.id ? deleteKvNamespace(tenantRoot, state.kvNamespaces.FORM_GUARD_KV.previewId, { env, dryRun, preview: true }) : null;
3110
- const session = state.kvNamespaces.SESSION?.id ? deleteKvNamespace(tenantRoot, state.kvNamespaces.SESSION.id, { env, dryRun }) : null;
3111
- const sessionPreview = state.kvNamespaces.SESSION?.previewId && state.kvNamespaces.SESSION.previewId !== state.kvNamespaces.SESSION.id ? deleteKvNamespace(tenantRoot, state.kvNamespaces.SESSION.previewId, { env, dryRun, preview: true }) : null;
3108
+ const formGuard = deleteKvNamespace(tenantRoot, state.kvNamespaces.FORM_GUARD_KV.id, { env, planOnly });
3109
+ const formGuardPreview = state.kvNamespaces.FORM_GUARD_KV.previewId && state.kvNamespaces.FORM_GUARD_KV.previewId !== state.kvNamespaces.FORM_GUARD_KV.id ? deleteKvNamespace(tenantRoot, state.kvNamespaces.FORM_GUARD_KV.previewId, { env, planOnly, preview: true }) : null;
3110
+ const session = state.kvNamespaces.SESSION?.id ? deleteKvNamespace(tenantRoot, state.kvNamespaces.SESSION.id, { env, planOnly }) : null;
3111
+ const sessionPreview = state.kvNamespaces.SESSION?.previewId && state.kvNamespaces.SESSION.previewId !== state.kvNamespaces.SESSION.id ? deleteKvNamespace(tenantRoot, state.kvNamespaces.SESSION.previewId, { env, planOnly, preview: true }) : null;
3112
3112
  const knownKvIds = new Set([
3113
3113
  state.kvNamespaces.FORM_GUARD_KV.id,
3114
3114
  state.kvNamespaces.FORM_GUARD_KV.previewId,
@@ -3116,16 +3116,16 @@ async function destroyTreeseedEnvironmentResources(tenantRoot, options = {}) {
3116
3116
  state.kvNamespaces.SESSION?.previewId
3117
3117
  ].filter(Boolean));
3118
3118
  const legacyKvPrefix = state.identity?.deploymentKey ?? state.pages?.projectName ?? "";
3119
- const legacyKvNamespaces = dryRun ? [] : kvNamespaces.filter((namespace) => {
3119
+ const legacyKvNamespaces = planOnly ? [] : kvNamespaces.filter((namespace) => {
3120
3120
  const title = typeof namespace?.title === "string" ? namespace.title : "";
3121
3121
  const id = typeof namespace?.id === "string" ? namespace.id : "";
3122
3122
  return title && id && !knownKvIds.has(id) && legacyKvPrefix && title.includes(legacyKvPrefix) && title.includes(target.scope);
3123
3123
  }).map((namespace) => {
3124
- const result = deleteKvNamespace(tenantRoot, namespace.id, { env, dryRun: false });
3124
+ const result = deleteKvNamespace(tenantRoot, namespace.id, { env, planOnly: false });
3125
3125
  return resourceOperation("cloudflare", "kv-namespace", namespace.title, result.status, { ...result, legacy: true });
3126
3126
  });
3127
- const database = deleteD1DatabaseForDestroy(tenantRoot, state.d1Databases.SITE_DATA_DB.databaseName, { env, dryRun, deleteData });
3128
- const r2Bucket = bucket || dryRun ? deleteR2Bucket(tenantRoot, state.content?.bucketName, { env, dryRun, deleteData }) : resourceOperation("cloudflare", "r2-bucket", state.content?.bucketName, "missing");
3127
+ const database = deleteD1DatabaseForDestroy(tenantRoot, state.d1Databases.SITE_DATA_DB.databaseName, { env, planOnly, deleteData });
3128
+ const r2Bucket = bucket || planOnly ? deleteR2Bucket(tenantRoot, state.content?.bucketName, { env, planOnly, deleteData }) : resourceOperation("cloudflare", "r2-bucket", state.content?.bucketName, "missing");
3129
3129
  const pageDnsNames = [
3130
3130
  state.pages?.customDomain,
3131
3131
  deployConfig.surfaces?.web?.environments?.[target.scope]?.domain,
@@ -3135,22 +3135,22 @@ async function destroyTreeseedEnvironmentResources(tenantRoot, options = {}) {
3135
3135
  deployConfig.services?.api?.environments?.[target.scope]?.domain,
3136
3136
  deployConfig.surfaces?.api?.environments?.[target.scope]?.domain
3137
3137
  ].filter(Boolean);
3138
- const dnsRecords = [.../* @__PURE__ */ new Set([...pageDnsNames, ...apiDnsNames])].flatMap((name) => deleteDnsRecordsForName(deployConfig, name, { env, dryRun }));
3139
- const cacheRules = deleteTreeseedCacheRules(deployConfig, state, { env, dryRun });
3140
- const pageCustomDomains = pagesProject || dryRun ? deletePagesCustomDomains(tenantRoot, state.pages?.projectName, pageDnsNames, { env, dryRun, knownOnly: !destroysSharedWebSurface }) : [resourceOperation("cloudflare", "pages-custom-domain", state.pages?.projectName, "missing")];
3141
- const pageDeployments = pagesProject || dryRun ? deletePagesDeployments(tenantRoot, state.pages?.projectName, {
3138
+ const dnsRecords = [.../* @__PURE__ */ new Set([...pageDnsNames, ...apiDnsNames])].flatMap((name) => deleteDnsRecordsForName(deployConfig, name, { env, planOnly }));
3139
+ const cacheRules = deleteTreeseedCacheRules(deployConfig, state, { env, planOnly });
3140
+ const pageCustomDomains = pagesProject || planOnly ? deletePagesCustomDomains(tenantRoot, state.pages?.projectName, pageDnsNames, { env, planOnly, knownOnly: !destroysSharedWebSurface }) : [resourceOperation("cloudflare", "pages-custom-domain", state.pages?.projectName, "missing")];
3141
+ const pageDeployments = pagesProject || planOnly ? deletePagesDeployments(tenantRoot, state.pages?.projectName, {
3142
3142
  env,
3143
- dryRun,
3143
+ planOnly,
3144
3144
  environment: destroysSharedWebSurface ? "all" : "preview"
3145
3145
  }) : resourceOperation("cloudflare", "pages-deployments", state.pages?.projectName, "missing");
3146
- const pages = destroysSharedWebSurface && (pagesProject || dryRun) ? deletePagesProject(state.pages?.projectName, { env, dryRun }) : resourceOperation("cloudflare", "pages-project", state.pages?.projectName, "skipped", {
3146
+ const pages = destroysSharedWebSurface && (pagesProject || planOnly) ? deletePagesProject(state.pages?.projectName, { env, planOnly }) : resourceOperation("cloudflare", "pages-project", state.pages?.projectName, "skipped", {
3147
3147
  reason: target.scope === "prod" ? "delete_data_required" : "shared_web_surface"
3148
3148
  });
3149
- const local = target.kind === "persistent" && target.scope === "local" ? destroyLocalRuntimeResources(tenantRoot, { dryRun, deleteData }) : { operations: [] };
3150
- const railway = await destroyRailwayResources(tenantRoot, deployConfig, target, { dryRun, deleteData, env: process.env });
3149
+ const local = target.kind === "persistent" && target.scope === "local" ? destroyLocalRuntimeResources(tenantRoot, { planOnly, deleteData }) : { operations: [] };
3150
+ const railway = await destroyRailwayResources(tenantRoot, deployConfig, target, { planOnly, deleteData, env: process.env });
3151
3151
  const sweep = sweepTreeseed ? {
3152
- cloudflare: sweepTreeSeedCloudflareResources(tenantRoot, deployConfig, state, { env, dryRun, deleteData }),
3153
- railway: await sweepTreeSeedRailwayResources(deployConfig, state, { env: process.env, dryRun })
3152
+ cloudflare: sweepTreeSeedCloudflareResources(tenantRoot, deployConfig, state, { env, planOnly, deleteData }),
3153
+ railway: await sweepTreeSeedRailwayResources(deployConfig, state, { env: process.env, planOnly })
3154
3154
  } : { cloudflare: [], railway: [] };
3155
3155
  const operations = {
3156
3156
  cloudflare: [
@@ -3176,7 +3176,7 @@ async function destroyTreeseedEnvironmentResources(tenantRoot, options = {}) {
3176
3176
  ],
3177
3177
  local: local.operations
3178
3178
  };
3179
- const verification = dryRun ? null : {
3179
+ const verification = planOnly ? null : {
3180
3180
  cloudflare: cloudflareDestroyVerification(tenantRoot, deployConfig, state, env),
3181
3181
  ...target.kind === "persistent" && target.scope === "local" ? { localDocker: localDockerDestroyVerification() } : {}
3182
3182
  };
@@ -3197,15 +3197,15 @@ function destroyCloudflareResources(tenantRoot, options = {}) {
3197
3197
  const env = {
3198
3198
  CLOUDFLARE_ACCOUNT_ID: resolveConfiguredCloudflareAccountId(deployConfig)
3199
3199
  };
3200
- const dryRun = options.dryRun ?? false;
3200
+ const planOnly = options.planOnly ?? false;
3201
3201
  const deleteData = options.deleteData === true;
3202
3202
  const force = options.force ?? false;
3203
- const kvNamespaces = dryRun ? [] : listKvNamespaces(tenantRoot, env);
3204
- const d1Databases = dryRun ? [] : listD1Databases(tenantRoot, env);
3203
+ const kvNamespaces = planOnly ? [] : listKvNamespaces(tenantRoot, env);
3204
+ const d1Databases = planOnly ? [] : listD1Databases(tenantRoot, env);
3205
3205
  const queues = listQueues(tenantRoot, env);
3206
- const buckets = dryRun ? [] : listR2Buckets(tenantRoot, env);
3207
- const pagesProjects = dryRun ? [] : listPagesProjects(tenantRoot, env);
3208
- const turnstileWidgets = dryRun ? [] : listTurnstileWidgets(tenantRoot, env);
3206
+ const buckets = planOnly ? [] : listR2Buckets(tenantRoot, env);
3207
+ const pagesProjects = planOnly ? [] : listPagesProjects(tenantRoot, env);
3208
+ const turnstileWidgets = planOnly ? [] : listTurnstileWidgets(tenantRoot, env);
3209
3209
  state.kvNamespaces.FORM_GUARD_KV.id = resolveExistingKvIdByName(
3210
3210
  kvNamespaces,
3211
3211
  state.kvNamespaces.FORM_GUARD_KV.name,
@@ -3219,16 +3219,16 @@ function destroyCloudflareResources(tenantRoot, options = {}) {
3219
3219
  state.turnstileWidgets.formGuard = resolveExistingTurnstileWidget(turnstileWidgets, state.turnstileWidgets?.formGuard);
3220
3220
  const bucket = buckets.find((entry) => entry?.name === state.content?.bucketName);
3221
3221
  const pagesProject = pagesProjects.find((entry) => entry?.name === state.pages?.projectName);
3222
- const worker = deleteWorker(tenantRoot, state.workerName, { env, dryRun, force });
3222
+ const worker = deleteWorker(tenantRoot, state.workerName, { env, planOnly, force });
3223
3223
  const turnstileWidget = deleteTurnstileWidget(state.turnstileWidgets?.formGuard?.sitekey, {
3224
3224
  env,
3225
- dryRun,
3225
+ planOnly,
3226
3226
  name: state.turnstileWidgets?.formGuard?.name
3227
3227
  });
3228
- const formGuard = deleteKvNamespace(tenantRoot, state.kvNamespaces.FORM_GUARD_KV.id, { env, dryRun });
3229
- const database = deleteD1DatabaseForDestroy(tenantRoot, state.d1Databases.SITE_DATA_DB.databaseName, { env, dryRun, deleteData });
3230
- const r2Bucket = bucket || dryRun ? deleteR2Bucket(tenantRoot, state.content?.bucketName, { env, dryRun, deleteData }) : resourceOperation("cloudflare", "r2-bucket", state.content?.bucketName, "missing");
3231
- const pages = pagesProject || dryRun ? deletePagesProject(state.pages?.projectName, { env, dryRun }) : resourceOperation("cloudflare", "pages-project", state.pages?.projectName, "missing");
3228
+ const formGuard = deleteKvNamespace(tenantRoot, state.kvNamespaces.FORM_GUARD_KV.id, { env, planOnly });
3229
+ const database = deleteD1DatabaseForDestroy(tenantRoot, state.d1Databases.SITE_DATA_DB.databaseName, { env, planOnly, deleteData });
3230
+ const r2Bucket = bucket || planOnly ? deleteR2Bucket(tenantRoot, state.content?.bucketName, { env, planOnly, deleteData }) : resourceOperation("cloudflare", "r2-bucket", state.content?.bucketName, "missing");
3231
+ const pages = pagesProject || planOnly ? deletePagesProject(state.pages?.projectName, { env, planOnly }) : resourceOperation("cloudflare", "pages-project", state.pages?.projectName, "missing");
3232
3232
  const operations = {
3233
3233
  worker,
3234
3234
  turnstileWidget,
@@ -3269,12 +3269,12 @@ function provisionCloudflareResources(tenantRoot, options = {}) {
3269
3269
  const env = {
3270
3270
  CLOUDFLARE_ACCOUNT_ID: resolveConfiguredCloudflareAccountId(deployConfig)
3271
3271
  };
3272
- const dryRun = options.dryRun ?? false;
3273
- const kvNamespaces = dryRun ? [] : listKvNamespaces(tenantRoot, env);
3274
- const d1Databases = dryRun ? [] : listD1Databases(tenantRoot, env);
3275
- const queues = dryRun ? [] : listQueues(tenantRoot, env);
3276
- const buckets = dryRun ? [] : listR2Buckets(tenantRoot, env);
3277
- const pagesProjects = dryRun ? [] : listPagesProjects(tenantRoot, env);
3272
+ const planOnly = options.planOnly ?? false;
3273
+ const kvNamespaces = planOnly ? [] : listKvNamespaces(tenantRoot, env);
3274
+ const d1Databases = planOnly ? [] : listD1Databases(tenantRoot, env);
3275
+ const queues = planOnly ? [] : listQueues(tenantRoot, env);
3276
+ const buckets = planOnly ? [] : listR2Buckets(tenantRoot, env);
3277
+ const pagesProjects = planOnly ? [] : listPagesProjects(tenantRoot, env);
3278
3278
  const ensureKv = (binding) => {
3279
3279
  const current = state.kvNamespaces[binding];
3280
3280
  if (current?.id && !isPlaceholderResourceId(current.id)) {
@@ -3287,9 +3287,9 @@ function provisionCloudflareResources(tenantRoot, options = {}) {
3287
3287
  state.kvNamespaces[binding].previewId = existing.id;
3288
3288
  return;
3289
3289
  }
3290
- if (dryRun) {
3291
- state.kvNamespaces[binding].id = `dryrun-${current.name}`;
3292
- state.kvNamespaces[binding].previewId = `dryrun-${current.name}-preview`;
3290
+ if (planOnly) {
3291
+ state.kvNamespaces[binding].id = `plan-${current.name}`;
3292
+ state.kvNamespaces[binding].previewId = `plan-${current.name}-preview`;
3293
3293
  return;
3294
3294
  }
3295
3295
  runWrangler(["kv", "namespace", "create", current.name], { cwd: tenantRoot, capture: true, env });
@@ -3312,9 +3312,9 @@ function provisionCloudflareResources(tenantRoot, options = {}) {
3312
3312
  current.previewDatabaseId = existing.previewDatabaseUuid ?? existing.uuid;
3313
3313
  return;
3314
3314
  }
3315
- if (dryRun) {
3316
- current.databaseId = `dryrun-${current.databaseName}`;
3317
- current.previewDatabaseId = `dryrun-${current.databaseName}-preview`;
3315
+ if (planOnly) {
3316
+ current.databaseId = `plan-${current.databaseName}`;
3317
+ current.previewDatabaseId = `plan-${current.databaseName}-preview`;
3318
3318
  return;
3319
3319
  }
3320
3320
  runWrangler(["d1", "create", current.databaseName], {
@@ -3340,7 +3340,7 @@ function provisionCloudflareResources(tenantRoot, options = {}) {
3340
3340
  if (exists) {
3341
3341
  return;
3342
3342
  }
3343
- if (dryRun) {
3343
+ if (planOnly) {
3344
3344
  return;
3345
3345
  }
3346
3346
  try {
@@ -3370,7 +3370,7 @@ function provisionCloudflareResources(tenantRoot, options = {}) {
3370
3370
  ensurePagesProjectCompatibility(env.CLOUDFLARE_ACCOUNT_ID ?? process.env.TREESEED_CLOUDFLARE_ACCOUNT_ID ?? "", current.projectName, env, exists, { state, target });
3371
3371
  return;
3372
3372
  }
3373
- if (dryRun) {
3373
+ if (planOnly) {
3374
3374
  current.url = `https://${current.projectName}.pages.dev`;
3375
3375
  return;
3376
3376
  }
@@ -3393,7 +3393,7 @@ function provisionCloudflareResources(tenantRoot, options = {}) {
3393
3393
  ensureD1();
3394
3394
  ensureR2Bucket();
3395
3395
  ensurePagesProject();
3396
- reconcileCloudflareWebCacheRules(tenantRoot, deployConfig, state, target, { dryRun });
3396
+ reconcileCloudflareWebCacheRules(tenantRoot, deployConfig, state, target, { planOnly });
3397
3397
  state.readiness.configured = true;
3398
3398
  state.readiness.provisioned = hasProvisionedCloudflareResources(state);
3399
3399
  state.readiness.deployable = state.readiness.provisioned === true;
@@ -3424,13 +3424,13 @@ function syncCloudflareSecrets(tenantRoot, options = {}) {
3424
3424
  ...extraSecrets
3425
3425
  };
3426
3426
  const synced = [];
3427
- const dryRun = options.dryRun ?? false;
3427
+ const planOnly = options.planOnly ?? false;
3428
3428
  for (const [key, value] of Object.entries(secrets)) {
3429
3429
  if (!value) {
3430
3430
  continue;
3431
3431
  }
3432
3432
  synced.push(key);
3433
- if (dryRun) {
3433
+ if (planOnly) {
3434
3434
  continue;
3435
3435
  }
3436
3436
  const command = state.pages?.projectName && target.kind === "persistent" ? [resolveWranglerBin(), "pages", "secret", "put", key, "--project-name", state.pages.projectName] : [resolveWranglerBin(), "secret", "put", key, "--config", resolveGeneratedWranglerPath(tenantRoot, { target })];
@@ -3461,14 +3461,14 @@ function verifyProvisionedCloudflareResources(tenantRoot, options = {}) {
3461
3461
  const env = {
3462
3462
  CLOUDFLARE_ACCOUNT_ID: resolveConfiguredCloudflareAccountId(deployConfig)
3463
3463
  };
3464
- const dryRun = options.dryRun ?? false;
3465
- const kvNamespaces = dryRun ? [] : listKvNamespaces(tenantRoot, env);
3466
- const d1Databases = dryRun ? [] : listD1Databases(tenantRoot, env);
3467
- const queues = dryRun ? [] : listQueues(tenantRoot, env);
3468
- const buckets = dryRun ? [] : listR2Buckets(tenantRoot, env);
3469
- const pagesProjects = dryRun ? [] : listPagesProjects(tenantRoot, env);
3464
+ const planOnly = options.planOnly ?? false;
3465
+ const kvNamespaces = planOnly ? [] : listKvNamespaces(tenantRoot, env);
3466
+ const d1Databases = planOnly ? [] : listD1Databases(tenantRoot, env);
3467
+ const queues = planOnly ? [] : listQueues(tenantRoot, env);
3468
+ const buckets = planOnly ? [] : listR2Buckets(tenantRoot, env);
3469
+ const pagesProjects = planOnly ? [] : listPagesProjects(tenantRoot, env);
3470
3470
  const livePages = pagesProjects.find((entry) => entry?.name === state.pages?.projectName);
3471
- const pagesProject = dryRun || !env.CLOUDFLARE_ACCOUNT_ID || !state.pages?.projectName ? livePages : cloudflareApiRequest(
3471
+ const pagesProject = planOnly || !env.CLOUDFLARE_ACCOUNT_ID || !state.pages?.projectName ? livePages : cloudflareApiRequest(
3472
3472
  `/accounts/${encodeURIComponent(env.CLOUDFLARE_ACCOUNT_ID)}/pages/projects/${encodeURIComponent(state.pages.projectName)}`,
3473
3473
  { env, allowFailure: true }
3474
3474
  )?.result ?? livePages;
@@ -3486,7 +3486,7 @@ function verifyProvisionedCloudflareResources(tenantRoot, options = {}) {
3486
3486
  pagesR2Binding: !state.content?.r2Binding || !pagesBindings.r2_buckets?.[state.content.r2Binding] || pageBindingConfigured("r2_buckets", state.content.r2Binding, pagesBindings.r2_buckets[state.content.r2Binding]),
3487
3487
  webCache: !shouldManageCloudflareWebCacheRules(deployConfig, target) || state.webCache?.rulesManaged === true
3488
3488
  };
3489
- const ok = dryRun ? true : Object.values(checks).every(Boolean);
3489
+ const ok = planOnly ? true : Object.values(checks).every(Boolean);
3490
3490
  state.readiness.configured = true;
3491
3491
  state.readiness.provisioned = ok;
3492
3492
  state.readiness.deployable = ok;
@@ -3503,9 +3503,9 @@ function verifyProvisionedCloudflareResources(tenantRoot, options = {}) {
3503
3503
  state.pages.url = target.kind === "persistent" && target.scope === "staging" ? `https://${state.pages.stagingBranch ?? "staging"}.${livePages.subdomain}` : `https://${livePages.subdomain}`;
3504
3504
  }
3505
3505
  }
3506
- if (!dryRun) {
3506
+ if (!planOnly) {
3507
3507
  try {
3508
- reconcileCloudflareWebCacheRules(tenantRoot, deployConfig, state, target, { dryRun: false });
3508
+ reconcileCloudflareWebCacheRules(tenantRoot, deployConfig, state, target, { planOnly: false });
3509
3509
  } catch (error) {
3510
3510
  state.webCache.rulesManaged = false;
3511
3511
  state.webCache.lastError = error instanceof Error ? error.message : String(error);
@@ -3523,8 +3523,8 @@ function verifyProvisionedCloudflareResources(tenantRoot, options = {}) {
3523
3523
  function runRemoteD1Migrations(tenantRoot, options = {}) {
3524
3524
  const target = normalizeTarget(options.scope ?? options.target ?? "prod");
3525
3525
  const { wranglerPath, deployConfig, state } = ensureGeneratedWranglerConfig(tenantRoot, { target });
3526
- if (options.dryRun) {
3527
- return { databaseName: state.d1Databases.SITE_DATA_DB.databaseName, dryRun: true };
3526
+ if (options.planOnly) {
3527
+ return { databaseName: state.d1Databases.SITE_DATA_DB.databaseName, planOnly: true };
3528
3528
  }
3529
3529
  const args = ["d1", "migrations", "apply", state.d1Databases.SITE_DATA_DB.databaseName, "--remote", "--config", wranglerPath];
3530
3530
  const env = { CLOUDFLARE_ACCOUNT_ID: resolveConfiguredCloudflareAccountId(deployConfig) };
@@ -3538,7 +3538,7 @@ function runRemoteD1Migrations(tenantRoot, options = {}) {
3538
3538
  allowFailure: true
3539
3539
  });
3540
3540
  if (result.status === 0) {
3541
- return { databaseName: state.d1Databases.SITE_DATA_DB.databaseName, dryRun: false };
3541
+ return { databaseName: state.d1Databases.SITE_DATA_DB.databaseName, planOnly: false };
3542
3542
  }
3543
3543
  lastOutput = [result.stderr?.trim(), result.stdout?.trim()].filter(Boolean).join("\n");
3544
3544
  if (!isTransient(lastOutput) || attempt === 3) {