@treeseed/sdk 0.6.1 → 0.6.3

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 (33) hide show
  1. package/dist/operations/services/bootstrap-runner.d.ts +33 -0
  2. package/dist/operations/services/bootstrap-runner.js +136 -0
  3. package/dist/operations/services/config-runtime.d.ts +27 -8
  4. package/dist/operations/services/config-runtime.js +303 -127
  5. package/dist/operations/services/github-api.d.ts +34 -0
  6. package/dist/operations/services/github-api.js +187 -4
  7. package/dist/operations/services/github-automation.d.ts +30 -0
  8. package/dist/operations/services/github-automation.js +107 -1
  9. package/dist/operations/services/project-platform.d.ts +38 -2
  10. package/dist/operations/services/project-platform.js +319 -15
  11. package/dist/operations/services/railway-deploy.d.ts +6 -2
  12. package/dist/operations/services/railway-deploy.js +26 -18
  13. package/dist/operations/services/runtime-tools.d.ts +0 -2
  14. package/dist/operations/services/runtime-tools.js +0 -2
  15. package/dist/platform/env.yaml +71 -96
  16. package/dist/platform/environment.d.ts +4 -0
  17. package/dist/platform/environment.js +54 -0
  18. package/dist/reconcile/bootstrap-systems.d.ts +32 -0
  19. package/dist/reconcile/bootstrap-systems.js +175 -0
  20. package/dist/reconcile/builtin-adapters.js +1 -9
  21. package/dist/reconcile/desired-state.js +16 -14
  22. package/dist/reconcile/engine.d.ts +9 -4
  23. package/dist/reconcile/engine.js +57 -14
  24. package/dist/reconcile/index.d.ts +1 -0
  25. package/dist/reconcile/index.js +1 -0
  26. package/dist/scripts/config-treeseed.js +30 -0
  27. package/dist/scripts/package-tools.js +0 -2
  28. package/dist/scripts/tenant-deploy.js +16 -36
  29. package/dist/scripts/test-cloudflare-local.js +0 -2
  30. package/dist/workflow/operations.js +23 -4
  31. package/dist/workflow.d.ts +5 -0
  32. package/package.json +1 -1
  33. package/templates/github/deploy.workflow.yml +15 -15
@@ -27,11 +27,23 @@ function parseGitHubRepositorySlug(value) {
27
27
  name: rest.join("/")
28
28
  };
29
29
  }
