@treeseed/sdk 0.6.42 → 0.6.44

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.
@@ -137,6 +137,126 @@ export declare function deployProjectPlatform(options: ProjectPlatformActionOpti
137
137
  skipped: boolean;
138
138
  reason: string;
139
139
  };
140
+ railwayResources: {
141
+ ok: boolean;
142
+ checks: ({
143
+ type: string;
144
+ service: string;
145
+ serviceName: string;
146
+ projectName: string;
147
+ environment: string;
148
+ ok: boolean;
149
+ status: string;
150
+ message: string;
151
+ serviceId?: undefined;
152
+ projectId?: undefined;
153
+ environmentId?: undefined;
154
+ instanceId?: undefined;
155
+ observed?: undefined;
156
+ volumeName?: undefined;
157
+ mountPath?: undefined;
158
+ } | {
159
+ type: string;
160
+ service: string;
161
+ serviceName: string;
162
+ serviceId: string;
163
+ projectId: string;
164
+ environment: string;
165
+ environmentId: string;
166
+ instanceId: string | null;
167
+ ok: boolean;
168
+ status: string;
169
+ observed: {
170
+ rootDirectory: string | null;
171
+ startCommand: string | null;
172
+ cronSchedule: string | null;
173
+ sleepApplication: boolean | null;
174
+ runtimeMode: string | null;
175
+ id?: undefined;
176
+ name?: undefined;
177
+ instances?: undefined;
178
+ } | null;
179
+ message: string | undefined;
180
+ projectName?: undefined;
181
+ volumeName?: undefined;
182
+ mountPath?: undefined;
183
+ } | {
184
+ type: string;
185
+ service: string;
186
+ serviceName: string;
187
+ serviceId: string;
188
+ projectId: string;
189
+ environment: string;
190
+ environmentId: string;
191
+ volumeName: string;
192
+ mountPath: string;
193
+ ok: boolean;
194
+ status: string;
195
+ observed: {
196
+ id: string;
197
+ name: string;
198
+ instances: import("./railway-api.ts").RailwayVolumeInstanceSummary[];
199
+ rootDirectory?: undefined;
200
+ startCommand?: undefined;
201
+ cronSchedule?: undefined;
202
+ sleepApplication?: undefined;
203
+ runtimeMode?: undefined;
204
+ } | null;
205
+ message: string | undefined;
206
+ projectName?: undefined;
207
+ instanceId?: undefined;
208
+ } | {
209
+ id: null;
210
+ ok: boolean;
211
+ status: string;
212
+ message: string;
213
+ service: string;
214
+ projectId: string | null;
215
+ projectName: string;
216
+ serviceId: string | null;
217
+ serviceName: string;
218
+ environment: string;
219
+ environmentId: string | null;
220
+ expression: string;
221
+ command: string | null;
222
+ enabled: boolean;
223
+ logicalName: string;
224
+ type: string;
225
+ instanceId?: undefined;
226
+ observed?: undefined;
227
+ volumeName?: undefined;
228
+ mountPath?: undefined;
229
+ } | {
230
+ id: string | null;
231
+ projectId: string;
232
+ serviceId: string;
233
+ environmentId: string;
234
+ ok: boolean;
235
+ status: string;
236
+ observed: {
237
+ expression: string | null;
238
+ command: string | null;
239
+ enabled: boolean;
240
+ } | null;
241
+ message: string | undefined;
242
+ service: string;
243
+ projectName: string;
244
+ serviceName: string;
245
+ environment: string;
246
+ expression: string;
247
+ command: string | null;
248
+ enabled: boolean;
249
+ logicalName: string;
250
+ type: string;
251
+ instanceId?: undefined;
252
+ volumeName?: undefined;
253
+ mountPath?: undefined;
254
+ })[];
255
+ } | {
256
+ ok: boolean;
257
+ skipped: boolean;
258
+ reason: string;
259
+ };
140
260
  pages: {
141
261
  ok: boolean;
142
262
  status: number;
@@ -315,6 +435,126 @@ export declare function monitorProjectPlatform(options: ProjectPlatformActionOpt
315
435
  skipped: boolean;
316
436
  reason: string;
317
437
  };
438
+ railwayResources: {
439
+ ok: boolean;
440
+ checks: ({
441
+ type: string;
442
+ service: string;
443
+ serviceName: string;
444
+ projectName: string;
445
+ environment: string;
446
+ ok: boolean;
447
+ status: string;
448
+ message: string;
449
+ serviceId?: undefined;
450
+ projectId?: undefined;
451
+ environmentId?: undefined;
452
+ instanceId?: undefined;
453
+ observed?: undefined;
454
+ volumeName?: undefined;
455
+ mountPath?: undefined;
456
+ } | {
457
+ type: string;
458
+ service: string;
459
+ serviceName: string;
460
+ serviceId: string;
461
+ projectId: string;
462
+ environment: string;
463
+ environmentId: string;
464
+ instanceId: string | null;
465
+ ok: boolean;
466
+ status: string;
467
+ observed: {
468
+ rootDirectory: string | null;
469
+ startCommand: string | null;
470
+ cronSchedule: string | null;
471
+ sleepApplication: boolean | null;
472
+ runtimeMode: string | null;
473
+ id?: undefined;
474
+ name?: undefined;
475
+ instances?: undefined;
476
+ } | null;
477
+ message: string | undefined;
478
+ projectName?: undefined;
479
+ volumeName?: undefined;
480
+ mountPath?: undefined;
481
+ } | {
482
+ type: string;
483
+ service: string;
484
+ serviceName: string;
485
+ serviceId: string;
486
+ projectId: string;
487
+ environment: string;
488
+ environmentId: string;
489
+ volumeName: string;
490
+ mountPath: string;
491
+ ok: boolean;
492
+ status: string;
493
+ observed: {
494
+ id: string;
495
+ name: string;
496
+ instances: import("./railway-api.ts").RailwayVolumeInstanceSummary[];
497
+ rootDirectory?: undefined;
498
+ startCommand?: undefined;
499
+ cronSchedule?: undefined;
500
+ sleepApplication?: undefined;
501
+ runtimeMode?: undefined;
502
+ } | null;
503
+ message: string | undefined;
504
+ projectName?: undefined;
505
+ instanceId?: undefined;
506
+ } | {
507
+ id: null;
508
+ ok: boolean;
509
+ status: string;
510
+ message: string;
511
+ service: string;
512
+ projectId: string | null;
513
+ projectName: string;
514
+ serviceId: string | null;
515
+ serviceName: string;
516
+ environment: string;
517
+ environmentId: string | null;
518
+ expression: string;
519
+ command: string | null;
520
+ enabled: boolean;
521
+ logicalName: string;
522
+ type: string;
523
+ instanceId?: undefined;
524
+ observed?: undefined;
525
+ volumeName?: undefined;
526
+ mountPath?: undefined;
527
+ } | {
528
+ id: string | null;
529
+ projectId: string;
530
+ serviceId: string;
531
+ environmentId: string;
532
+ ok: boolean;
533
+ status: string;
534
+ observed: {
535
+ expression: string | null;
536
+ command: string | null;
537
+ enabled: boolean;
538
+ } | null;
539
+ message: string | undefined;
540
+ service: string;
541
+ projectName: string;
542
+ serviceName: string;
543
+ environment: string;
544
+ expression: string;
545
+ command: string | null;
546
+ enabled: boolean;
547
+ logicalName: string;
548
+ type: string;
549
+ instanceId?: undefined;
550
+ volumeName?: undefined;
551
+ mountPath?: undefined;
552
+ })[];
553
+ } | {
554
+ ok: boolean;
555
+ skipped: boolean;
556
+ reason: string;
557
+ };
318
558
  pages: {
319
559
  ok: boolean;
320
560
  status: number;
@@ -498,6 +738,126 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
498
738
  skipped: boolean;
499
739
  reason: string;
500
740
  };
741
+ railwayResources: {
742
+ ok: boolean;
743
+ checks: ({
744
+ type: string;
745
+ service: string;
746
+ serviceName: string;
747
+ projectName: string;
748
+ environment: string;
749
+ ok: boolean;
750
+ status: string;
751
+ message: string;
752
+ serviceId?: undefined;
753
+ projectId?: undefined;
754
+ environmentId?: undefined;
755
+ instanceId?: undefined;
756
+ observed?: undefined;
757
+ volumeName?: undefined;
758
+ mountPath?: undefined;
759
+ } | {
760
+ type: string;
761
+ service: string;
762
+ serviceName: string;
763
+ serviceId: string;
764
+ projectId: string;
765
+ environment: string;
766
+ environmentId: string;
767
+ instanceId: string | null;
768
+ ok: boolean;
769
+ status: string;
770
+ observed: {
771
+ rootDirectory: string | null;
772
+ startCommand: string | null;
773
+ cronSchedule: string | null;
774
+ sleepApplication: boolean | null;
775
+ runtimeMode: string | null;
776
+ id?: undefined;
777
+ name?: undefined;
778
+ instances?: undefined;
779
+ } | null;
780
+ message: string | undefined;
781
+ projectName?: undefined;
782
+ volumeName?: undefined;
783
+ mountPath?: undefined;
784
+ } | {
785
+ type: string;
786
+ service: string;
787
+ serviceName: string;
788
+ serviceId: string;
789
+ projectId: string;
790
+ environment: string;
791
+ environmentId: string;
792
+ volumeName: string;
793
+ mountPath: string;
794
+ ok: boolean;
795
+ status: string;
796
+ observed: {
797
+ id: string;
798
+ name: string;
799
+ instances: import("./railway-api.ts").RailwayVolumeInstanceSummary[];
800
+ rootDirectory?: undefined;
801
+ startCommand?: undefined;
802
+ cronSchedule?: undefined;
803
+ sleepApplication?: undefined;
804
+ runtimeMode?: undefined;
805
+ } | null;
806
+ message: string | undefined;
807
+ projectName?: undefined;
808
+ instanceId?: undefined;
809
+ } | {
810
+ id: null;
811
+ ok: boolean;
812
+ status: string;
813
+ message: string;
814
+ service: string;
815
+ projectId: string | null;
816
+ projectName: string;
817
+ serviceId: string | null;
818
+ serviceName: string;
819
+ environment: string;
820
+ environmentId: string | null;
821
+ expression: string;
822
+ command: string | null;
823
+ enabled: boolean;
824
+ logicalName: string;
825
+ type: string;
826
+ instanceId?: undefined;
827
+ observed?: undefined;
828
+ volumeName?: undefined;
829
+ mountPath?: undefined;
830
+ } | {
831
+ id: string | null;
832
+ projectId: string;
833
+ serviceId: string;
834
+ environmentId: string;
835
+ ok: boolean;
836
+ status: string;
837
+ observed: {
838
+ expression: string | null;
839
+ command: string | null;
840
+ enabled: boolean;
841
+ } | null;
842
+ message: string | undefined;
843
+ service: string;
844
+ projectName: string;
845
+ serviceName: string;
846
+ environment: string;
847
+ expression: string;
848
+ command: string | null;
849
+ enabled: boolean;
850
+ logicalName: string;
851
+ type: string;
852
+ instanceId?: undefined;
853
+ volumeName?: undefined;
854
+ mountPath?: undefined;
855
+ })[];
856
+ } | {
857
+ ok: boolean;
858
+ skipped: boolean;
859
+ reason: string;
860
+ };
501
861
  pages: {
502
862
  ok: boolean;
503
863
  status: number;
@@ -637,6 +997,126 @@ export declare function runProjectPlatformAction(action: ProjectPlatformAction,
637
997
  skipped: boolean;
638
998
  reason: string;
639
999
  };
1000
+ railwayResources: {
1001
+ ok: boolean;
1002
+ checks: ({
1003
+ type: string;
1004
+ service: string;
1005
+ serviceName: string;
1006
+ projectName: string;
1007
+ environment: string;
1008
+ ok: boolean;
1009
+ status: string;
1010
+ message: string;
1011
+ serviceId?: undefined;
1012
+ projectId?: undefined;
1013
+ environmentId?: undefined;
1014
+ instanceId?: undefined;
1015
+ observed?: undefined;
1016
+ volumeName?: undefined;
1017
+ mountPath?: undefined;
1018
+ } | {
1019
+ type: string;
1020
+ service: string;
1021
+ serviceName: string;
1022
+ serviceId: string;
1023
+ projectId: string;
1024
+ environment: string;
1025
+ environmentId: string;
1026
+ instanceId: string | null;
1027
+ ok: boolean;
1028
+ status: string;
1029
+ observed: {
1030
+ rootDirectory: string | null;
1031
+ startCommand: string | null;
1032
+ cronSchedule: string | null;
1033
+ sleepApplication: boolean | null;
1034
+ runtimeMode: string | null;
1035
+ id?: undefined;
1036
+ name?: undefined;
1037
+ instances?: undefined;
1038
+ } | null;
1039
+ message: string | undefined;
1040
+ projectName?: undefined;
1041
+ volumeName?: undefined;
1042
+ mountPath?: undefined;
1043
+ } | {
1044
+ type: string;
1045
+ service: string;
1046
+ serviceName: string;
1047
+ serviceId: string;
1048
+ projectId: string;
1049
+ environment: string;
1050
+ environmentId: string;
1051
+ volumeName: string;
1052
+ mountPath: string;
1053
+ ok: boolean;
1054
+ status: string;
1055
+ observed: {
1056
+ id: string;
1057
+ name: string;
1058
+ instances: import("./railway-api.ts").RailwayVolumeInstanceSummary[];
1059
+ rootDirectory?: undefined;
1060
+ startCommand?: undefined;
1061
+ cronSchedule?: undefined;
1062
+ sleepApplication?: undefined;
1063
+ runtimeMode?: undefined;
1064
+ } | null;
1065
+ message: string | undefined;
1066
+ projectName?: undefined;
1067
+ instanceId?: undefined;
1068
+ } | {
1069
+ id: null;
1070
+ ok: boolean;
1071
+ status: string;
1072
+ message: string;
1073
+ service: string;
1074
+ projectId: string | null;
1075
+ projectName: string;
1076
+ serviceId: string | null;
1077
+ serviceName: string;
1078
+ environment: string;
1079
+ environmentId: string | null;
1080
+ expression: string;
1081
+ command: string | null;
1082
+ enabled: boolean;
1083
+ logicalName: string;
1084
+ type: string;
1085
+ instanceId?: undefined;
1086
+ observed?: undefined;
1087
+ volumeName?: undefined;
1088
+ mountPath?: undefined;
1089
+ } | {
1090
+ id: string | null;
1091
+ projectId: string;
1092
+ serviceId: string;
1093
+ environmentId: string;
1094
+ ok: boolean;
1095
+ status: string;
1096
+ observed: {
1097
+ expression: string | null;
1098
+ command: string | null;
1099
+ enabled: boolean;
1100
+ } | null;
1101
+ message: string | undefined;
1102
+ service: string;
1103
+ projectName: string;
1104
+ serviceName: string;
1105
+ environment: string;
1106
+ expression: string;
1107
+ command: string | null;
1108
+ enabled: boolean;
1109
+ logicalName: string;
1110
+ type: string;
1111
+ instanceId?: undefined;
1112
+ volumeName?: undefined;
1113
+ mountPath?: undefined;
1114
+ })[];
1115
+ } | {
1116
+ ok: boolean;
1117
+ skipped: boolean;
1118
+ reason: string;
1119
+ };
640
1120
  pages: {
641
1121
  ok: boolean;
642
1122
  status: number;
@@ -35,6 +35,7 @@ import {
35
35
  ensureRailwayScheduledJobs,
36
36
  validateRailwayDeployPrerequisites,
37
37
  validateRailwayServiceConfiguration,
38
+ verifyRailwayManagedResources,
38
39
  verifyRailwayScheduledJobs
39
40
  } from "./railway-deploy.js";
40
41
  import { loadCliDeployConfig, packageScriptPath } from "./runtime-tools.js";
@@ -1209,6 +1210,7 @@ async function publishProjectContent(options) {
1209
1210
  }
1210
1211
  async function monitorProjectPlatform(options) {
1211
1212
  const reporter = resolveReporter(options.tenantRoot, options.reporter);
1213
+ const env = { ...process.env, ...options.env ?? {} };
1212
1214
  const target = createPersistentDeployTarget(options.scope === "local" ? "staging" : options.scope);
1213
1215
  const siteConfig = loadCliDeployConfig(options.tenantRoot);
1214
1216
  const selectedSystems = new Set(resolveProjectPlatformBootstrapSystems(options, siteConfig));
@@ -1228,12 +1230,14 @@ async function monitorProjectPlatform(options) {
1228
1230
  r2: options.dryRun ? { ok: true, skipped: true, reason: "dry_run" } : probeR2(options.tenantRoot, siteConfig, state, target),
1229
1231
  queue: options.dryRun ? Promise.resolve({ ok: true, skipped: true, reason: "dry_run" }) : probeQueue(siteConfig, state),
1230
1232
  scaleProbe: probeScaleConfiguration(siteConfig, state),
1233
+ railwayResources: options.scope === "local" || !apiSelected && !agentsSelected ? Promise.resolve({ ok: true, skipped: true, reason: options.scope === "local" ? "local_scope" : "railway_not_selected" }) : verifyRailwayManagedResources(options.tenantRoot, options.scope, { env }),
1231
1234
  readiness: state.readiness
1232
1235
  };
1233
1236
  const resolvedChecks = {
1234
1237
  ...checks,
1235
1238
  r2: await checks.r2,
1236
- queue: await checks.queue
1239
+ queue: await checks.queue,
1240
+ railwayResources: await checks.railwayResources
1237
1241
  };
1238
1242
  const ok = [
1239
1243
  resolvedChecks.pages,
@@ -1243,7 +1247,8 @@ async function monitorProjectPlatform(options) {
1243
1247
  resolvedChecks.agentHealth,
1244
1248
  resolvedChecks.r2,
1245
1249
  resolvedChecks.queue,
1246
- resolvedChecks.scaleProbe
1250
+ resolvedChecks.scaleProbe,
1251
+ resolvedChecks.railwayResources
1247
1252
  ].every((check) => check?.ok === true || check?.skipped === true);
1248
1253
  if (!ok) {
1249
1254
  const failedChecks = Object.entries(resolvedChecks).filter(([, check]) => check && typeof check === "object" && check.ok !== true && check.skipped !== true).map(([name, check]) => `${name}: ${JSON.stringify(check)}`);
@@ -281,6 +281,125 @@ export declare function verifyRailwayScheduledJobs(tenantRoot: any, scope: any,
281
281
  unsupported?: undefined;
282
282
  message?: undefined;
283
283
  }>;
284
+ export declare function verifyRailwayManagedResources(tenantRoot: any, scope: any, { fetchImpl, apiToken, apiUrl, env }?: {
285
+ fetchImpl?: typeof fetch | undefined;
286
+ env?: NodeJS.ProcessEnv | undefined;
287
+ }): Promise<{
288
+ ok: boolean;
289
+ checks: ({
290
+ type: string;
291
+ service: string;
292
+ serviceName: string;
293
+ projectName: string;
294
+ environment: string;
295
+ ok: boolean;
296
+ status: string;
297
+ message: string;
298
+ serviceId?: undefined;
299
+ projectId?: undefined;
300
+ environmentId?: undefined;
301
+ instanceId?: undefined;
302
+ observed?: undefined;
303
+ volumeName?: undefined;
304
+ mountPath?: undefined;
305
+ } | {
306
+ type: string;
307
+ service: string;
308
+ serviceName: string;
309
+ serviceId: string;
310
+ projectId: string;
311
+ environment: string;
312
+ environmentId: string;
313
+ instanceId: string | null;
314
+ ok: boolean;
315
+ status: string;
316
+ observed: {
317
+ rootDirectory: string | null;
318
+ startCommand: string | null;
319
+ cronSchedule: string | null;
320
+ sleepApplication: boolean | null;
321
+ runtimeMode: string | null;
322
+ id?: undefined;
323
+ name?: undefined;
324
+ instances?: undefined;
325
+ } | null;
326
+ message: string | undefined;
327
+ projectName?: undefined;
328
+ volumeName?: undefined;
329
+ mountPath?: undefined;
330
+ } | {
331
+ type: string;
332
+ service: string;
333
+ serviceName: string;
334
+ serviceId: string;
335
+ projectId: string;
336
+ environment: string;
337
+ environmentId: string;
338
+ volumeName: string;
339
+ mountPath: string;
340
+ ok: boolean;
341
+ status: string;
342
+ observed: {
343
+ id: string;
344
+ name: string;
345
+ instances: import("./railway-api.ts").RailwayVolumeInstanceSummary[];
346
+ rootDirectory?: undefined;
347
+ startCommand?: undefined;
348
+ cronSchedule?: undefined;
349
+ sleepApplication?: undefined;
350
+ runtimeMode?: undefined;
351
+ } | null;
352
+ message: string | undefined;
353
+ projectName?: undefined;
354
+ instanceId?: undefined;
355
+ } | {
356
+ id: null;
357
+ ok: boolean;
358
+ status: string;
359
+ message: string;
360
+ service: string;
361
+ projectId: string | null;
362
+ projectName: string;
363
+ serviceId: string | null;
364
+ serviceName: string;
365
+ environment: string;
366
+ environmentId: string | null;
367
+ expression: string;
368
+ command: string | null;
369
+ enabled: boolean;
370
+ logicalName: string;
371
+ type: string;
372
+ instanceId?: undefined;
373
+ observed?: undefined;
374
+ volumeName?: undefined;
375
+ mountPath?: undefined;
376
+ } | {
377
+ id: string | null;
378
+ projectId: string;
379
+ serviceId: string;
380
+ environmentId: string;
381
+ ok: boolean;
382
+ status: string;
383
+ observed: {
384
+ expression: string | null;
385
+ command: string | null;
386
+ enabled: boolean;
387
+ } | null;
388
+ message: string | undefined;
389
+ service: string;
390
+ projectName: string;
391
+ serviceName: string;
392
+ environment: string;
393
+ expression: string;
394
+ command: string | null;
395
+ enabled: boolean;
396
+ logicalName: string;
397
+ type: string;
398
+ instanceId?: undefined;
399
+ volumeName?: undefined;
400
+ mountPath?: undefined;
401
+ })[];
402
+ }>;
284
403
  export declare function planRailwayServiceDeploy(service: any, { env }?: {
285
404
  env?: NodeJS.ProcessEnv | undefined;
286
405
  }): {
@@ -15,6 +15,7 @@ import {
15
15
  listRailwayEnvironments,
16
16
  listRailwayProjects,
17
17
  listRailwayServices,
18
+ listRailwayVolumes,
18
19
  normalizeRailwayEnvironmentName,
19
20
  resolveRailwayApiToken,
20
21
  resolveRailwayApiUrl,
@@ -841,6 +842,112 @@ async function verifyRailwayScheduledJobs(tenantRoot, scope, { fetchImpl = fetch
841
842
  checks
842
843
  };
843
844
  }
845
+ async function verifyRailwayManagedResources(tenantRoot, scope, { fetchImpl = fetch, apiToken, apiUrl, env = process.env } = {}) {
846
+ const effectiveApiToken = apiToken || resolveRailwayAuthToken(env);
847
+ const effectiveApiUrl = apiUrl || resolveRailwayApiUrl(env);
848
+ const effectiveEnv = { ...env, RAILWAY_API_TOKEN: effectiveApiToken, TREESEED_RAILWAY_API_URL: effectiveApiUrl };
849
+ const services = configuredRailwayServices(tenantRoot, scope);
850
+ const checks = [];
851
+ for (const service of services) {
852
+ const target = await resolveRailwayScheduleTarget({
853
+ projectId: service.projectId,
854
+ projectName: service.projectName,
855
+ serviceId: service.serviceId,
856
+ serviceName: service.serviceName,
857
+ environment: normalizeRailwayEnvironmentName(service.railwayEnvironment),
858
+ environmentId: envValue("TREESEED_RAILWAY_ENVIRONMENT_ID") || null
859
+ }, {
860
+ env: effectiveEnv,
861
+ fetchImpl,
862
+ ensure: false
863
+ });
864
+ if (!target.project || !target.environment || !target.service) {
865
+ checks.push({
866
+ type: "service",
867
+ service: service.key,
868
+ serviceName: service.serviceName,
869
+ projectName: service.projectName,
870
+ environment: service.railwayEnvironment,
871
+ ok: false,
872
+ status: "missing",
873
+ message: `Railway service ${service.serviceName} is missing in ${service.railwayEnvironment}.`
874
+ });
875
+ continue;
876
+ }
877
+ const instance = await getRailwayServiceInstance({
878
+ serviceId: target.service.id,
879
+ environmentId: target.environment.id,
880
+ env: effectiveEnv,
881
+ fetchImpl
882
+ });
883
+ checks.push({
884
+ type: "service-instance",
885
+ service: service.key,
886
+ serviceName: target.service.name,
887
+ serviceId: target.service.id,
888
+ projectId: target.project.id,
889
+ environment: target.environment.name,
890
+ environmentId: target.environment.id,
891
+ instanceId: instance.id,
892
+ ok: Boolean(instance.id),
893
+ status: instance.id ? "checked" : "missing",
894
+ observed: instance.id ? {
895
+ rootDirectory: instance.rootDirectory,
896
+ startCommand: instance.startCommand,
897
+ cronSchedule: instance.cronSchedule,
898
+ sleepApplication: instance.sleepApplication,
899
+ runtimeMode: instance.runtimeMode
900
+ } : null,
901
+ message: instance.id ? void 0 : `Railway service instance for ${target.service.name} is missing in ${target.environment.name}.`
902
+ });
903
+ if (service.key === "workerRunner") {
904
+ const expectedVolumeName = deriveRailwayWorkerRunnerVolumeName(target.service.name, target.environment.name);
905
+ const volumes = await listRailwayVolumes({
906
+ projectId: target.project.id,
907
+ env: effectiveEnv,
908
+ fetchImpl
909
+ });
910
+ const volume = volumes.find(
911
+ (candidate) => candidate.name === expectedVolumeName && candidate.instances.some((entry) => entry.serviceId === target.service.id && entry.environmentId === target.environment.id && entry.mountPath === WORKER_RUNNER_VOLUME_MOUNT_PATH)
912
+ ) ?? null;
913
+ checks.push({
914
+ type: "worker-runner-volume",
915
+ service: service.key,
916
+ serviceName: target.service.name,
917
+ serviceId: target.service.id,
918
+ projectId: target.project.id,
919
+ environment: target.environment.name,
920
+ environmentId: target.environment.id,
921
+ volumeName: expectedVolumeName,
922
+ mountPath: WORKER_RUNNER_VOLUME_MOUNT_PATH,
923
+ ok: Boolean(volume),
924
+ status: volume ? "checked" : "missing",
925
+ observed: volume ? {
926
+ id: volume.id,
927
+ name: volume.name,
928
+ instances: volume.instances
929
+ } : null,
930
+ message: volume ? void 0 : `Railway worker-runner volume ${expectedVolumeName} is missing or is not mounted at ${WORKER_RUNNER_VOLUME_MOUNT_PATH}.`
931
+ });
932
+ }
933
+ }
934
+ const schedules = await verifyRailwayScheduledJobs(tenantRoot, scope, {
935
+ fetchImpl,
936
+ apiToken: effectiveApiToken,
937
+ apiUrl: effectiveApiUrl,
938
+ env: effectiveEnv
939
+ });
940
+ for (const check of schedules.checks ?? []) {
941
+ checks.push({
942
+ type: "schedule",
943
+ ...check
944
+ });
945
+ }
946
+ return {
947
+ ok: checks.every((entry) => entry.ok === true || entry.skipped === true),
948
+ checks
949
+ };
950
+ }
844
951
  function shouldAttachRailwayDeployLogs(env = process.env) {
845
952
  return configuredEnvValue(env, "TREESEED_RAILWAY_DEPLOY_ATTACH_LOGS") === "1";
846
953
  }
@@ -942,6 +1049,15 @@ async function syncRailwayServiceRuntimeConfigurationAfterDeploy(tenantRoot, ser
942
1049
  runtimeMode: service.runtimeMode,
943
1050
  env
944
1051
  }) : null;
1052
+ await upsertRailwayVariables({
1053
+ projectId: project.id,
1054
+ environmentId: environment.id,
1055
+ serviceId: railwayService.id,
1056
+ variables: {
1057
+ TREESEED_SKIP_PACKAGE_PREPARE: "1"
1058
+ },
1059
+ env
1060
+ });
945
1061
  const volumeMountPath = service.runnerPool?.volumeMountPath ?? WORKER_RUNNER_VOLUME_MOUNT_PATH;
946
1062
  const volumeConfiguration = wantsRunnerVolume ? await ensureRailwayServiceVolumeWithCliFallback({
947
1063
  tenantRoot,
@@ -1159,5 +1275,6 @@ export {
1159
1275
  setRailwaySecretVariable,
1160
1276
  validateRailwayDeployPrerequisites,
1161
1277
  validateRailwayServiceConfiguration,
1278
+ verifyRailwayManagedResources,
1162
1279
  verifyRailwayScheduledJobs
1163
1280
  };
@@ -319,7 +319,7 @@ function normalizeSaveVerifyMode(mode) {
319
319
  }
320
320
  }
321
321
  function shouldUseHostedSaveCi(input) {
322
- return normalizeCiMode(input.ciMode, "save") === "hosted" || input.verifyMode === "hosted" || input.verifyMode === "both";
322
+ return normalizeCiMode(input.ciMode, "save") === "hosted" || input.verifyMode === "hosted" || input.verifyMode === "both" || input.verifyDeployedResources === true;
323
323
  }
324
324
  function worktreePayload(root, requestedMode) {
325
325
  const metadata = managedWorkflowWorktreeMetadata(root);
@@ -2875,7 +2875,8 @@ async function workflowSave(helpers, input) {
2875
2875
  ciMode: effectiveInput.ciMode ?? "auto",
2876
2876
  worktreeMode: effectiveInput.worktreeMode ?? "auto",
2877
2877
  commitMessageMode: effectiveInput.commitMessageMode ?? "auto",
2878
- workspaceLinks: effectiveInput.workspaceLinks ?? "auto"
2878
+ workspaceLinks: effectiveInput.workspaceLinks ?? "auto",
2879
+ verifyDeployedResources: effectiveInput.verifyDeployedResources === true
2879
2880
  },
2880
2881
  [
2881
2882
  {
@@ -2971,6 +2972,13 @@ async function workflowSave(helpers, input) {
2971
2972
  branch,
2972
2973
  headSha: savedRootRepo.commitSha
2973
2974
  }] : [],
2975
+ ...effectiveInput.verifyDeployedResources === true && scope !== "local" && savedRootRepo.pushed && savedRootRepo.commitSha && branch ? [{
2976
+ name: savedRootRepo.name,
2977
+ repoPath: savedRootRepo.path,
2978
+ workflow: "deploy.yml",
2979
+ branch,
2980
+ headSha: savedRootRepo.commitSha
2981
+ }] : [],
2974
2982
  ...savedPackageReports.filter((repo) => repo.pushed && repo.commitSha && repo.branch).map((repo) => ({
2975
2983
  name: repo.name,
2976
2984
  repoPath: repo.path,
@@ -3289,6 +3297,7 @@ async function workflowStage(helpers, input) {
3289
3297
  const effectiveInput = autoResumeRun ? autoResumeRun.input : input;
3290
3298
  const message = ensureMessage("stage", effectiveInput.message, "a resolution message");
3291
3299
  const ciMode = normalizeCiMode(effectiveInput.ciMode, "stage");
3300
+ const waitForStaging = effectiveInput.verifyDeployedResources === true || effectiveInput.waitForStaging !== false;
3292
3301
  if (executionMode === "plan") {
3293
3302
  const blockers = [];
3294
3303
  if (initialSession.branchRole !== "feature") {
@@ -3371,11 +3380,12 @@ async function workflowStage(helpers, input) {
3371
3380
  session,
3372
3381
  {
3373
3382
  message,
3374
- waitForStaging: effectiveInput.waitForStaging !== false,
3383
+ waitForStaging,
3375
3384
  deletePreview: effectiveInput.deletePreview !== false,
3376
3385
  deleteBranch: effectiveInput.deleteBranch !== false,
3377
3386
  ciMode,
3378
- worktreeMode: effectiveInput.worktreeMode ?? "auto"
3387
+ worktreeMode: effectiveInput.worktreeMode ?? "auto",
3388
+ verifyDeployedResources: effectiveInput.verifyDeployedResources === true
3379
3389
  },
3380
3390
  [
3381
3391
  { id: "workspace-unlink", description: "Remove local workspace links", repoName: rootRepo.name, repoPath: rootRepo.path, branch: featureBranch, resumable: true },
@@ -3491,7 +3501,7 @@ async function workflowStage(helpers, input) {
3491
3501
  exitCode: 12
3492
3502
  });
3493
3503
  }
3494
- const stageWorkflowGateResult = effectiveInput.waitForStaging === false ? (skipJournalStep(root, workflowRun.runId, "wait-staging", { status: "skipped", reason: "disabled" }), { status: "skipped", reason: "disabled" }) : await executeJournalStep(root, workflowRun.runId, "wait-staging", () => waitForWorkflowGates("stage", [
3504
+ const stageWorkflowGateResult = !waitForStaging ? (skipJournalStep(root, workflowRun.runId, "wait-staging", { status: "skipped", reason: "disabled" }), { status: "skipped", reason: "disabled" }) : await executeJournalStep(root, workflowRun.runId, "wait-staging", () => waitForWorkflowGates("stage", [
3495
3505
  {
3496
3506
  name: rootRepo.name,
3497
3507
  repoPath: rootRepo.path,
@@ -111,6 +111,7 @@ export type TreeseedSaveInput = {
111
111
  worktreeMode?: TreeseedWorkflowWorktreeMode;
112
112
  commitMessageMode?: 'auto' | 'cloudflare' | 'generated' | 'fallback';
113
113
  workspaceLinks?: 'auto' | 'off';
114
+ verifyDeployedResources?: boolean;
114
115
  plan?: boolean;
115
116
  dryRun?: boolean;
116
117
  };
@@ -153,6 +154,7 @@ export type TreeseedStageInput = {
153
154
  ciMode?: TreeseedWorkflowCiMode;
154
155
  worktreeMode?: TreeseedWorkflowWorktreeMode;
155
156
  workspaceLinks?: 'auto' | 'off';
157
+ verifyDeployedResources?: boolean;
156
158
  plan?: boolean;
157
159
  dryRun?: boolean;
158
160
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@treeseed/sdk",
3
- "version": "0.6.42",
3
+ "version": "0.6.44",
4
4
  "description": "Shared Treeseed SDK for content-backed and D1-backed object models.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {