@substrat-run/cli 0.50.0 → 0.52.0

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.
@@ -0,0 +1,33 @@
1
+ import { type StoreDriverApprovalBody, type StoreDriverApprovalResultView, type StoreDriverRevokeResultView, type StoreDriverView } from '@substrat-run/control-plane-client';
2
+ /** CLI backstop: one release walk should not require more than 10,000 page requests. */
3
+ export declare const STORE_DRIVER_REVOKE_MAX_PAGES = 10000;
4
+ /** The same printable, bounded text rule as the approval and revoke routes. Values stay exact. */
5
+ export declare function storeDriverReviewText(value: unknown, field: string): string;
6
+ /** Validate the full body before the client sends it; no text is silently normalised. */
7
+ export declare function validateStoreDriverApproval(value: unknown): StoreDriverApprovalBody;
8
+ export declare function approvalFromFiles(input: {
9
+ reason: string;
10
+ sourceReferencesFile: string;
11
+ isolationReviewFile: string;
12
+ schema: string;
13
+ className: string;
14
+ operations: string[];
15
+ }): StoreDriverApprovalBody;
16
+ export declare function approvalLines(result: StoreDriverApprovalResultView): string[];
17
+ export declare function approvalStatusLines(view: StoreDriverView): string[];
18
+ export declare function uploadApprovalLine(driver: string, sha256: string): string;
19
+ /** Resume every server page; a busy or lost hold can be retried with the same command. */
20
+ export declare function revokeStoreDriverUntilComplete(input: {
21
+ client: {
22
+ revokeStoreDriverRelease(driver: string, sha256: string, body: {
23
+ reason: string;
24
+ emergency?: boolean;
25
+ }): Promise<StoreDriverRevokeResultView>;
26
+ };
27
+ driver: string;
28
+ sha256: string;
29
+ reason: string;
30
+ emergency: boolean;
31
+ progress: (line: string) => void;
32
+ }): Promise<StoreDriverRevokeResultView>;
33
+ //# sourceMappingURL=store-driver-approval.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-driver-approval.d.ts","sourceRoot":"","sources":["../src/store-driver-approval.ts"],"names":[],"mappings":"AAGA,OAAO,EAEL,KAAK,uBAAuB,EAC5B,KAAK,6BAA6B,EAClC,KAAK,2BAA2B,EAChC,KAAK,eAAe,EACrB,MAAM,oCAAoC,CAAC;AAU5C,wFAAwF;AACxF,eAAO,MAAM,6BAA6B,QAAS,CAAC;AAapD,kGAAkG;AAClG,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAK3E;AAED,yFAAyF;AACzF,wBAAgB,2BAA2B,CAAC,KAAK,EAAE,OAAO,GAAG,uBAAuB,CA2DnF;AAUD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE;IACvC,MAAM,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,CAAC;IAAC,mBAAmB,EAAE,MAAM,CAAC;IAC1E,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,EAAE,CAAC;CACzD,GAAG,uBAAuB,CAQ1B;AAED,wBAAgB,aAAa,CAAC,MAAM,EAAE,6BAA6B,GAAG,MAAM,EAAE,CAM7E;AAED,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAMnE;AAED,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAIzE;AAED,0FAA0F;AAC1F,wBAAsB,8BAA8B,CAAC,KAAK,EAAE;IAC1D,MAAM,EAAE;QAAE,wBAAwB,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE;YAAE,MAAM,EAAE,MAAM,CAAC;YAAC,SAAS,CAAC,EAAE,OAAO,CAAA;SAAE,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAA;KAAE,CAAC;IAC1J,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,OAAO,CAAC;IACnE,QAAQ,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAClC,GAAG,OAAO,CAAC,2BAA2B,CAAC,CA+BvC"}
@@ -0,0 +1,178 @@
1
+ /** Scriptable, person-only approval commands for already uploaded store-driver releases (D-65). */
2
+ import { readFileSync, statSync } from 'node:fs';
3
+ import { storeCatalogOperation } from '@substrat-run/contracts';
4
+ import { ControlPlaneError, } from '@substrat-run/control-plane-client';
5
+ const nonPrinting = /[\p{Cc}\p{Cf}\u2028\u2029]/u;
6
+ const commitShape = /^(?:[0-9a-f]{40}|[0-9a-f]{64})$/;
7
+ const classShape = /^[A-Za-z_][A-Za-z0-9_]*$/;
8
+ const reviewKeys = [
9
+ 'separateScriptPerTenant', 'noOutboundAccess', 'envelopeVerifiedOutsideDriver',
10
+ 'envelopeChecked', 'reservedOperationsChecked', 'noModuleStateChecked',
11
+ ];
12
+ const MAX_REVIEW_FILE_BYTES = 128 * 1024;
13
+ /** CLI backstop: one release walk should not require more than 10,000 page requests. */
14
+ export const STORE_DRIVER_REVOKE_MAX_PAGES = 10_000;
15
+ const record = (value, field) => {
16
+ if (value === null || typeof value !== 'object' || Array.isArray(value))
17
+ throw new Error(`${field}: expected an object`);
18
+ return value;
19
+ };
20
+ const exactKeys = (value, keys, field) => {
21
+ if (Object.keys(value).length !== keys.length || keys.some((key) => !Object.hasOwn(value, key))) {
22
+ throw new Error(`${field}: expected exactly ${keys.join(', ')}`);
23
+ }
24
+ };
25
+ /** The same printable, bounded text rule as the approval and revoke routes. Values stay exact. */
26
+ export function storeDriverReviewText(value, field) {
27
+ if (typeof value !== 'string' || value.length < 1 || value.length > 2048 || value.trim().length === 0 || nonPrinting.test(value)) {
28
+ throw new Error(`${field}: expected 1–2048 printable characters`);
29
+ }
30
+ return value;
31
+ }
32
+ /** Validate the full body before the client sends it; no text is silently normalised. */
33
+ export function validateStoreDriverApproval(value) {
34
+ const body = record(value, 'approval');
35
+ exactKeys(body, ['reason', 'sourceReferences', 'isolationReview', 'schema', 'className', 'operations'], 'approval');
36
+ const reason = storeDriverReviewText(body.reason, 'reason');
37
+ if (!Array.isArray(body.sourceReferences) || body.sourceReferences.length < 1 || body.sourceReferences.length > 64) {
38
+ throw new Error('sourceReferences: expected 1–64 repository and commit pairs');
39
+ }
40
+ const sourceReferences = body.sourceReferences.map((entry, i) => {
41
+ const ref = record(entry, `sourceReferences.${i}`);
42
+ exactKeys(ref, ['repository', 'commit'], `sourceReferences.${i}`);
43
+ const repository = ref.repository;
44
+ if (typeof repository !== 'string' || repository.length < 1 || repository.length > 1024 ||
45
+ !repository.startsWith('https://') || /[\s\\?#]/u.test(repository) || nonPrinting.test(repository)) {
46
+ throw new Error(`sourceReferences.${i}.repository: expected an HTTPS URL with host and path`);
47
+ }
48
+ let url;
49
+ try {
50
+ url = new URL(repository);
51
+ }
52
+ catch {
53
+ throw new Error(`sourceReferences.${i}.repository: expected an HTTPS URL with host and path`);
54
+ }
55
+ if (url.protocol !== 'https:' || !url.hostname || url.username || url.password || url.search || url.hash ||
56
+ !url.pathname.split('/').some(Boolean)) {
57
+ throw new Error(`sourceReferences.${i}.repository: expected an HTTPS URL with host and path`);
58
+ }
59
+ if (typeof ref.commit !== 'string' || !commitShape.test(ref.commit)) {
60
+ throw new Error(`sourceReferences.${i}.commit: expected 40 or 64 lowercase hex characters`);
61
+ }
62
+ return { repository, commit: ref.commit };
63
+ });
64
+ const review = record(body.isolationReview, 'isolationReview');
65
+ exactKeys(review, reviewKeys, 'isolationReview');
66
+ const checked = (key) => {
67
+ const part = record(review[key], `isolationReview.${key}`);
68
+ exactKeys(part, ['checked', 'evidence'], `isolationReview.${key}`);
69
+ if (part.checked !== true)
70
+ throw new Error(`isolationReview.${key}.checked: expected true`);
71
+ return { checked: true, evidence: storeDriverReviewText(part.evidence, `isolationReview.${key}.evidence`) };
72
+ };
73
+ const met = (key) => {
74
+ const part = record(review[key], `isolationReview.${key}`);
75
+ exactKeys(part, ['met', 'evidence'], `isolationReview.${key}`);
76
+ if (typeof part.met !== 'boolean')
77
+ throw new Error(`isolationReview.${key}.met: expected a boolean`);
78
+ return { met: part.met, evidence: storeDriverReviewText(part.evidence, `isolationReview.${key}.evidence`) };
79
+ };
80
+ const isolationReview = {
81
+ separateScriptPerTenant: met('separateScriptPerTenant'),
82
+ noOutboundAccess: met('noOutboundAccess'),
83
+ envelopeVerifiedOutsideDriver: met('envelopeVerifiedOutsideDriver'),
84
+ envelopeChecked: checked('envelopeChecked'),
85
+ reservedOperationsChecked: checked('reservedOperationsChecked'),
86
+ noModuleStateChecked: checked('noModuleStateChecked'),
87
+ };
88
+ if (typeof body.schema !== 'number' || !Number.isSafeInteger(body.schema) || body.schema < 0) {
89
+ throw new Error('schema: expected a non-negative integer');
90
+ }
91
+ if (typeof body.className !== 'string' || body.className.length > 256 || !classShape.test(body.className)) {
92
+ throw new Error('className: expected a Python class identifier');
93
+ }
94
+ if (!Array.isArray(body.operations) || body.operations.length > 256 ||
95
+ body.operations.some((name) => typeof name !== 'string' || nonPrinting.test(name) || !storeCatalogOperation.safeParse(name).success)) {
96
+ throw new Error('operations: expected at most 256 fixed catalog labels');
97
+ }
98
+ return { reason, sourceReferences, isolationReview, schema: body.schema, className: body.className, operations: body.operations };
99
+ }
100
+ function readReviewJson(path) {
101
+ if (statSync(path).size > MAX_REVIEW_FILE_BYTES)
102
+ throw new Error(`${path}: review JSON exceeds ${MAX_REVIEW_FILE_BYTES} bytes`);
103
+ const text = readFileSync(path, 'utf8');
104
+ if (Buffer.byteLength(text) > MAX_REVIEW_FILE_BYTES)
105
+ throw new Error(`${path}: review JSON exceeds ${MAX_REVIEW_FILE_BYTES} bytes`);
106
+ try {
107
+ return JSON.parse(text);
108
+ }
109
+ catch {
110
+ throw new Error(`${path}: expected JSON`);
111
+ }
112
+ }
113
+ export function approvalFromFiles(input) {
114
+ if (!/^(?:0|[1-9][0-9]*)$/.test(input.schema))
115
+ throw new Error('schema: expected a non-negative integer');
116
+ return validateStoreDriverApproval({
117
+ reason: input.reason,
118
+ sourceReferences: readReviewJson(input.sourceReferencesFile),
119
+ isolationReview: readReviewJson(input.isolationReviewFile),
120
+ schema: Number(input.schema), className: input.className, operations: input.operations,
121
+ });
122
+ }
123
+ export function approvalLines(result) {
124
+ const { approval, currentSchema } = result;
125
+ return [
126
+ `✓ approved ${approval.driver} ${approval.sha256} (approval ${approval.approvalId})`,
127
+ ` schema ${approval.schema}; current good schema ${currentSchema ?? 'none'}`,
128
+ ];
129
+ }
130
+ export function approvalStatusLines(view) {
131
+ if (!view.approvals)
132
+ return [];
133
+ if (view.approvals.length === 0)
134
+ return [' approvals: none'];
135
+ return view.approvals.map((approval) => approval.revokedAt
136
+ ? ` approval ${approval.approvalId} ${approval.sha256}: revoked ${approval.revokedAt} by ${approval.revokedBy}${approval.revokedEmergency ? ' (emergency)' : ''}; reason: ${approval.revokedReason}`
137
+ : ` approval ${approval.approvalId} ${approval.sha256}: live, approved ${approval.approvedAt} by ${approval.approvedBy}; schema ${approval.schema}, class ${approval.className}, operations ${approval.operations.join(', ') || 'none'}`);
138
+ }
139
+ export function uploadApprovalLine(driver, sha256) {
140
+ return ` upload alone does not make these bytes runnable; a staff person approves them with: ` +
141
+ `substrat store-driver approve --driver ${driver} --sha256 ${sha256} --reason <reason> ` +
142
+ '--source-references <json-file> --isolation-review <json-file> --schema <n> --class-name <Class> [--operation <name> ...]';
143
+ }
144
+ /** Resume every server page; a busy or lost hold can be retried with the same command. */
145
+ export async function revokeStoreDriverUntilComplete(input) {
146
+ let pages = 0;
147
+ let previousRemaining;
148
+ let unchangedPages = 0;
149
+ while (true) {
150
+ if (pages >= STORE_DRIVER_REVOKE_MAX_PAGES) {
151
+ throw new Error(`revoke walk exceeded the ${STORE_DRIVER_REVOKE_MAX_PAGES}-page CLI limit; run the same command again, or check store-driver status`);
152
+ }
153
+ pages += 1;
154
+ let result;
155
+ try {
156
+ result = await input.client.revokeStoreDriverRelease(input.driver, input.sha256, { reason: input.reason, ...(input.emergency ? { emergency: true } : {}) });
157
+ }
158
+ catch (error) {
159
+ if (error instanceof ControlPlaneError && error.status === 409 && /hold|held|busy|rollout or push/i.test(error.message)) {
160
+ throw new Error(`${error.message}; retry the same store-driver revoke command`);
161
+ }
162
+ throw error;
163
+ }
164
+ input.progress(result.complete
165
+ ? `✓ revoked approval ${result.approval.approvalId} for ${input.driver} ${input.sha256}`
166
+ : ` revoke walk paused: ${result.remaining} script(s) remaining; continuing`);
167
+ if (result.complete)
168
+ return result;
169
+ unchangedPages = previousRemaining !== undefined && result.remaining >= previousRemaining
170
+ ? unchangedPages + 1
171
+ : 0;
172
+ previousRemaining = result.remaining;
173
+ if (unchangedPages >= 3) {
174
+ throw new Error(`revoke walk remains at ${result.remaining} script(s) remaining; run the same command again, or check store-driver status`);
175
+ }
176
+ }
177
+ }
178
+ //# sourceMappingURL=store-driver-approval.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store-driver-approval.js","sourceRoot":"","sources":["../src/store-driver-approval.ts"],"names":[],"mappings":"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"}
@@ -46,6 +46,7 @@ export declare const uploadStoreDriverRelease: (input: Plane & {
46
46
  }) => Promise<{
47
47
  release: import("@substrat-run/control-plane-client").StoreDriverReleaseView;
48
48
  pinned: boolean;
49
+ approved?: boolean;
49
50
  }>;
50
51
  export declare const rollOutStoreDriver: (input: Plane & {
51
52
  driver: string;
@@ -1 +1 @@
1
- {"version":3,"file":"store-driver.d.ts","sourceRoot":"","sources":["../src/store-driver.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAiF,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACvJ,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAelG;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA8D,CAAC;AAI9G;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBnD;AAED,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,QAAS,MAAM,KAAG,MAAM,EAAqE,CAAC;AAEpI;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAgB5E;AAED,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,wBAAwB,CAiB7G;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAAE,CAUpJ;AAED,0GAA0G;AAC1G,eAAO,MAAM,YAAY,UAAW,MAAM,GAAG,SAAS,KAAG,KAAK,IAAI,MAA6D,CAAC;AAEhI,KAAK,KAAK,GAAG;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAEzE,eAAO,MAAM,wBAAwB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,wBAAwB,CAAA;CAAE;;;EACR,CAAC;AAEnG,eAAO,MAAM,kBAAkB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,uFACU,CAAC;AAE/F,eAAO,MAAM,mBAAmB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,uFACY,CAAC;AAElF,eAAO,MAAM,iBAAiB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,6BACS,CAAC;AAE7E,eAAO,MAAM,kBAAkB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE;;;EACqC,CAAC;AAEpI;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,EAAE,CA4BjF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAStF"}
1
+ {"version":3,"file":"store-driver.d.ts","sourceRoot":"","sources":["../src/store-driver.ts"],"names":[],"mappings":"AA2BA,OAAO,EAAiF,KAAK,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AACvJ,OAAO,KAAK,EAAE,sBAAsB,EAAE,eAAe,EAAE,MAAM,oCAAoC,CAAC;AAelG;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,SAAS,MAAM,EAA8D,CAAC;AAI9G;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAwBnD;AAED,gFAAgF;AAChF,eAAO,MAAM,yBAAyB,QAAS,MAAM,KAAG,MAAM,EAAqE,CAAC;AAEpI;;;;;;GAMG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAgB5E;AAED,kGAAkG;AAClG,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,wBAAwB,CAiB7G;AAED;;;;GAIG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE;IAAE,KAAK,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,OAAO,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,EAAE,CAUpJ;AAED,0GAA0G;AAC1G,eAAO,MAAM,YAAY,UAAW,MAAM,GAAG,SAAS,KAAG,KAAK,IAAI,MAA6D,CAAC;AAEhI,KAAK,KAAK,GAAG;IAAE,eAAe,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,CAAC;AAEzE,eAAO,MAAM,wBAAwB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,wBAAwB,CAAA;CAAE;;;;EACR,CAAC;AAEnG,eAAO,MAAM,kBAAkB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,uFACU,CAAC;AAE/F,eAAO,MAAM,mBAAmB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,uFACY,CAAC;AAElF,eAAO,MAAM,iBAAiB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAA;CAAE,6BACS,CAAC;AAE7E,eAAO,MAAM,kBAAkB,UAAW,KAAK,GAAG;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,cAAc,CAAC,EAAE,OAAO,CAAA;CAAE;;;EACqC,CAAC;AAEpI;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,sBAAsB,GAAG,MAAM,EAAE,CA4BjF;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,eAAe,GAAG,MAAM,EAAE,CAStF"}
@@ -4,7 +4,7 @@
4
4
  * refuses the service token.
5
5
  *
6
6
  * - `upload` packs the driver's package from `--dir` and stores it. The control plane names the
7
- * release by its sha256 and says whether this repo pins it yet; bytes may go up first.
7
+ * release by its sha256; a staff person approves those bytes separately.
8
8
  * - `rollout --sha256` moves every vertical to a stored, pinned release, after a canary. A big
9
9
  * fleet takes more than one request: the command says so, and running it again continues.
10
10
  * - `rollback` returns the driver to the immediately previous good release.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@substrat-run/cli",
3
- "version": "0.50.0",
3
+ "version": "0.52.0",
4
4
  "description": "The substrat CLI — authenticated deploy tooling: push a vertical to the platform, manage its versions and channels",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -30,10 +30,10 @@
30
30
  "dependencies": {
31
31
  "@babel/parser": "^7.29.11",
32
32
  "esbuild": "^0.28.2",
33
- "@substrat-run/boundary-lint": "^0.8.0",
34
- "@substrat-run/control-plane-client": "^0.3.15",
35
- "@substrat-run/contracts": "^0.164.0",
36
- "@substrat-run/model-view": "^0.6.11"
33
+ "@substrat-run/contracts": "^0.166.0",
34
+ "@substrat-run/control-plane-client": "^0.3.17",
35
+ "@substrat-run/boundary-lint": "^0.8.1",
36
+ "@substrat-run/model-view": "^0.6.13"
37
37
  },
38
38
  "devDependencies": {
39
39
  "@types/node": "^22.20.5",