runcloud 0.2.190 → 0.2.191

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,24 @@
1
+ import { readFileSync, statSync } from 'node:fs';
2
+ const path = '/run-cloud/admin/fleet-release-control';
3
+ export function releaseControlRequest(file) {
4
+ const stat = statSync(file);
5
+ if (!stat.isFile() || stat.size > 512 * 1024)
6
+ throw new Error('Use a JSON request file smaller than 512 KiB');
7
+ const value = JSON.parse(readFileSync(file, 'utf8'));
8
+ if (!value || typeof value !== 'object' || Array.isArray(value) || typeof value.reason !== 'string' || !value.reason.trim()
9
+ || !Number.isSafeInteger(value.expectedRevision) || Number(value.expectedRevision) < 0
10
+ || !['bootstrap', 'enroll', 'announce', 'override', 'pause', 'resume', 'rollback', 'defer'].includes(String(value.action))) {
11
+ throw new Error('Request needs action, reason and expectedRevision from the current release-control status');
12
+ }
13
+ return value;
14
+ }
15
+ export function registerFleetReleaseControlCommands(fleet, client, action) {
16
+ const release = fleet.command('release-control').description('Audited fleet targets and coordinated health-gated serve-sim rollouts');
17
+ release.command('status').description('Read targets, rollout stages, gate values and audit history').action(() => action(async () => {
18
+ console.log(JSON.stringify(await client().get(path, { signal: AbortSignal.timeout(30000) }), null, 2));
19
+ }));
20
+ release.command('apply <request.json>').description('Apply an audited target or rollout request; pause stops new grants while existing holders finish safely')
21
+ .action((file) => action(async () => {
22
+ console.log(JSON.stringify(await client().post(path, releaseControlRequest(file), { signal: AbortSignal.timeout(30000) }), null, 2));
23
+ }));
24
+ }
@@ -5,6 +5,7 @@ import { ApiClient, ApiError } from '../api.js';
5
5
  import { requireCredentials } from '../config.js';
6
6
  import { surveyFleet, surveyText } from './run-cloud-fleet-survey.js';
7
7
  import { listReleaseChannels, promoteReleaseChannel, releaseText } from './run-cloud-fleet-releases.js';
8
+ import { registerFleetReleaseControlCommands } from './run-cloud-fleet-release-control.js';
8
9
  const ROOT = '/run-cloud/admin/simulators';
9
10
  const RANGES = ['1h', '6h', '24h', '7d', '30d', '90d', '1y', '2y'];
10
11
  export const ACCESSIBILITY_CODES = ['accessibility_device_unavailable', 'accessibility_capture_failed'];
@@ -303,6 +304,7 @@ function printReport(report, json) {
303
304
  }
304
305
  export function registerRunCloudFleet(program) {
305
306
  const fleet = program.command('fleet').description('Admin fleet telemetry, diagnosis, events, failure evidence and serve-sim release channels');
307
+ registerFleetReleaseControlCommands(fleet, credentialsClient, action);
306
308
  fleet.command('survey [hostId]').description('Survey all fleet signals in seconds; authenticated admin reads, no local services')
307
309
  .option('--json', 'Structured metrics, diagnosis, observations and coverage')
308
310
  .option('--range <range>', 'Alert/input-lag window: 1h, 6h, 24h, 7d', '24h')
package/dist/version.js CHANGED
@@ -1 +1 @@
1
- export const CLI_VERSION = '0.2.190';
1
+ export const CLI_VERSION = '0.2.191';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runcloud",
3
- "version": "0.2.190",
3
+ "version": "0.2.191",
4
4
  "description": "Create and control run.cloud remote mobile simulators and cloud sandboxes",
5
5
  "license": "Apache-2.0",
6
6
  "keywords": [
Binary file
Binary file