30
- function createGitHubSignal(timeoutMs = DEFAULT_GITHUB_API_TIMEOUT_MS) {
30
+ function createGitHubRequestSignal(timeoutMs = DEFAULT_GITHUB_API_TIMEOUT_MS, upstreamSignal) {
31
31
  if (typeof AbortSignal !== "undefined" && typeof AbortSignal.timeout === "function") {
32
- return AbortSignal.timeout(timeoutMs);
32
+ const timeoutSignal = AbortSignal.timeout(timeoutMs);
33
+ if (upstreamSignal) {
34
+ const abortSignalAny = AbortSignal.any;
35
+ return typeof abortSignalAny === "function" ? abortSignalAny([upstreamSignal, timeoutSignal]) : timeoutSignal;
36
+ }
37
+ return timeoutSignal;
33
38
  }
34
- return void 0;
39
+ return upstreamSignal ?? void 0;
40
+ }
41
+ function createGitHubTimeoutFetch(timeoutMs = DEFAULT_GITHUB_API_TIMEOUT_MS) {
42
+ const baseFetch = globalThis.fetch.bind(globalThis);
43
+ return ((input, init) => {
44
+ const signal = createGitHubRequestSignal(timeoutMs, init?.signal ?? null);
45
+ return baseFetch(input, signal ? { ...init, signal } : init);
46
+ });
35
47
  }
36
48
  function normalizeGitHubApiError(error, context) {
37
49
  if (error && typeof error === "object") {
@@ -100,7 +112,7 @@ function createGitHubApiClient({
100
112
  return new Octokit({
101
113
  auth: token,
102
114
  request: {
103
- signal: createGitHubSignal(timeoutMs)
115
+ fetch: createGitHubTimeoutFetch(timeoutMs)
104
116
  }
105
117
  });
106
118
  }
@@ -208,6 +220,119 @@ async function listGitHubRepositoryVariableNames(repository, { client = createGi
208
220
  throw normalizeGitHubApiError(error, `Unable to list GitHub variables for ${owner}/${name}`);
209
221
  }
210
222
  }
223
+ async function ensureGitHubActionsEnvironment(repository, environmentName, {
224
+ client = createGitHubApiClient(),
225
+ branchName
226
+ } = {}) {
227
+ const { owner, name: repo } = typeof repository === "string" ? parseGitHubRepositorySlug(repository) : repository;
228
+ try {
229
+ await withGitHubApiRetries(() => client.request("PUT /repos/{owner}/{repo}/environments/{environment_name}", {
230
+ owner,
231
+ repo,
232
+ environment_name: environmentName,
233
+ ...branchName ? {
234
+ deployment_branch_policy: {
235
+ protected_branches: false,
236
+ custom_branch_policies: true
237
+ }
238
+ } : {}
239
+ }));
240
+ if (branchName) {
241
+ await ensureGitHubEnvironmentBranchPolicy(client, {
242
+ owner,
243
+ repo,
244
+ environmentName,
245
+ branchName
246
+ });
247
+ }
248
+ return { repository: `${owner}/${repo}`, environment: environmentName };
249
+ } catch (error) {
250
+ throw normalizeGitHubApiError(error, `Unable to ensure GitHub environment ${environmentName} for ${owner}/${repo}`);
251
+ }
252
+ }
253
+ async function ensureGitHubEnvironmentBranchPolicy(client, {
254
+ owner,
255
+ repo,
256
+ environmentName,
257
+ branchName
258
+ }) {
259
+ const response = await withGitHubApiRetries(() => client.request(
260
+ "GET /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies",
261
+ {
262
+ owner,
263
+ repo,
264
+ environment_name: environmentName,
265
+ per_page: 100
266
+ }
267
+ ));
268
+ const policies = Array.isArray(response.data?.branch_policies) ? response.data.branch_policies : [];
269
+ const desired = policies.find((policy) => policy.name === branchName && (policy.type ?? "branch") === "branch");
270
+ for (const policy of policies) {
271
+ if (!policy.id || policy.name === branchName && (policy.type ?? "branch") === "branch") {
272
+ continue;
273
+ }
274
+ await withGitHubApiRetries(() => client.request(
275
+ "DELETE /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies/{branch_policy_id}",
276
+ {
277
+ owner,
278
+ repo,
279
+ environment_name: environmentName,
280
+ branch_policy_id: policy.id
281
+ }
282
+ ));
283
+ }
284
+ if (desired) {
285
+ return;
286
+ }
287
+ try {
288
+ await withGitHubApiRetries(() => client.request(
289
+ "POST /repos/{owner}/{repo}/environments/{environment_name}/deployment-branch-policies",
290
+ {
291
+ owner,
292
+ repo,
293
+ environment_name: environmentName,
294
+ name: branchName,
295
+ type: "branch"
296
+ }
297
+ ));
298
+ } catch (error) {
299
+ if (error && typeof error === "object" && error.status === 303) {
300
+ return;
301
+ }
302
+ throw error;
303
+ }
304
+ }
305
+ async function paginateGitHubEnvironmentNames(client, route, params) {
306
+ const paginate = client.paginate;
307
+ return await paginateNames(() => paginate(route, {
308
+ ...params,
309
+ per_page: 100
310
+ }));
311
+ }
312
+ async function listGitHubEnvironmentSecretNames(repository, environmentName, { client = createGitHubApiClient() } = {}) {
313
+ const { owner, name } = typeof repository === "string" ? parseGitHubRepositorySlug(repository) : repository;
314
+ try {
315
+ return await paginateGitHubEnvironmentNames(
316
+ client,
317
+ "GET /repos/{owner}/{repo}/environments/{environment_name}/secrets",
318
+ { owner, repo: name, environment_name: environmentName }
319
+ );
320
+ } catch (error) {
321
+ throw normalizeGitHubApiError(error, `Unable to list GitHub environment secrets for ${owner}/${name}:${environmentName}`);
322
+ }
323
+ }
324
+ async function listGitHubEnvironmentVariableNames(repository, environmentName, { client = createGitHubApiClient() } = {}) {
325
+ const { owner, name } = typeof repository === "string" ? parseGitHubRepositorySlug(repository) : repository;
326
+ try {
327
+ return await paginateGitHubEnvironmentNames(
328
+ client,
329
+ "GET /repos/{owner}/{repo}/environments/{environment_name}/variables",
330
+ { owner, repo: name, environment_name: environmentName }
331
+ );
332
+ } catch (error) {
333
+ throw normalizeGitHubApiError(error, `Unable to list GitHub environment variables for ${owner}/${name}:${environmentName}`);
334
+ }
335
+ }
211
336
  async function encryptGitHubSecret(secret, key) {
212
337
  await sodium.ready;
213
338
  const messageBytes = Buffer.from(secret);
@@ -233,6 +358,27 @@ async function upsertGitHubRepositorySecret(repository, name, value, { client =
233
358
  throw normalizeGitHubApiError(error, `Unable to upsert GitHub secret ${name} for ${owner}/${repo}`);
234
359
  }
235
360
  }
361
+ async function upsertGitHubEnvironmentSecret(repository, environmentName, name, value, { client = createGitHubApiClient() } = {}) {
362
+ const { owner, name: repo } = typeof repository === "string" ? parseGitHubRepositorySlug(repository) : repository;
363
+ try {
364
+ const key = await client.request("GET /repos/{owner}/{repo}/environments/{environment_name}/secrets/public-key", {
365
+ owner,
366
+ repo,
367
+ environment_name: environmentName
368
+ });
369
+ const encryptedValue = await encryptGitHubSecret(value, String(key.data.key ?? ""));
370
+ await withGitHubApiRetries(() => client.request("PUT /repos/{owner}/{repo}/environments/{environment_name}/secrets/{secret_name}", {
371
+ owner,
372
+ repo,
373
+ environment_name: environmentName,
374
+ secret_name: name,
375
+ encrypted_value: encryptedValue,
376
+ key_id: String(key.data.key_id ?? "")
377
+ }));
378
+ } catch (error) {
379
+ throw normalizeGitHubApiError(error, `Unable to upsert GitHub environment secret ${name} for ${owner}/${repo}:${environmentName}`);
380
+ }
381
+ }
236
382
  async function upsertGitHubRepositoryVariable(repository, name, value, { client = createGitHubApiClient() } = {}) {
237
383
  const { owner, name: repo } = typeof repository === "string" ? parseGitHubRepositorySlug(repository) : repository;
238
384
  try {
@@ -273,6 +419,38 @@ async function upsertGitHubRepositoryVariable(repository, name, value, { client
273
419
  throw normalizeGitHubApiError(error, `Unable to upsert GitHub variable ${name} for ${owner}/${repo}`);
274
420
  }
275
421
  }
422
+ async function upsertGitHubEnvironmentVariable(repository, environmentName, name, value, { client = createGitHubApiClient() } = {}) {
423
+ const { owner, name: repo } = typeof repository === "string" ? parseGitHubRepositorySlug(repository) : repository;
424
+ try {
425
+ await withGitHubApiRetries(async () => {
426
+ try {
427
+ await client.request("POST /repos/{owner}/{repo}/environments/{environment_name}/variables", {
428
+ owner,
429
+ repo,
430
+ environment_name: environmentName,
431
+ name,
432
+ value
433
+ });
434
+ return;
435
+ } catch (error) {
436
+ const status = typeof error?.status === "number" ? Number(error.status) : null;
437
+ const message = error instanceof Error ? error.message : String(error ?? "");
438
+ if (status !== 409 && status !== 422 && !/already exists/iu.test(message)) {
439
+ throw error;
440
+ }
441
+ }
442
+ await client.request("PATCH /repos/{owner}/{repo}/environments/{environment_name}/variables/{name}", {
443
+ owner,
444
+ repo,
445
+ environment_name: environmentName,
446
+ name,
447
+ value
448
+ });
449
+ });
450
+ } catch (error) {
451
+ throw normalizeGitHubApiError(error, `Unable to upsert GitHub environment variable ${name} for ${owner}/${repo}:${environmentName}`);
452
+ }
453
+ }
276
454
  function upsertGitHubRepositoryVariableWithGhCli(repository, name, value, {
277
455
  env = process.env
278
456
  } = {}) {
@@ -440,14 +618,19 @@ async function ensureGitHubBranchFromBase(repository, branch, {
440
618
  }
441
619
  export {
442
620
  createGitHubApiClient,
621
+ ensureGitHubActionsEnvironment,
443
622
  ensureGitHubBranchFromBase,
444
623
  ensureGitHubRepository,
445
624
  getGitHubRepository,
625
+ listGitHubEnvironmentSecretNames,
626
+ listGitHubEnvironmentVariableNames,
446
627
  listGitHubRepositorySecretNames,
447
628
  listGitHubRepositoryVariableNames,
448
629
  maybeGetGitHubRepository,
449
630
  parseGitHubRepositorySlug,
450
631
  resolveGitHubApiToken,
632
+ upsertGitHubEnvironmentSecret,
633
+ upsertGitHubEnvironmentVariable,
451
634
  upsertGitHubRepositorySecret,
452
635
  upsertGitHubRepositoryVariable,
453
636
  upsertGitHubRepositoryVariableWithGhCli,
@@ -16,11 +16,41 @@ export interface GitHubProvisionedRepository {
16
16
  visibility: 'private' | 'public' | 'internal';
17
17
  defaultBranch: string;
18
18
  }
19
+ export interface TreeseedGitHubRepositoryTarget {
20
+ owner: string;
21
+ name: string;
22
+ visibility: 'private' | 'public' | 'internal';
23
+ source: 'config' | 'origin' | 'default';
24
+ }
19
25
  export declare function getGitHubAutomationMode(): "stub" | "real";
20
26
  export declare function parseGitHubRepositoryFromRemote(remoteUrl: any): string | null;
21
27
  export declare function resolveGitHubRepositorySlug(tenantRoot: any): string;
22
28
  export declare function maybeResolveGitHubRepositorySlug(tenantRoot: any): string | null;
23
29
  export declare function resolveDefaultGitHubOwner(): string;
30
+ export declare function resolveGitHubRepositoryTarget(tenantRoot: string, { values, defaultName, }?: {
31
+ values?: Record<string, string | undefined>;
32
+ defaultName?: string;
33
+ }): TreeseedGitHubRepositoryTarget;
34
+ export declare function ensureGitHubBootstrapRepository(tenantRoot: string, { values, defaultName, onProgress, }?: {
35
+ values?: Record<string, string | undefined>;
36
+ defaultName?: string;
37
+ onProgress?: (message: string) => void;
38
+ }): Promise<{
39
+ repository: string;
40
+ target: TreeseedGitHubRepositoryTarget;
41
+ created: boolean;
42
+ remote: {
43
+ changed: boolean;
44
+ previous: null;
45
+ next: string;
46
+ } | {
47
+ changed: boolean;
48
+ previous: string;
49
+ next: string;
50
+ };
51
+ pushed: boolean;
52
+ mode: string;
53
+ }>;
24
54
  export declare function createGitHubRepository(input: any): Promise<import("./github-api.ts").GitHubRepositorySummary | {
25
55
  visibility: any;
26
56
  defaultBranch: string;
@@ -6,6 +6,8 @@ import { packageRoot, loadCliDeployConfig } from "./runtime-tools.js";
6
6
  import {
7
7
  createGitHubApiClient,
8
8
  ensureGitHubRepository,
9
+ maybeGetGitHubRepository,
10
+ parseGitHubRepositorySlug,
9
11
  listGitHubRepositorySecretNames,
10
12
  listGitHubRepositoryVariableNames,
11
13
  upsertGitHubRepositorySecret,
@@ -97,7 +99,7 @@ function maybeResolveGitHubRepositorySlug(tenantRoot) {
97
99
  }
98
100
  }
99
101
  function resolveDefaultGitHubOwner() {
100
- const explicit = envOrNull("TREESEED_KNOWLEDGE_COOP_GITHUB_OWNER");
102
+ const explicit = envOrNull("TREESEED_GITHUB_OWNER");
101
103
  if (explicit) {
102
104
  return explicit;
103
105
  }
@@ -110,6 +112,108 @@ function resolveDefaultGitHubOwner() {
110
112
  }
111
113
  return "treeseed-ai";
112
114
  }
115
+ function normalizeGitHubVisibility(value) {
116
+ const normalized = String(value ?? "").trim().toLowerCase();
117
+ return normalized === "public" || normalized === "internal" || normalized === "private" ? normalized : "private";
118
+ }
119
+ function configuredValue(values, key) {
120
+ const value = values?.[key] ?? process.env[key];
121
+ return typeof value === "string" && value.trim().length > 0 ? value.trim() : "";
122
+ }
123
+ function resolveGitHubRepositoryTarget(tenantRoot, {
124
+ values = {},
125
+ defaultName
126
+ } = {}) {
127
+ const origin = maybeResolveGitHubRepositorySlug(tenantRoot);
128
+ const parsedOrigin = origin ? parseGitHubRepositorySlug(origin) : null;
129
+ const owner = configuredValue(values, "TREESEED_GITHUB_OWNER") || parsedOrigin?.owner || "";
130
+ const name = configuredValue(values, "TREESEED_GITHUB_REPOSITORY_NAME") || parsedOrigin?.name || defaultName || "project";
131
+ if (!owner) {
132
+ throw new Error("Configure TREESEED_GITHUB_OWNER before GitHub repository bootstrap.");
133
+ }
134
+ return {
135
+ owner: slugifySegment(owner, "owner"),
136
+ name: slugifySegment(name, "project"),
137
+ visibility: normalizeGitHubVisibility(configuredValue(values, "TREESEED_GITHUB_REPOSITORY_VISIBILITY")),
138
+ source: configuredValue(values, "TREESEED_GITHUB_OWNER") || configuredValue(values, "TREESEED_GITHUB_REPOSITORY_NAME") ? "config" : parsedOrigin ? "origin" : "default"
139
+ };
140
+ }
141
+ function ensureGitRepositoryInitialized(cwd, defaultBranch) {
142
+ const insideWorkTree = runGit(["rev-parse", "--is-inside-work-tree"], { cwd, allowFailure: true }).stdout?.trim() === "true";
143
+ if (!insideWorkTree) {
144
+ runGit(["init", "-b", defaultBranch], { cwd });
145
+ }
146
+ ensureGitIdentity(cwd);
147
+ }
148
+ function ensureOriginRemote(cwd, repository, remoteName = "origin") {
149
+ const currentRemote = runGit(["remote", "get-url", remoteName], { cwd, allowFailure: true }).stdout?.trim() ?? "";
150
+ if (!currentRemote) {
151
+ runGit(["remote", "add", remoteName, repository.sshUrl], { cwd });
152
+ return { changed: true, previous: null, next: repository.sshUrl };
153
+ }
154
+ if (currentRemote !== repository.sshUrl && currentRemote !== repository.httpsUrl) {
155
+ runGit(["remote", "set-url", remoteName, repository.sshUrl], { cwd });
156
+ return { changed: true, previous: currentRemote, next: repository.sshUrl };
157
+ }
158
+ return { changed: false, previous: currentRemote, next: currentRemote };
159
+ }
160
+ function pushAllGitHubRefs(cwd, remoteName = "origin") {
161
+ runGit(["push", "-u", remoteName, "--all"], { cwd, capture: false });
162
+ runGit(["push", remoteName, "--tags"], { cwd, capture: false });
163
+ }
164
+ async function ensureGitHubBootstrapRepository(tenantRoot, {
165
+ values = {},
166
+ defaultName,
167
+ onProgress
168
+ } = {}) {
169
+ const target = resolveGitHubRepositoryTarget(tenantRoot, { values, defaultName });
170
+ const remotes = resolveGitHubRemoteUrls(target.owner, target.name);
171
+ const slug = remotes.slug;
172
+ onProgress?.(`[local][github][repo] Preparing ${slug} from ${target.source}...`);
173
+ if (isGitHubAutomationStubbed()) {
174
+ onProgress?.(`[local][github][repo] Stubbed GitHub automation; repository ${slug} not changed.`);
175
+ return {
176
+ repository: slug,
177
+ target,
178
+ created: false,
179
+ remote: { changed: false, previous: null, next: remotes.sshUrl },
180
+ pushed: false,
181
+ mode: "stub"
182
+ };
183
+ }
184
+ const client = createGitHubApiClient({
185
+ env: {
186
+ GH_TOKEN: configuredValue(values, "GH_TOKEN") || configuredValue(values, "GITHUB_TOKEN"),
187
+ GITHUB_TOKEN: configuredValue(values, "GH_TOKEN") || configuredValue(values, "GITHUB_TOKEN")
188
+ }
189
+ });
190
+ const existing = await maybeGetGitHubRepository({ owner: target.owner, name: target.name }, { client });
191
+ const repository = existing ?? await ensureGitHubRepository({
192
+ owner: target.owner,
193
+ name: target.name,
194
+ visibility: target.visibility
195
+ }, { client });
196
+ const created = !existing;
197
+ onProgress?.(`[local][github][repo] ${created ? "Created" : "Verified"} ${repository.slug}.`);
198
+ ensureGitRepositoryInitialized(tenantRoot, repository.defaultBranch || "main");
199
+ const remote = ensureOriginRemote(tenantRoot, repository);
200
+ if (remote.changed) {
201
+ onProgress?.(`[local][github][repo] Updated origin remote to ${repository.slug}.`);
202
+ }
203
+ if (created) {
204
+ onProgress?.(`[local][github][repo] Pushing all local branches and tags to ${repository.slug}...`);
205
+ pushAllGitHubRefs(tenantRoot);
206
+ onProgress?.(`[local][github][repo] Pushed all local branches and tags to ${repository.slug}.`);
207
+ }
208
+ return {
209
+ repository: repository.slug,
210
+ target,
211
+ created,
212
+ remote,
213
+ pushed: created,
214
+ mode: "real"
215
+ };
216
+ }
113
217
  async function createGitHubRepository(input) {
114
218
  const visibility = input.visibility ?? "private";
115
219
  const remotes = resolveGitHubRemoteUrls(input.owner, input.name);
@@ -422,6 +526,7 @@ async function waitForGitHubWorkflowCompletion(tenantRoot, {
422
526
  export {
423
527
  createGitHubRepository,
424
528
  ensureDeployWorkflow,
529
+ ensureGitHubBootstrapRepository,
425
530
  ensureGitHubDeployAutomation,
426
531
  ensureGitHubEnvironment,
427
532
  ensureGitHubSecrets,
@@ -440,6 +545,7 @@ export {
440
545
  requiredGitHubSecrets,
441
546
  resolveDefaultGitHubOwner,
442
547
  resolveGitHubRepositorySlug,
548
+ resolveGitHubRepositoryTarget,
443
549
  resolveGitRepositoryRoot,
444
550
  waitForGitHubWorkflowCompletion
445
551
  };
@@ -1,4 +1,6 @@
1
1
  import { type ControlPlaneReporter } from '../../control-plane.ts';
2
+ import type { TreeseedRunnableBootstrapSystem } from '../../reconcile/index.ts';
3
+ import { type TreeseedBootstrapExecution, type TreeseedBootstrapWriter } from './bootstrap-runner.ts';
2
4
  export type ProjectPlatformScope = 'local' | 'staging' | 'prod';
3
5
  export type ProjectPlatformAction = 'provision' | 'deploy_code' | 'publish_content' | 'monitor';
4
6
  export interface ProjectPlatformActionOptions {
@@ -9,9 +11,43 @@ export interface ProjectPlatformActionOptions {
9
11
  dryRun?: boolean;
10
12
  reporter?: ControlPlaneReporter;
11
13
  skipProvision?: boolean;
14
+ bootstrapSystems?: TreeseedRunnableBootstrapSystem[];
15
+ bootstrapExecution?: TreeseedBootstrapExecution;
16
+ write?: TreeseedBootstrapWriter;
17
+ env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
12
18
  }
13
19
  export declare function inferEnvironmentFromBranch(tenantRoot: string): "staging" | "prod";
14
20
  export declare function resolveScope(environment: string | null): ProjectPlatformScope;
21
+ export type TenantCloudflareDeployContext = {
22
+ tenantRoot: string;
23
+ scope: ProjectPlatformScope;
24
+ target: any;
25
+ dryRun?: boolean;
26
+ wranglerPath: string;
27
+ databaseName: string;
28
+ pagesProjectName: string | null;
29
+ pagesBranchName: string | null;
30
+ env: NodeJS.ProcessEnv | Record<string, string | undefined>;
31
+ write?: TreeseedBootstrapWriter;
32
+ };
33
+ export declare function prepareTenantCloudflareDeploy({ tenantRoot, scope, target: explicitTarget, dryRun, write, env, }: {
34
+ tenantRoot: string;
35
+ scope: ProjectPlatformScope;
36
+ target?: any;
37
+ dryRun?: boolean;
38
+ write?: TreeseedBootstrapWriter;
39
+ env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
40
+ }): TenantCloudflareDeployContext;
41
+ export declare function runTenantDataMigration(context: TenantCloudflareDeployContext): Promise<{
42
+ databaseName: string;
43
+ dryRun: boolean;
44
+ }>;
45
+ export declare function runTenantWebBuild(context: Pick<TenantCloudflareDeployContext, 'tenantRoot' | 'scope' | 'dryRun' | 'env' | 'write'>): Promise<{
46
+ dryRun: boolean;
47
+ }>;
48
+ export declare function runTenantWebPublish(context: TenantCloudflareDeployContext): Promise<{
49
+ dryRun: boolean;
50
+ }>;
15
51
  export declare function provisionProjectPlatform(options: ProjectPlatformActionOptions): Promise<{
16
52
  ok: boolean;
17
53
  scope: ProjectPlatformScope;
@@ -209,7 +245,7 @@ export declare function deployProjectPlatform(options: ProjectPlatformActionOpti
209
245
  healthcheckTimeoutSeconds: number | null;
210
246
  runtimeMode: string | null;
211
247
  } | null;
212
- })[];
248
+ } | undefined)[];
213
249
  }>;
214
250
  export declare function publishProjectContent(options: ProjectPlatformActionOptions): Promise<{
215
251
  ok: boolean;
@@ -698,5 +734,5 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
698
734
  healthcheckTimeoutSeconds: number | null;
699
735
  runtimeMode: string | null;
700
736
  } | null;
701
- })[];
737
+ } | undefined)[];
702
738
  }>;