@skrr-ai/cli 0.1.24 → 0.1.26
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.
- package/dist/base-command.d.ts +4 -4
- package/dist/base-command.js +11 -10
- package/dist/commands/code/install.js +13 -0
- package/dist/commands/harnesses/leases/billing.d.ts +9 -6
- package/dist/commands/harnesses/leases/billing.js +19 -24
- package/dist/commands/machines/dedicated/attach.d.ts +28 -0
- package/dist/commands/machines/dedicated/attach.js +75 -0
- package/dist/commands/machines/dedicated/catalog.d.ts +17 -0
- package/dist/commands/machines/dedicated/catalog.js +75 -0
- package/dist/commands/machines/dedicated/cp.d.ts +22 -0
- package/dist/commands/machines/dedicated/cp.js +76 -0
- package/dist/commands/machines/dedicated/create.d.ts +6 -2
- package/dist/commands/machines/dedicated/create.js +29 -20
- package/dist/commands/machines/dedicated/destroy.d.ts +6 -2
- package/dist/commands/machines/dedicated/destroy.js +41 -24
- package/dist/commands/machines/dedicated/exec.d.ts +28 -0
- package/dist/commands/machines/dedicated/exec.js +105 -0
- package/dist/commands/machines/dedicated/grow.d.ts +6 -2
- package/dist/commands/machines/dedicated/grow.js +14 -19
- package/dist/commands/machines/dedicated/health-check.d.ts +2 -2
- package/dist/commands/machines/dedicated/health-check.js +16 -14
- package/dist/commands/machines/dedicated/incident-close.d.ts +3 -2
- package/dist/commands/machines/dedicated/incident-close.js +11 -14
- package/dist/commands/machines/dedicated/index.js +37 -16
- package/dist/commands/machines/dedicated/list.d.ts +2 -2
- package/dist/commands/machines/dedicated/list.js +28 -17
- package/dist/commands/machines/dedicated/restart.d.ts +5 -2
- package/dist/commands/machines/dedicated/restart.js +8 -19
- package/dist/commands/machines/dedicated/show.d.ts +2 -2
- package/dist/commands/machines/dedicated/show.js +28 -30
- package/dist/commands/machines/dedicated/sign-in.d.ts +19 -0
- package/dist/commands/machines/dedicated/sign-in.js +49 -0
- package/dist/commands/machines/dedicated/snapshot.d.ts +5 -2
- package/dist/commands/machines/dedicated/snapshot.js +11 -19
- package/dist/commands/machines/dedicated/spending-limit.d.ts +22 -0
- package/dist/commands/machines/dedicated/spending-limit.js +50 -0
- package/dist/commands/machines/dedicated/start.d.ts +5 -2
- package/dist/commands/machines/dedicated/start.js +8 -19
- package/dist/commands/machines/dedicated/stop.d.ts +5 -2
- package/dist/commands/machines/dedicated/stop.js +8 -19
- package/dist/commands/machines/dedicated/terminal.d.ts +22 -0
- package/dist/commands/machines/dedicated/terminal.js +42 -0
- package/dist/commands/spaces/auto-executor/preview.d.ts +8 -0
- package/dist/commands/spaces/auto-executor/preview.js +41 -0
- package/dist/commands/spaces/task-rollups.d.ts +14 -0
- package/dist/commands/spaces/task-rollups.js +66 -0
- package/dist/commands/spaces/work-sync/telemetry.js +22 -0
- package/dist/commands/tasks/assign.js +1 -1
- package/dist/commands/tasks/create.js +10 -4
- package/dist/commands/tasks/list.js +27 -0
- package/dist/lib/api-fetch.js +9 -1
- package/dist/lib/assignee-resolver.d.ts +7 -6
- package/dist/lib/daemonBroker.d.ts +28 -0
- package/dist/lib/daemonBroker.js +60 -19
- package/dist/lib/dedicated-copy.d.ts +22 -0
- package/dist/lib/dedicated-copy.js +115 -0
- package/dist/lib/dedicated-lease-command.d.ts +50 -0
- package/dist/lib/dedicated-lease-command.js +158 -0
- package/dist/lib/dedicated-machines.d.ts +248 -12
- package/dist/lib/dedicated-machines.js +385 -25
- package/dist/lib/dedicated-terminal.d.ts +89 -0
- package/dist/lib/dedicated-terminal.js +275 -0
- package/dist/lib/dedicated-wait.d.ts +72 -0
- package/dist/lib/dedicated-wait.js +195 -0
- package/dist/lib/harnesses.d.ts +6 -0
- package/dist/lib/idempotency-scope.d.ts +10 -0
- package/dist/lib/idempotency-scope.js +16 -0
- package/dist/lib/node-adapter.d.ts +1 -1
- package/dist/lib/node-adapter.js +13 -11
- package/dist/lib/sky-code.d.ts +30 -1
- package/dist/lib/sky-code.js +44 -2
- package/dist/lib/triggers.js +7 -0
- package/dist/lib/work-sync.d.ts +35 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/index.js +2 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/kek/linux.js +71 -21
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.d.ts +10 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/cjs/spawnEnv.js +17 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/kek/linux.js +71 -21
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.d.ts +10 -0
- package/dist/node_modules/@skrr-ai/auth-core/dist/esm/spawnEnv.js +16 -0
- package/dist/node_modules/@skrr-ai/auth-core/package.json +1 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +2657 -2596
- package/oclif.manifest.json +5075 -4294
- package/package.json +1 -1
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
|
|
5
5
|
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
-
class DedicatedMachinesDestroy extends
|
|
7
|
-
static description = 'Destroy a Dedicated Runtime lease. Retention class standard/extended archives the lease and keeps the workspace volume; destroy an archived lease
|
|
6
|
+
class DedicatedMachinesDestroy extends dedicated_lease_command_1.DedicatedLeaseCommand {
|
|
7
|
+
static description = 'Destroy a Dedicated Runtime lease. Retention class standard/extended archives the lease and keeps the workspace volume; destroy an archived lease, or pass --purge-storage, to delete it.';
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> machines dedicated destroy <lease-id>',
|
|
10
|
-
'<%= config.bin %> machines dedicated destroy <lease-id> --
|
|
10
|
+
'<%= config.bin %> machines dedicated destroy <lease-id> --retain-storage --wait',
|
|
11
|
+
'<%= config.bin %> machines dedicated destroy <lease-id> --purge-storage --yes --json',
|
|
11
12
|
];
|
|
12
13
|
static args = {
|
|
13
14
|
lease: core_1.Args.string({
|
|
@@ -23,34 +24,50 @@ class DedicatedMachinesDestroy extends base_command_1.BaseCommand {
|
|
|
23
24
|
exclusive: ['purge-storage'],
|
|
24
25
|
}),
|
|
25
26
|
'purge-storage': core_1.Flags.boolean({
|
|
26
|
-
description: 'Permanently delete the workspace volume',
|
|
27
|
+
description: 'Permanently delete the workspace volume. Asks first unless --yes.',
|
|
27
28
|
exclusive: ['retain-storage'],
|
|
28
29
|
}),
|
|
30
|
+
yes: core_1.Flags.boolean({
|
|
31
|
+
char: 'y',
|
|
32
|
+
description: 'Skip the confirmation a destroy that deletes the workspace asks for',
|
|
33
|
+
default: false,
|
|
34
|
+
}),
|
|
35
|
+
...dedicated_lease_command_1.dedicatedWaitFlags,
|
|
29
36
|
};
|
|
30
37
|
async run() {
|
|
31
38
|
this.requireAuth();
|
|
32
39
|
const { args, flags } = await this.parse(DedicatedMachinesDestroy);
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
this.error(message, { exit: 1 });
|
|
47
|
-
this.handleApiError(err);
|
|
40
|
+
// Only a destroy that DELETES the workspace asks, and that is not only
|
|
41
|
+
// `--purge-storage`: the server also purges when the lease is already
|
|
42
|
+
// archived, or when its retention class is `none` (or unset)
|
|
43
|
+
// — `resolveDestroyRetention`. A retained destroy can still be purged later,
|
|
44
|
+
// so it does not ask. This mirrors the server's rule only to decide whether
|
|
45
|
+
// to PROMPT; the server still decides what happens.
|
|
46
|
+
let willPurge = Boolean(flags['purge-storage']);
|
|
47
|
+
if (!willPurge && !flags.yes) {
|
|
48
|
+
const current = await this.callDedicated(() => (0, dedicated_machines_1.getDedicatedRuntime)(args.lease, this.scopeFrom(flags)));
|
|
49
|
+
const lease = current?.lease;
|
|
50
|
+
willPurge =
|
|
51
|
+
lease?.state === 'archived' ||
|
|
52
|
+
(!flags['retain-storage'] && (lease?.storage?.retentionClass || 'none') === 'none');
|
|
48
53
|
}
|
|
49
|
-
if (flags.
|
|
50
|
-
|
|
51
|
-
|
|
54
|
+
if (willPurge && !flags.yes) {
|
|
55
|
+
if (!process.stdin.isTTY) {
|
|
56
|
+
this.error('This destroy deletes the workspace volume permanently. Pass --yes to confirm when not at a terminal.', { exit: 2 });
|
|
57
|
+
}
|
|
58
|
+
const confirmed = await this.confirm(`Permanently delete the workspace of ${args.lease}? Files, sign-ins and repositories on it cannot be recovered. [y/N] `);
|
|
59
|
+
if (!confirmed) {
|
|
60
|
+
this.log('Aborted.');
|
|
61
|
+
this.exit(1);
|
|
62
|
+
}
|
|
52
63
|
}
|
|
53
|
-
|
|
64
|
+
let retentionIntent;
|
|
65
|
+
if (flags['purge-storage'])
|
|
66
|
+
retentionIntent = 'purge';
|
|
67
|
+
else if (flags['retain-storage'])
|
|
68
|
+
retentionIntent = 'retain';
|
|
69
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.destroyDedicatedRuntime)(args.lease, { ...this.scopeFrom(flags), retentionIntent }));
|
|
70
|
+
await this.reportLeaseAction(response, flags, { kind: 'destroyed' }, 'Destroying');
|
|
54
71
|
}
|
|
55
72
|
}
|
|
56
73
|
exports.default = DedicatedMachinesDestroy;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { BaseCommand } from '../../../base-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr machines dedicated exec` — the Run Command half of EC2 parity.
|
|
4
|
+
*
|
|
5
|
+
* There is deliberately no `shell` beside it. A loop that sends one line at a
|
|
6
|
+
* time through exec is not a terminal: no TTY, no job control, no prompts a
|
|
7
|
+
* program can ask, no state between lines (`cd` does not stick). Hosted
|
|
8
|
+
* Machine's `connect` is that loop and has to say so in its own docs. The honest
|
|
9
|
+
* interactive surface is the terminal in the web app, which runs a real
|
|
10
|
+
* pseudo-terminal on the machine through the same daemon.
|
|
11
|
+
*/
|
|
12
|
+
export default class DedicatedMachinesExec extends BaseCommand {
|
|
13
|
+
static description: string;
|
|
14
|
+
static strict: boolean;
|
|
15
|
+
static examples: string[];
|
|
16
|
+
static usage: string;
|
|
17
|
+
static args: {
|
|
18
|
+
id: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
19
|
+
};
|
|
20
|
+
static flags: {
|
|
21
|
+
command: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
cwd: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
|
+
workspace: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
25
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
26
|
+
};
|
|
27
|
+
run(): Promise<void>;
|
|
28
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const base_command_1 = require("../../../base-command");
|
|
5
|
+
const shell_quote_1 = require("../../../lib/shell-quote");
|
|
6
|
+
const hosted_machines_1 = require("../../../lib/hosted-machines");
|
|
7
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
8
|
+
const exec_1 = require("../hosted/exec");
|
|
9
|
+
/**
|
|
10
|
+
* `skrr machines dedicated exec` — the Run Command half of EC2 parity.
|
|
11
|
+
*
|
|
12
|
+
* There is deliberately no `shell` beside it. A loop that sends one line at a
|
|
13
|
+
* time through exec is not a terminal: no TTY, no job control, no prompts a
|
|
14
|
+
* program can ask, no state between lines (`cd` does not stick). Hosted
|
|
15
|
+
* Machine's `connect` is that loop and has to say so in its own docs. The honest
|
|
16
|
+
* interactive surface is the terminal in the web app, which runs a real
|
|
17
|
+
* pseudo-terminal on the machine through the same daemon.
|
|
18
|
+
*/
|
|
19
|
+
class DedicatedMachinesExec extends base_command_1.BaseCommand {
|
|
20
|
+
static description = 'Run one command on a Dedicated Runtime machine and return its output and exit code';
|
|
21
|
+
static strict = false;
|
|
22
|
+
static examples = [
|
|
23
|
+
'<%= config.bin %> machines dedicated exec <lease-id> -- git -C repos/app status',
|
|
24
|
+
'<%= config.bin %> machines dedicated exec <lease-id> --cwd repos/app --timeout 5m -- npm test',
|
|
25
|
+
'<%= config.bin %> machines dedicated exec <lease-id> --command "ls -la user-data" --json',
|
|
26
|
+
];
|
|
27
|
+
static usage = 'machines dedicated exec <lease-id> [flags] -- <command...>';
|
|
28
|
+
static args = {
|
|
29
|
+
id: core_1.Args.string({
|
|
30
|
+
description: 'Dedicated Runtime lease id',
|
|
31
|
+
required: true,
|
|
32
|
+
ignoreStdin: true,
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
static flags = {
|
|
36
|
+
command: core_1.Flags.string({
|
|
37
|
+
description: 'Command to run as one shell string, instead of trailing argv',
|
|
38
|
+
}),
|
|
39
|
+
cwd: core_1.Flags.string({
|
|
40
|
+
description: 'Working directory, relative to /workspace (for example repos/app)',
|
|
41
|
+
}),
|
|
42
|
+
timeout: core_1.Flags.string({
|
|
43
|
+
description: `How long to let it run, such as 30s or 5m (default 2m, max ${dedicated_machines_1.DEDICATED_EXEC_MAX_TIMEOUT_MS / 60000}m). The process group is killed at the deadline.`,
|
|
44
|
+
}),
|
|
45
|
+
workspace: core_1.Flags.string({ description: 'Workspace scope' }),
|
|
46
|
+
json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
|
|
47
|
+
};
|
|
48
|
+
async run() {
|
|
49
|
+
this.requireAuth();
|
|
50
|
+
// Same argv contract as `machines hosted exec`: everything after the FIRST
|
|
51
|
+
// `--` is the remote argv, taken from the raw line so a second `--` survives.
|
|
52
|
+
const { head, tail } = (0, exec_1.splitExecArgv)(this.argv);
|
|
53
|
+
const { argv, flags } = await this.parse(DedicatedMachinesExec, head);
|
|
54
|
+
const raw = argv;
|
|
55
|
+
const id = raw[0];
|
|
56
|
+
const command = flags.command || (0, shell_quote_1.shellQuoteArgv)(tail ?? raw.slice(1));
|
|
57
|
+
if (!id) {
|
|
58
|
+
this.error('Lease id is required.', { exit: 2 });
|
|
59
|
+
}
|
|
60
|
+
if (!command.trim()) {
|
|
61
|
+
this.error('Command is required. Use --command or pass it after --.', { exit: 2 });
|
|
62
|
+
}
|
|
63
|
+
let timeoutMs;
|
|
64
|
+
try {
|
|
65
|
+
timeoutMs = (0, hosted_machines_1.parseDurationMs)(flags.timeout, '--timeout');
|
|
66
|
+
}
|
|
67
|
+
catch (err) {
|
|
68
|
+
this.error(err.message, { exit: 2 });
|
|
69
|
+
}
|
|
70
|
+
if (timeoutMs !== undefined && timeoutMs > dedicated_machines_1.DEDICATED_EXEC_MAX_TIMEOUT_MS) {
|
|
71
|
+
this.error(`--timeout is at most ${dedicated_machines_1.DEDICATED_EXEC_MAX_TIMEOUT_MS / 60000}m. For longer work, start it in the background (nohup … &) or give it to an agent.`, { exit: 2 });
|
|
72
|
+
}
|
|
73
|
+
let result;
|
|
74
|
+
try {
|
|
75
|
+
result = await (0, dedicated_machines_1.execDedicatedRuntime)(id, { command, ...(flags.cwd ? { cwd: flags.cwd } : {}), ...(timeoutMs ? { timeoutMs } : {}) }, { workspaceId: flags.workspace });
|
|
76
|
+
}
|
|
77
|
+
catch (err) {
|
|
78
|
+
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
79
|
+
if (message)
|
|
80
|
+
this.error(message, { exit: 1, code: (0, dedicated_machines_1.dedicatedRuntimeApiErrorCode)(err) });
|
|
81
|
+
this.handleApiError(err);
|
|
82
|
+
}
|
|
83
|
+
if (flags.json) {
|
|
84
|
+
this.log(JSON.stringify(result, null, 2));
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
if (result.stdout)
|
|
88
|
+
process.stdout.write(result.stdout);
|
|
89
|
+
// About the invocation, not the command's output — stderr, so a caller
|
|
90
|
+
// piping stdout reads only what the machine printed.
|
|
91
|
+
if (result.truncated) {
|
|
92
|
+
process.stderr.write('\n[output truncated at 1 MB]\n');
|
|
93
|
+
}
|
|
94
|
+
if (result.timedOut) {
|
|
95
|
+
process.stderr.write(`\n[timed out after ${Math.round(result.durationMs / 1000)}s; the process group was killed]\n`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
// Mirror the remote exit status so `exec … && next` composes like a local
|
|
99
|
+
// command. A timeout has no status of its own; 124 is what `timeout(1)` uses.
|
|
100
|
+
const exitCode = result.timedOut ? 124 : (result.exitCode ?? 1);
|
|
101
|
+
if (exitCode !== 0)
|
|
102
|
+
this.exit(exitCode);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
exports.default = DedicatedMachinesExec;
|
|
@@ -1,12 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class DedicatedMachinesGrow extends
|
|
1
|
+
import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
|
|
2
|
+
export default class DedicatedMachinesGrow extends DedicatedLeaseCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static args: {
|
|
6
6
|
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
7
|
};
|
|
8
8
|
static flags: {
|
|
9
|
+
wait: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
interval: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
12
|
'storage-gb': import("@oclif/core/lib/interfaces").OptionFlag<number, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
13
|
+
'request-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
14
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
11
15
|
};
|
|
12
16
|
run(): Promise<void>;
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
|
|
5
5
|
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
-
class DedicatedMachinesGrow extends
|
|
7
|
-
static description = 'Increase Dedicated Runtime workspace storage. Shrink is unsupported.';
|
|
6
|
+
class DedicatedMachinesGrow extends dedicated_lease_command_1.DedicatedLeaseCommand {
|
|
7
|
+
static description = 'Increase Dedicated Runtime workspace storage. Shrink is unsupported, and growth is permanent for the life of the volume.';
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> machines dedicated grow <lease-id> --storage-gb 200',
|
|
10
|
-
'<%= config.bin %> machines dedicated grow <lease-id> --storage-gb 200 --json',
|
|
10
|
+
'<%= config.bin %> machines dedicated grow <lease-id> --storage-gb 200 --wait --json',
|
|
11
11
|
];
|
|
12
12
|
static args = {
|
|
13
13
|
lease: core_1.Args.string({
|
|
@@ -21,26 +21,21 @@ class DedicatedMachinesGrow extends base_command_1.BaseCommand {
|
|
|
21
21
|
description: 'New workspace size in GiB. Must be larger than the current size.',
|
|
22
22
|
required: true,
|
|
23
23
|
}),
|
|
24
|
+
'request-id': core_1.Flags.string({
|
|
25
|
+
description: 'Idempotency key. Reuse it to safely retry the same grow request.',
|
|
26
|
+
}),
|
|
24
27
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
28
|
+
...dedicated_lease_command_1.dedicatedWaitFlags,
|
|
25
29
|
};
|
|
26
30
|
async run() {
|
|
27
31
|
this.requireAuth();
|
|
28
32
|
const { args, flags } = await this.parse(DedicatedMachinesGrow);
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
if (message)
|
|
36
|
-
this.error(message, { exit: 1 });
|
|
37
|
-
this.handleApiError(err);
|
|
38
|
-
}
|
|
39
|
-
if (flags.json) {
|
|
40
|
-
this.log(JSON.stringify(response, null, 2));
|
|
41
|
-
return;
|
|
42
|
-
}
|
|
43
|
-
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(response?.lease)} ${(0, dedicated_machines_1.dedicatedLeaseState)(response?.lease)}.`);
|
|
33
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.growDedicatedRuntime)(args.lease, flags['storage-gb'], {
|
|
34
|
+
...this.scopeFrom(flags),
|
|
35
|
+
...(flags['request-id'] ? { requestId: flags['request-id'] } : {}),
|
|
36
|
+
}));
|
|
37
|
+
// A grow never changes the lease state, so --wait watches the size itself.
|
|
38
|
+
await this.reportLeaseAction(response, flags, { kind: 'grown', storageGb: flags['storage-gb'] }, 'Growing');
|
|
44
39
|
}
|
|
45
40
|
}
|
|
46
41
|
exports.default = DedicatedMachinesGrow;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class DedicatedMachinesHealthCheck extends
|
|
1
|
+
import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
|
|
2
|
+
export default class DedicatedMachinesHealthCheck extends DedicatedLeaseCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static args: {
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
|
|
5
5
|
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
-
class DedicatedMachinesHealthCheck extends
|
|
7
|
-
static description = '
|
|
6
|
+
class DedicatedMachinesHealthCheck extends dedicated_lease_command_1.DedicatedLeaseCommand {
|
|
7
|
+
static description = 'Ask the control plane to re-observe a Dedicated Runtime (compute, volume, daemon heartbeat) and print what it found';
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> machines dedicated health-check <lease-id>',
|
|
10
10
|
'<%= config.bin %> machines dedicated health-check <lease-id> --json',
|
|
@@ -22,21 +22,23 @@ class DedicatedMachinesHealthCheck extends base_command_1.BaseCommand {
|
|
|
22
22
|
async run() {
|
|
23
23
|
this.requireAuth();
|
|
24
24
|
const { args, flags } = await this.parse(DedicatedMachinesHealthCheck);
|
|
25
|
-
|
|
26
|
-
try {
|
|
27
|
-
response = await (0, dedicated_machines_1.performDedicatedLeaseAction)(args.lease, 'health-check');
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
31
|
-
if (message)
|
|
32
|
-
this.error(message, { exit: 1 });
|
|
33
|
-
this.handleApiError(err);
|
|
34
|
-
}
|
|
25
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.performDedicatedLeaseAction)(args.lease, 'health-check', this.scopeFrom(flags)));
|
|
35
26
|
if (flags.json) {
|
|
36
27
|
this.log(JSON.stringify(response, null, 2));
|
|
37
28
|
return;
|
|
38
29
|
}
|
|
39
|
-
|
|
30
|
+
const lease = response?.lease;
|
|
31
|
+
if (!lease) {
|
|
32
|
+
this.log(`Dedicated Runtime ${args.lease} ${(0, dedicated_machines_1.dedicatedLeaseState)(lease)}.`);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
// A health check exists to answer "can it take work, and if not why" — the
|
|
36
|
+
// one-line state it used to print could not say either.
|
|
37
|
+
for (const line of (0, dedicated_machines_1.describeDedicatedLease)(lease))
|
|
38
|
+
this.log(line);
|
|
39
|
+
if (lease.health?.reasons?.includes('dedicated_runtime_provider_blind')) {
|
|
40
|
+
this.log('\nThe provider could not be read just now. That is not the same as the machine being gone; check again shortly.');
|
|
41
|
+
}
|
|
40
42
|
}
|
|
41
43
|
}
|
|
42
44
|
exports.default = DedicatedMachinesHealthCheck;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class DedicatedMachinesIncidentClose extends
|
|
1
|
+
import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
|
|
2
|
+
export default class DedicatedMachinesIncidentClose extends DedicatedLeaseCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static args: {
|
|
@@ -7,6 +7,7 @@ export default class DedicatedMachinesIncidentClose extends BaseCommand {
|
|
|
7
7
|
};
|
|
8
8
|
static flags: {
|
|
9
9
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
'request-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
10
11
|
};
|
|
11
12
|
run(): Promise<void>;
|
|
12
13
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
|
|
5
5
|
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
-
class DedicatedMachinesIncidentClose extends
|
|
7
|
-
static description = 'Close a Dedicated Runtime AZ-recovery incident hold. Does not
|
|
6
|
+
class DedicatedMachinesIncidentClose extends dedicated_lease_command_1.DedicatedLeaseCommand {
|
|
7
|
+
static description = 'Close a Dedicated Runtime AZ-recovery incident hold, releasing the held failed source volume. Does not touch the live workspace.';
|
|
8
8
|
static examples = [
|
|
9
9
|
'<%= config.bin %> machines dedicated incident-close <lease-id>',
|
|
10
10
|
'<%= config.bin %> machines dedicated incident-close <lease-id> --json',
|
|
@@ -18,25 +18,22 @@ class DedicatedMachinesIncidentClose extends base_command_1.BaseCommand {
|
|
|
18
18
|
};
|
|
19
19
|
static flags = {
|
|
20
20
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
21
|
+
'request-id': core_1.Flags.string({
|
|
22
|
+
description: 'Idempotency key. Reuse it to safely retry the same close.',
|
|
23
|
+
}),
|
|
21
24
|
};
|
|
22
25
|
async run() {
|
|
23
26
|
this.requireAuth();
|
|
24
27
|
const { args, flags } = await this.parse(DedicatedMachinesIncidentClose);
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
catch (err) {
|
|
30
|
-
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
31
|
-
if (message)
|
|
32
|
-
this.error(message, { exit: 1 });
|
|
33
|
-
this.handleApiError(err);
|
|
34
|
-
}
|
|
28
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.closeDedicatedRuntimeIncidentHold)(args.lease, {
|
|
29
|
+
...this.scopeFrom(flags),
|
|
30
|
+
...(flags['request-id'] ? { requestId: flags['request-id'] } : {}),
|
|
31
|
+
}));
|
|
35
32
|
if (flags.json) {
|
|
36
33
|
this.log(JSON.stringify(response, null, 2));
|
|
37
34
|
return;
|
|
38
35
|
}
|
|
39
|
-
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(response?.lease)} ${(0, dedicated_machines_1.dedicatedLeaseState)(response?.lease)}.`);
|
|
36
|
+
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(response?.lease)} ${(0, dedicated_machines_1.dedicatedLeaseState)(response?.lease)}; incident hold ${response?.lease?.recovery?.incidentHold?.status ?? 'closed'}.`);
|
|
40
37
|
}
|
|
41
38
|
}
|
|
42
39
|
exports.default = DedicatedMachinesIncidentClose;
|
|
@@ -9,31 +9,52 @@ class DedicatedMachines extends core_1.Command {
|
|
|
9
9
|
// — was invisible until a restart lost their work.
|
|
10
10
|
static description = 'A private VM with a durable workspace — files survive restart, running processes do not';
|
|
11
11
|
static examples = [
|
|
12
|
+
'<%= config.bin %> machines dedicated catalog',
|
|
13
|
+
'<%= config.bin %> machines dedicated create --name dev-box --size-preset standard --spending-limit-cents 20000 --wait',
|
|
12
14
|
'<%= config.bin %> machines dedicated list',
|
|
13
15
|
'<%= config.bin %> machines dedicated show <lease-id>',
|
|
14
|
-
'<%= config.bin %> machines dedicated
|
|
15
|
-
'<%= config.bin %> machines dedicated
|
|
16
|
-
'<%= config.bin %> machines dedicated
|
|
16
|
+
'<%= config.bin %> machines dedicated attach <lease-id> --agent <agent-id>',
|
|
17
|
+
'<%= config.bin %> machines dedicated terminal <lease-id>',
|
|
18
|
+
'<%= config.bin %> machines dedicated sign-in <lease-id> github',
|
|
19
|
+
'<%= config.bin %> machines dedicated exec <lease-id> -- git -C repos/app status',
|
|
20
|
+
'<%= config.bin %> machines dedicated cp ./notes.md <lease-id>:user-data/notes.md',
|
|
21
|
+
'<%= config.bin %> machines dedicated stop <lease-id> --wait',
|
|
22
|
+
'<%= config.bin %> machines dedicated start <lease-id> --wait',
|
|
17
23
|
'<%= config.bin %> machines dedicated restart <lease-id>',
|
|
18
|
-
'<%= config.bin %> machines dedicated snapshot <lease-id>',
|
|
24
|
+
'<%= config.bin %> machines dedicated snapshot <lease-id> --wait',
|
|
19
25
|
'<%= config.bin %> machines dedicated grow <lease-id> --storage-gb 200',
|
|
20
|
-
'<%= config.bin %> machines dedicated
|
|
26
|
+
'<%= config.bin %> machines dedicated spending-limit <lease-id> --cents 30000',
|
|
21
27
|
'<%= config.bin %> machines dedicated health-check <lease-id>',
|
|
28
|
+
'<%= config.bin %> machines dedicated incident-close <lease-id>',
|
|
22
29
|
'<%= config.bin %> machines dedicated destroy <lease-id>',
|
|
23
30
|
];
|
|
24
31
|
async run() {
|
|
32
|
+
const rows = [
|
|
33
|
+
['catalog', 'sizes, storage bounds and prices create accepts'],
|
|
34
|
+
['create', 'request a Dedicated Runtime'],
|
|
35
|
+
['list', 'list Dedicated Runtime leases'],
|
|
36
|
+
['show', 'state, size, spend, health and engines of one lease'],
|
|
37
|
+
['attach', 'pin an agent so its work runs on the machine'],
|
|
38
|
+
['terminal', 'open an interactive shell on the machine'],
|
|
39
|
+
['sign-in', 'sign in to GitHub CLI, Claude Code or Codex there'],
|
|
40
|
+
['exec', 'run one command; output and exit code'],
|
|
41
|
+
['cp', 'copy a file to or from the machine'],
|
|
42
|
+
['start', 'start a stopped runtime'],
|
|
43
|
+
['stop', 'stop compute and keep the disk'],
|
|
44
|
+
['restart', 'restart the instance; files stay'],
|
|
45
|
+
['snapshot', 'create a recovery point'],
|
|
46
|
+
['grow', 'increase workspace storage; shrink is unsupported'],
|
|
47
|
+
['spending-limit', 'change the monthly spending cap'],
|
|
48
|
+
['health-check', 'probe daemon and disk liveness'],
|
|
49
|
+
['incident-close', 'close AZ-recovery evidence hold'],
|
|
50
|
+
['destroy', 'stop compute; keep or purge the workspace disk'],
|
|
51
|
+
];
|
|
25
52
|
this.log('skrr Dedicated Runtime commands:');
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
this.log('
|
|
30
|
-
this.log('
|
|
31
|
-
this.log(' skrr machines dedicated restart restart the instance; files stay');
|
|
32
|
-
this.log(' skrr machines dedicated snapshot create a recovery point');
|
|
33
|
-
this.log(' skrr machines dedicated grow increase workspace storage; shrink is unsupported');
|
|
34
|
-
this.log(' skrr machines dedicated incident-close close AZ-recovery evidence hold');
|
|
35
|
-
this.log(' skrr machines dedicated health-check probe daemon and disk liveness');
|
|
36
|
-
this.log(' skrr machines dedicated destroy stop compute; keep or purge the workspace disk');
|
|
53
|
+
for (const [name, summary] of rows) {
|
|
54
|
+
this.log(` skrr machines dedicated ${name.padEnd(15)} ${summary}`);
|
|
55
|
+
}
|
|
56
|
+
this.log('');
|
|
57
|
+
this.log('Lifecycle commands take --wait; every command takes --workspace for a workspace machine.');
|
|
37
58
|
}
|
|
38
59
|
}
|
|
39
60
|
exports.default = DedicatedMachines;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class DedicatedMachinesList extends
|
|
1
|
+
import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
|
|
2
|
+
export default class DedicatedMachinesList extends DedicatedLeaseCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static flags: {
|
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
const core_1 = require("@oclif/core");
|
|
4
|
-
const
|
|
4
|
+
const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
|
|
5
5
|
const format_1 = require("../../../lib/format");
|
|
6
6
|
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
7
|
-
class DedicatedMachinesList extends
|
|
7
|
+
class DedicatedMachinesList extends dedicated_lease_command_1.DedicatedLeaseCommand {
|
|
8
8
|
static description = 'List Dedicated Runtime leases';
|
|
9
9
|
static examples = [
|
|
10
10
|
'<%= config.bin %> machines dedicated list',
|
|
11
|
-
'<%= config.bin %> machines dedicated list --
|
|
11
|
+
'<%= config.bin %> machines dedicated list --state stopped',
|
|
12
|
+
'<%= config.bin %> machines dedicated list --workspace <workspace-id> --json',
|
|
12
13
|
];
|
|
13
14
|
static flags = {
|
|
14
15
|
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
@@ -18,38 +19,48 @@ class DedicatedMachinesList extends base_command_1.BaseCommand {
|
|
|
18
19
|
async run() {
|
|
19
20
|
this.requireAuth();
|
|
20
21
|
const { flags } = await this.parse(DedicatedMachinesList);
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
});
|
|
27
|
-
}
|
|
28
|
-
catch (err) {
|
|
29
|
-
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
30
|
-
if (message)
|
|
31
|
-
this.error(message, { exit: 1 });
|
|
32
|
-
this.handleApiError(err);
|
|
33
|
-
}
|
|
22
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.listDedicatedRuntimes)({
|
|
23
|
+
limit: flags.limit,
|
|
24
|
+
state: flags.state,
|
|
25
|
+
...this.scopeFrom(flags),
|
|
26
|
+
}));
|
|
34
27
|
if (flags.json) {
|
|
35
28
|
this.log(JSON.stringify(response, null, 2));
|
|
36
29
|
return;
|
|
37
30
|
}
|
|
38
31
|
const leases = response?.leases ?? [];
|
|
39
32
|
if (leases.length === 0) {
|
|
40
|
-
|
|
33
|
+
// An empty filtered list and an empty account are different facts, and a
|
|
34
|
+
// scope that sees nothing is the usual reason a machine "disappeared".
|
|
35
|
+
this.log(flags.state
|
|
36
|
+
? `No Dedicated Runtime leases in state "${flags.state}".`
|
|
37
|
+
: 'No Dedicated Runtime leases.');
|
|
38
|
+
if (!flags.workspace) {
|
|
39
|
+
this.log('Machines created in a workspace are listed with --workspace <id>.');
|
|
40
|
+
}
|
|
41
41
|
return;
|
|
42
42
|
}
|
|
43
43
|
(0, format_1.renderTable)(leases.map((lease) => ({
|
|
44
44
|
id: (0, format_1.formatCell)((0, dedicated_machines_1.dedicatedLeaseId)(lease)),
|
|
45
45
|
status: (0, format_1.formatCell)((0, dedicated_machines_1.dedicatedLeaseState)(lease)),
|
|
46
46
|
name: (0, format_1.formatCell)((0, dedicated_machines_1.dedicatedLeaseDisplayName)(lease)),
|
|
47
|
+
size: (0, format_1.formatCell)([
|
|
48
|
+
lease.resources?.sizePreset,
|
|
49
|
+
lease.resources?.storageGb ? `${lease.resources.storageGb}G` : '',
|
|
50
|
+
]
|
|
51
|
+
.filter(Boolean)
|
|
52
|
+
.join(' ') || '-'),
|
|
53
|
+
spend: (0, format_1.formatCell)(lease.billing
|
|
54
|
+
? `${(0, dedicated_machines_1.formatUsdCents)(lease.billing.currentMonthSpendCents)}/${(0, dedicated_machines_1.formatUsdCents)(lease.billing.monthlySpendLimitCents)}${lease.billing.spendingLimitExceeded ? ' OVER' : ''}`
|
|
55
|
+
: '-'),
|
|
47
56
|
retention: (0, format_1.formatCell)(lease.storage?.retentionClass || '-'),
|
|
48
57
|
backup: (0, format_1.formatCell)(lease.storage?.lastBackupAt || '-'),
|
|
49
58
|
})), [
|
|
50
59
|
{ key: 'id', header: 'ID' },
|
|
51
60
|
{ key: 'status', header: 'STATUS' },
|
|
52
61
|
{ key: 'name', header: 'NAME', maxWidth: 28 },
|
|
62
|
+
{ key: 'size', header: 'SIZE', maxWidth: 18 },
|
|
63
|
+
{ key: 'spend', header: 'MONTH/CAP', maxWidth: 24 },
|
|
53
64
|
{ key: 'retention', header: 'RETENTION', maxWidth: 14 },
|
|
54
65
|
{ key: 'backup', header: 'LAST BACKUP', maxWidth: 24 },
|
|
55
66
|
], (line) => this.log(line));
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import {
|
|
2
|
-
export default class DedicatedMachinesRestart extends
|
|
1
|
+
import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
|
|
2
|
+
export default class DedicatedMachinesRestart extends DedicatedLeaseCommand {
|
|
3
3
|
static description: string;
|
|
4
4
|
static examples: string[];
|
|
5
5
|
static args: {
|
|
6
6
|
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
7
7
|
};
|
|
8
8
|
static flags: {
|
|
9
|
+
wait: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
11
|
+
interval: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
9
12
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
10
13
|
};
|
|
11
14
|
run(): Promise<void>;
|