@treeseed/sdk 0.10.18 → 0.10.20

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.
@@ -199,7 +199,7 @@ export declare function getRailwayServiceInstance({ serviceId, environmentId, en
199
199
  sleepApplication: null;
200
200
  runtimeConfigSupported: false;
201
201
  }>;
202
- export declare function ensureRailwayServiceInstanceConfiguration({ serviceId, environmentId, buildCommand, startCommand, cronSchedule, rootDirectory, healthcheckPath, healthcheckTimeoutSeconds, healthcheckIntervalSeconds, restartPolicy, runtimeMode, env, fetchImpl, }: {
202
+ export declare function ensureRailwayServiceInstanceConfiguration({ serviceId, environmentId, buildCommand, startCommand, cronSchedule, rootDirectory, healthcheckPath, healthcheckTimeoutSeconds, healthcheckIntervalSeconds, restartPolicy, runtimeMode, env, fetchImpl, settleAttempts, settleDelayMs, }: {
203
203
  serviceId: string;
204
204
  environmentId: string;
205
205
  buildCommand?: string | null;
@@ -213,6 +213,8 @@ export declare function ensureRailwayServiceInstanceConfiguration({ serviceId, e
213
213
  runtimeMode?: string | null;
214
214
  env?: NodeJS.ProcessEnv | Record<string, string | undefined>;
215
215
  fetchImpl?: typeof fetch;
216
+ settleAttempts?: number;
217
+ settleDelayMs?: number;
216
218
  }): Promise<{
217
219
  instance: {
218
220
  id: string | null;
@@ -838,7 +838,9 @@ async function ensureRailwayServiceInstanceConfiguration({
838
838
  restartPolicy,
839
839
  runtimeMode,
840
840
  env = process.env,
841
- fetchImpl = fetch
841
+ fetchImpl = fetch,
842
+ settleAttempts = 24,
843
+ settleDelayMs = 5e3
842
844
  }) {
843
845
  let current = await getRailwayServiceInstance({ serviceId, environmentId, env, fetchImpl });
844
846
  if (!current.id) {
@@ -911,34 +913,32 @@ mutation TreeseedRailwayServiceInstanceUpdateLegacy($serviceId: String!, $enviro
911
913
  }
912
914
  throw error;
913
915
  }
914
- let instance = await getRailwayServiceInstance({
915
- serviceId,
916
- environmentId,
917
- env,
918
- fetchImpl
919
- });
920
- for (let attempt = 0; attempt < 5 && serviceInstanceDrifted(instance, desired); attempt += 1) {
921
- await new Promise((resolve) => setTimeout(resolve, 1e3));
916
+ let instance = current;
917
+ for (let attempt = 0; attempt <= settleAttempts; attempt += 1) {
922
918
  instance = await getRailwayServiceInstance({
923
919
  serviceId,
924
920
  environmentId,
925
921
  env,
926
922
  fetchImpl
927
923
  });
924
+ if (!serviceInstanceDrifted(instance, desired) || attempt >= settleAttempts) {
925
+ break;
926
+ }
927
+ await new Promise((resolve) => setTimeout(resolve, settleDelayMs));
928
928
  }
929
929
  return {
930
930
  instance: {
931
931
  id: instance.id || current.id,
932
- buildCommand: instance.buildCommand ?? desired.buildCommand,
933
- startCommand: instance.startCommand ?? desired.startCommand,
934
- cronSchedule: instance.cronSchedule ?? desired.cronSchedule,
935
- rootDirectory: instance.rootDirectory ?? desired.rootDirectory,
936
- healthcheckPath: instance.healthcheckPath ?? desired.healthcheckPath,
937
- healthcheckTimeoutSeconds: instance.healthcheckTimeoutSeconds ?? desired.healthcheckTimeoutSeconds,
938
- healthcheckIntervalSeconds: instance.healthcheckIntervalSeconds ?? desired.healthcheckIntervalSeconds,
939
- restartPolicy: instance.restartPolicy ?? desired.restartPolicy,
940
- runtimeMode: instance.runtimeMode ?? desired.runtimeMode,
941
- sleepApplication: instance.sleepApplication ?? desired.sleepApplication,
932
+ buildCommand: instance.buildCommand,
933
+ startCommand: instance.startCommand,
934
+ cronSchedule: instance.cronSchedule,
935
+ rootDirectory: instance.rootDirectory,
936
+ healthcheckPath: instance.healthcheckPath,
937
+ healthcheckTimeoutSeconds: instance.healthcheckTimeoutSeconds,
938
+ healthcheckIntervalSeconds: instance.healthcheckIntervalSeconds,
939
+ restartPolicy: instance.restartPolicy,
940
+ runtimeMode: instance.runtimeMode,
941
+ sleepApplication: instance.sleepApplication,
942
942
  runtimeConfigSupported: instance.runtimeConfigSupported
943
943
  },
944
944
  updated: true
@@ -4,7 +4,16 @@ export declare function deriveRailwayMarketOperationsRunnerServiceName(baseServi
4
4
  export declare function deriveRailwayWorkerRunnerVolumeName(serviceName: any, environmentName?: string): string;
5
5
  export declare function deriveRailwayMarketOperationsRunnerVolumeName(serviceName: any, environmentName?: string): string;
6
6
  export declare function railwayServiceRuntimeStartCommand(service: any): any;
7
+ export declare function parseRailwayJsonOutput(output: any): any;
7
8
  export declare function collectRailwayDeploymentStatusChecks(statusPayload: any, scope: any, services: any): any;
9
+ export declare function listRailwayServiceVolumesWithCli({ cwd, serviceId, environmentId, name, mountPath, env, }: {
10
+ cwd: any;
11
+ serviceId: any;
12
+ environmentId: any;
13
+ name: any;
14
+ mountPath: any;
15
+ env?: NodeJS.ProcessEnv | undefined;
16
+ }): any;
8
17
  export declare function isUsableRailwayToken(value: any): boolean;
9
18
  export declare function resolveRailwayAuthToken(env?: NodeJS.ProcessEnv): string;
10
19
  export declare function buildRailwayCommandEnv(env?: NodeJS.ProcessEnv): {
@@ -225,6 +225,30 @@ function normalizeRailwayCliVolumeList(value, options) {
225
225
  }
226
226
  return value.volumes.map((entry) => normalizeRailwayCliVolume(entry, options)).filter(Boolean);
227
227
  }
228
+ function listRailwayServiceVolumesWithCli({
229
+ cwd,
230
+ serviceId,
231
+ environmentId,
232
+ name,
233
+ mountPath,
234
+ env = process.env
235
+ }) {
236
+ const listResult = runRailway(["volume", "--service", serviceId, "--environment", environmentId, "list", "--json"], {
237
+ cwd,
238
+ capture: true,
239
+ allowFailure: true,
240
+ env
241
+ });
242
+ if ((listResult.status ?? 1) !== 0) {
243
+ return [];
244
+ }
245
+ return normalizeRailwayCliVolumeList(parseRailwayJsonOutput(listResult.stdout ?? ""), {
246
+ serviceId,
247
+ environmentId,
248
+ fallbackName: name,
249
+ fallbackMountPath: mountPath
250
+ });
251
+ }
228
252
  function isUsableRailwayToken(value) {
229
253
  return typeof value === "string" && value.trim().length >= 8;
230
254
  }
@@ -589,9 +613,7 @@ function setRailwaySecretVariable({ cwd, service, environment, key, value, env =
589
613
  }
590
614
  function ensureRailwayProjectExists(service, { env = process.env } = {}) {
591
615
  const projectName = typeof service?.projectName === "string" ? service.projectName.trim() : "";
592
- if (!projectName) {
593
- throw new Error(`Railway service ${service?.key ?? service?.serviceName ?? service?.serviceId ?? "(unknown)"} is missing a projectName.`);
594
- }
616
+ const projectId = typeof service?.projectId === "string" ? service.projectId.trim() : "";
595
617
  const listed = runRailway(["list", "--json"], {
596
618
  cwd: service.rootDir,
597
619
  capture: true,
@@ -599,11 +621,17 @@ function ensureRailwayProjectExists(service, { env = process.env } = {}) {
599
621
  env
600
622
  });
601
623
  if (listed.status === 0) {
602
- const match = normalizeRailwayProjectList(listed.stdout ?? "").find((entry) => entry.name === projectName || entry.id === projectName);
624
+ const match = normalizeRailwayProjectList(listed.stdout ?? "").find((entry) => entry.name === projectName || entry.id === projectName || entry.id === projectId);
603
625
  if (match) {
604
626
  return match;
605
627
  }
606
628
  }
629
+ if (!projectName) {
630
+ if (projectId) {
631
+ return { id: projectId, name: "" };
632
+ }
633
+ throw new Error(`Railway service ${service?.key ?? service?.serviceName ?? service?.serviceId ?? "(unknown)"} is missing a projectName.`);
634
+ }
607
635
  const args = ["init", "--name", projectName, "--json"];
608
636
  const workspace = resolveRailwayWorkspace(env);
609
637
  if (workspace) {
@@ -1734,6 +1762,16 @@ async function ensureRailwayServiceVolumeWithCliFallback({
1734
1762
  capture: true,
1735
1763
  env
1736
1764
  };
1765
+ ensureRailwayProjectContext({
1766
+ key: serviceName,
1767
+ projectId,
1768
+ serviceName,
1769
+ rootDir: tenantRoot,
1770
+ railwayEnvironment: environmentName
1771
+ }, {
1772
+ env,
1773
+ capture: true
1774
+ });
1737
1775
  const volumeArgs = ["volume", "--service", serviceId, "--environment", environmentId];
1738
1776
  const listResult = runRailway([...volumeArgs, "list", "--json"], cliOptions);
1739
1777
  const existingVolumes = normalizeRailwayCliVolumeList(parseRailwayJsonOutput(listResult.stdout ?? ""), {
@@ -1758,7 +1796,43 @@ async function ensureRailwayServiceVolumeWithCliFallback({
1758
1796
  }
1759
1797
  created = true;
1760
1798
  }
1761
- const instance = volume.instances.find((entry) => entry.serviceId === serviceId && entry.environmentId === environmentId) ?? volume.instances[0] ?? null;
1799
+ let instance = volume.instances.find((entry) => entry.serviceId === serviceId && entry.environmentId === environmentId) ?? volume.instances[0] ?? null;
1800
+ if (!instance || instance.mountPath !== mountPath) {
1801
+ const attachResult = runRailway([...volumeArgs, "attach", "--volume", volume.id, "--yes", "--json"], {
1802
+ ...cliOptions,
1803
+ allowFailure: true
1804
+ });
1805
+ if ((attachResult.status ?? 1) !== 0) {
1806
+ const attachMessage = attachResult.stderr?.trim() || attachResult.stdout?.trim() || "";
1807
+ if (!/already mounted/iu.test(attachMessage)) {
1808
+ throw new Error(attachMessage || `Railway volume attach failed for ${serviceName} in ${environmentName}.`);
1809
+ }
1810
+ }
1811
+ const attachedVolume = (attachResult.status ?? 1) === 0 ? normalizeRailwayCliVolume(parseRailwayJsonOutput(attachResult.stdout ?? ""), {
1812
+ serviceId,
1813
+ environmentId,
1814
+ fallbackName: name,
1815
+ fallbackMountPath: mountPath
1816
+ }) : null;
1817
+ volume = attachedVolume ?? {
1818
+ ...volume,
1819
+ instances: [{
1820
+ ...instance ?? {
1821
+ id: volume.id,
1822
+ serviceId,
1823
+ environmentId,
1824
+ state: "READY",
1825
+ sizeGb: null,
1826
+ usedGb: null
1827
+ },
1828
+ serviceId,
1829
+ environmentId,
1830
+ mountPath
1831
+ }]
1832
+ };
1833
+ instance = volume.instances.find((entry) => entry.serviceId === serviceId && entry.environmentId === environmentId) ?? volume.instances[0] ?? null;
1834
+ updated = true;
1835
+ }
1762
1836
  if (volume.name !== name || instance?.mountPath !== mountPath) {
1763
1837
  const updateResult = runRailway([...volumeArgs, "update", "--volume", volume.id, "--name", name, "--mount-path", mountPath, "--json"], cliOptions);
1764
1838
  const updatedVolume = normalizeRailwayCliVolume(parseRailwayJsonOutput(updateResult.stdout ?? ""), {
@@ -1774,6 +1848,18 @@ async function ensureRailwayServiceVolumeWithCliFallback({
1774
1848
  };
1775
1849
  updated = true;
1776
1850
  }
1851
+ const apiVolume = await waitForRailwayServiceVolumeMount({
1852
+ projectId,
1853
+ volumeId: volume.id,
1854
+ volumeName: name,
1855
+ serviceId,
1856
+ environmentId,
1857
+ mountPath,
1858
+ env
1859
+ });
1860
+ if (apiVolume) {
1861
+ volume = apiVolume;
1862
+ }
1777
1863
  return {
1778
1864
  volume,
1779
1865
  instance: volume.instances.find((entry) => entry.serviceId === serviceId && entry.environmentId === environmentId) ?? volume.instances[0] ?? null,
@@ -1781,6 +1867,33 @@ async function ensureRailwayServiceVolumeWithCliFallback({
1781
1867
  updated
1782
1868
  };
1783
1869
  }
1870
+ async function waitForRailwayServiceVolumeMount({
1871
+ projectId,
1872
+ volumeId,
1873
+ volumeName,
1874
+ serviceId,
1875
+ environmentId,
1876
+ mountPath,
1877
+ env
1878
+ }) {
1879
+ for (let attempt = 0; attempt <= 24; attempt += 1) {
1880
+ const volumes = await listRailwayVolumes({ projectId, env });
1881
+ const match = volumes.find(
1882
+ (entry) => entry.id === volumeId || entry.name === volumeName || entry.instances.some(
1883
+ (instance) => instance.serviceId === serviceId && instance.environmentId === environmentId && instance.mountPath === mountPath
1884
+ )
1885
+ ) ?? null;
1886
+ if (match?.instances.some(
1887
+ (instance) => instance.serviceId === serviceId && instance.environmentId === environmentId && instance.mountPath === mountPath
1888
+ )) {
1889
+ return match;
1890
+ }
1891
+ if (attempt < 24) {
1892
+ await sleep(5e3);
1893
+ }
1894
+ }
1895
+ return null;
1896
+ }
1784
1897
  async function deployRailwayService(tenantRoot, service, {
1785
1898
  dryRun = false,
1786
1899
  write,
@@ -1928,6 +2041,8 @@ export {
1928
2041
  ensureRailwayServiceVolumeWithCliFallback,
1929
2042
  isRailwayTransientFailure,
1930
2043
  isUsableRailwayToken,
2044
+ listRailwayServiceVolumesWithCli,
2045
+ parseRailwayJsonOutput,
1931
2046
  planRailwayServiceDeploy,
1932
2047
  planRailwayServiceLink,
1933
2048
  railwayServiceRuntimeStartCommand,
@@ -33,6 +33,7 @@ import {
33
33
  deriveRailwayMarketOperationsRunnerVolumeName,
34
34
  ensureRailwayProjectContext,
35
35
  ensureRailwayServiceVolumeWithCliFallback,
36
+ listRailwayServiceVolumesWithCli,
36
37
  runRailway,
37
38
  validateRailwayDeployPrerequisites
38
39
  } from "../operations/services/railway-deploy.js";
@@ -46,6 +47,7 @@ import {
46
47
  getRailwayServiceInstance,
47
48
  getRailwayProject,
48
49
  listRailwayCustomDomains,
50
+ listRailwayEnvironments,
49
51
  listRailwayProjects,
50
52
  listRailwayVolumes,
51
53
  listRailwayVariables,
@@ -1394,6 +1396,44 @@ function relativeRailwayRootDir(tenantRoot, serviceRoot) {
1394
1396
  const resolved = relative(tenantRoot, serviceRoot).replace(/\\/gu, "/");
1395
1397
  return !resolved || resolved === "" ? "." : resolved;
1396
1398
  }
1399
+ async function ensureRailwayEnvironmentForService({
1400
+ service,
1401
+ project,
1402
+ environmentName,
1403
+ env
1404
+ }) {
1405
+ try {
1406
+ return (await ensureRailwayEnvironment({
1407
+ projectId: project.id,
1408
+ environmentName,
1409
+ env
1410
+ })).environment;
1411
+ } catch (error) {
1412
+ const message = error instanceof Error ? error.message : String(error ?? "");
1413
+ if (!/Problem processing request/iu.test(message)) {
1414
+ throw error;
1415
+ }
1416
+ }
1417
+ ensureRailwayProjectContext({
1418
+ ...service,
1419
+ projectId: project.id,
1420
+ projectName: project.name ?? service.projectName,
1421
+ railwayEnvironment: environmentName
1422
+ }, {
1423
+ env,
1424
+ allowFailure: true,
1425
+ capture: true
1426
+ });
1427
+ for (let attempt = 0; attempt < 12; attempt += 1) {
1428
+ const environments = await listRailwayEnvironments({ projectId: project.id, env });
1429
+ const existing = environments.find((environment) => environment.name === environmentName || environment.id === environmentName) ?? null;
1430
+ if (existing) {
1431
+ return existing;
1432
+ }
1433
+ await new Promise((resolve2) => setTimeout(resolve2, 2500));
1434
+ }
1435
+ throw new Error(`Railway environment ${environmentName} was created through the CLI fallback but was not visible through the Railway API.`);
1436
+ }
1397
1437
  async function resolveRailwayTopologyForScope(input, scope, {
1398
1438
  ensure = false,
1399
1439
  refresh = false,
@@ -1464,11 +1504,12 @@ async function resolveRailwayTopologyForScope(input, scope, {
1464
1504
  }
1465
1505
  let environment = project?.environments.find((entry) => entry.name === service.railwayEnvironment || entry.id === service.railwayEnvironment) ?? null;
1466
1506
  if (project && !environment && ensure) {
1467
- environment = (await ensureRailwayEnvironment({
1468
- projectId: project.id,
1507
+ environment = await ensureRailwayEnvironmentForService({
1508
+ service,
1509
+ project,
1469
1510
  environmentName: service.railwayEnvironment,
1470
1511
  env
1471
- })).environment;
1512
+ });
1472
1513
  project = {
1473
1514
  ...project,
1474
1515
  environments: [...project.environments.filter((entry) => entry.id !== environment?.id), environment]
@@ -2216,16 +2257,33 @@ async function verifyRailwayUnit(input) {
2216
2257
  const volumes = entry.project?.id ? await listRailwayVolumes({ projectId: entry.project.id, env: topology.env }) : [];
2217
2258
  const expectedServiceId = entry.service?.id ?? null;
2218
2259
  const expectedEnvironmentId = entry.environment?.id ?? null;
2219
- const mountedVolume = volumes.find((volume) => volume.instances.some(
2260
+ let mountedVolume = volumes.find((volume) => volume.instances.some(
2220
2261
  (instance) => instance.serviceId === expectedServiceId && instance.environmentId === expectedEnvironmentId && instance.mountPath === service.volumeMountPath
2221
2262
  )) ?? null;
2263
+ let mountedVolumeSource = "api";
2264
+ if (!mountedVolume && serviceKey === "marketOperationsRunner" && expectedServiceId && expectedEnvironmentId) {
2265
+ ensureRailwayProjectContext(service, { env: topology.env, capture: true });
2266
+ const cliVolumes = listRailwayServiceVolumesWithCli({
2267
+ cwd: service.rootDir,
2268
+ serviceId: expectedServiceId,
2269
+ environmentId: expectedEnvironmentId,
2270
+ name: deriveRailwayMarketOperationsRunnerVolumeName(entry.service?.name ?? service.serviceName ?? service.key, entry.environment?.name ?? service.railwayEnvironment),
2271
+ mountPath: service.volumeMountPath,
2272
+ env: topology.env
2273
+ });
2274
+ mountedVolume = cliVolumes.find((volume) => volume.instances.some(
2275
+ (instance) => instance.serviceId === expectedServiceId && instance.environmentId === expectedEnvironmentId && instance.mountPath === service.volumeMountPath
2276
+ )) ?? null;
2277
+ mountedVolumeSource = mountedVolume ? "cli" : "api";
2278
+ }
2222
2279
  checks.push(verificationCheck("railway.volume:data", "Railway service has persistent data volume mounted", "api", {
2223
2280
  exists: Boolean(mountedVolume),
2224
2281
  configured: Boolean(mountedVolume),
2225
2282
  expected: service.volumeMountPath,
2226
2283
  observed: mountedVolume ? {
2227
2284
  name: mountedVolume.name,
2228
- mountPath: service.volumeMountPath
2285
+ mountPath: service.volumeMountPath,
2286
+ source: mountedVolumeSource
2229
2287
  } : null,
2230
2288
  issues: mountedVolume ? [] : [`Railway service ${service.serviceName ?? service.key} is missing a persistent volume mounted at ${service.volumeMountPath}.`]
2231
2289
  }));
@@ -2247,7 +2305,13 @@ async function verifyRailwayUnit(input) {
2247
2305
  issues: Object.hasOwn(entry.currentVariables, key) ? [] : [`Railway secret ${key} is missing.`]
2248
2306
  }));
2249
2307
  }
2250
- return summarizeVerification(input.unit.unitId, checks);
2308
+ const verification = summarizeVerification(input.unit.unitId, checks);
2309
+ if (!verification.verified && attempt < 12 && railwayVerificationMaySettle(verification)) {
2310
+ attempt += 1;
2311
+ sleepMs(5e3);
2312
+ continue;
2313
+ }
2314
+ return verification;
2251
2315
  } catch (error) {
2252
2316
  if (attempt >= 2 || !isTransientRailwayReconcileError(error)) {
2253
2317
  throw error;
@@ -2257,6 +2321,11 @@ async function verifyRailwayUnit(input) {
2257
2321
  }
2258
2322
  }
2259
2323
  }
2324
+ function railwayVerificationMaySettle(verification) {
2325
+ return verification.checks.some(
2326
+ (check) => !check.verified && (check.key === "railway.instance" || check.key.startsWith("railway.instance.") || check.key === "railway.volume:data")
2327
+ );
2328
+ }
2260
2329
  function railwayStartCommandMatches(serviceKey, observed, expected) {
2261
2330
  if (observed === expected) {
2262
2331
  return true;
@@ -69,6 +69,7 @@ import {
69
69
  syncBranchWithOrigin
70
70
  } from "../operations/services/git-workflow.js";
71
71
  import { resolveGitHubRepositorySlug } from "../operations/services/github-automation.js";
72
+ import { dispatchGitHubWorkflowRun } from "../operations/services/github-api.js";
72
73
  import {
73
74
  formatGitHubActionsGateFailure,
74
75
  inspectGitHubActionsVerification,
@@ -1168,6 +1169,9 @@ function workflowSessionSnapshot(session) {
1168
1169
  }))
1169
1170
  };
1170
1171
  }
1172
+ function sleep(ms) {
1173
+ return new Promise((resolve2) => setTimeout(resolve2, ms));
1174
+ }
1171
1175
  function nextPendingJournalStep(journal) {
1172
1176
  return journal.steps.find((step) => step.status === "pending") ?? null;
1173
1177
  }
@@ -3127,9 +3131,39 @@ async function workflowSave(helpers, input) {
3127
3131
  lockfileValidation: repo.lockfileValidation
3128
3132
  }))
3129
3133
  };
3130
- const saveWorkflowGates = shouldUseHostedSaveCi(effectiveInput, branch) ? await executeJournalStep(root, workflowRun.runId, "hosted-ci", () => {
3134
+ const saveWorkflowGates = shouldUseHostedSaveCi(effectiveInput, branch) ? await executeJournalStep(root, workflowRun.runId, "hosted-ci", async () => {
3131
3135
  if (branch === STAGING_BRANCH) {
3132
- return { workflowGates: saveResult?.workflowGates ?? [] };
3136
+ const workflowGates = saveResult?.workflowGates ?? [];
3137
+ if (workflowGates.length > 0 || effectiveInput.verifyDeployedResources !== true || scope === "local" || !savedRootRepo.commitSha) {
3138
+ return { workflowGates };
3139
+ }
3140
+ helpers.write("[save][workflow] Dispatching hosted market deploy gate for deployed resource verification.");
3141
+ const repository = resolveGitHubRepositorySlug(savedRootRepo.path);
3142
+ await dispatchGitHubWorkflowRun(repository, {
3143
+ workflow: "deploy.yml",
3144
+ branch,
3145
+ inputs: {
3146
+ environment: "staging",
3147
+ action_kind: "deploy_web"
3148
+ }
3149
+ });
3150
+ await sleep(5e3);
3151
+ helpers.write("[save][workflow] Waiting for hosted market deploy gate.");
3152
+ const dispatchedGates = await waitForWorkflowGates("save", [
3153
+ hostedDeployGate({
3154
+ name: savedRootRepo.name,
3155
+ repoPath: savedRootRepo.path,
3156
+ repository,
3157
+ workflow: "deploy.yml",
3158
+ branch,
3159
+ headSha: savedRootRepo.commitSha
3160
+ })
3161
+ ], "hosted", {
3162
+ root,
3163
+ runId: workflowRun.runId,
3164
+ onProgress: (line, stream) => helpers.write(line, stream)
3165
+ });
3166
+ return { workflowGates: dispatchedGates };
3133
3167
  }
3134
3168
  helpers.write("[save][workflow] Waiting for hosted save workflow gates.");
3135
3169
  return waitForWorkflowGates("save", [
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.10.18",
3
+ "version": "0.10.20",
4
4
  "description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {