@skrr-ai/cli 0.1.26 → 0.1.28
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.js +25 -0
- package/dist/commands/machines/dedicated/attach.js +4 -3
- package/dist/commands/machines/dedicated/current.d.ts +19 -0
- package/dist/commands/machines/dedicated/current.js +49 -0
- package/dist/commands/machines/dedicated/destroy.js +7 -6
- package/dist/commands/machines/dedicated/exec.d.ts +4 -0
- package/dist/commands/machines/dedicated/exec.js +19 -2
- package/dist/commands/machines/dedicated/grow.js +3 -2
- package/dist/commands/machines/dedicated/health-check.js +4 -3
- package/dist/commands/machines/dedicated/incident-close.js +3 -2
- package/dist/commands/machines/dedicated/index.js +2 -0
- package/dist/commands/machines/dedicated/restart.js +3 -2
- package/dist/commands/machines/dedicated/restore.d.ts +26 -0
- package/dist/commands/machines/dedicated/restore.js +64 -0
- package/dist/commands/machines/dedicated/show.js +3 -2
- package/dist/commands/machines/dedicated/snapshot.js +3 -2
- package/dist/commands/machines/dedicated/spending-limit.js +4 -3
- package/dist/commands/machines/dedicated/start.js +3 -2
- package/dist/commands/machines/dedicated/stop.js +3 -2
- package/dist/lib/dedicated-exec.d.ts +80 -0
- package/dist/lib/dedicated-exec.js +271 -0
- package/dist/lib/dedicated-lease-command.d.ts +9 -0
- package/dist/lib/dedicated-lease-command.js +24 -1
- package/dist/lib/dedicated-machines.d.ts +90 -1
- package/dist/lib/dedicated-machines.js +125 -6
- package/dist/lib/edge-error-page.d.ts +49 -0
- package/dist/lib/edge-error-page.js +120 -0
- package/dist/lib/harnesses.d.ts +9 -1
- package/dist/lib/harnesses.js +20 -2
- package/dist/lib/hosted-machines.js +7 -0
- package/dist/lib/sky-code.js +11 -1
- package/dist/node_modules/@skrr-ai/data-provider/index.js +12 -0
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/index.js +3 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/loopback-server.js +64 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/managed-inference-broker.d.ts +30 -0
- package/dist/node_modules/@skrr-ai/inference-broker/dist/cjs/managed-inference-broker.js +43 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.d.ts +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/index.js +1 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/loopback-server.js +64 -1
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/managed-inference-broker.d.ts +30 -0
- package/dist/node_modules/@skrr-ai/inference-broker/dist/esm/managed-inference-broker.js +41 -0
- package/dist/node_modules/@skrr-ai/inference-broker/package.json +1 -1
- package/oclif.manifest.json +2928 -2734
- package/package.json +1 -1
package/dist/base-command.js
CHANGED
|
@@ -38,6 +38,7 @@ const refresh_1 = require("./lib/refresh");
|
|
|
38
38
|
const auth_storage_1 = require("./lib/auth-storage");
|
|
39
39
|
const update_check_1 = require("./lib/update-check");
|
|
40
40
|
const web_url_1 = require("./lib/web-url");
|
|
41
|
+
const edge_error_page_1 = require("./lib/edge-error-page");
|
|
41
42
|
const delegated_cli_1 = require("./lib/delegated-cli");
|
|
42
43
|
const tasks_1 = require("./lib/tasks");
|
|
43
44
|
function assigneePayloadNeedsResolution(payload) {
|
|
@@ -887,6 +888,30 @@ class BaseCommand extends core_1.Command {
|
|
|
887
888
|
retryable: true,
|
|
888
889
|
});
|
|
889
890
|
}
|
|
891
|
+
else if ((e.status === 403 || e.status === 504) &&
|
|
892
|
+
!body &&
|
|
893
|
+
(0, edge_error_page_1.describeEdgeErrorPage)({ status: e.status, body: e.body, method: e.method })) {
|
|
894
|
+
// An HTML page in place of the API's JSON: the edge answered, not the
|
|
895
|
+
// API (OSK-8700, OSK-8705). A WAF 403 is a content match that the same
|
|
896
|
+
// request will hit again, not "transient" and not a permission; an edge
|
|
897
|
+
// 504 is a request the API may still be carrying out, not proof of an
|
|
898
|
+
// outage. 502/503 pages keep the outage branch below, which is what
|
|
899
|
+
// they usually are and which records the incident.
|
|
900
|
+
const edge = (0, edge_error_page_1.describeEdgeErrorPage)({
|
|
901
|
+
status: e.status,
|
|
902
|
+
body: e.body,
|
|
903
|
+
method: e.method,
|
|
904
|
+
host: this.cliConfig?.baseURL,
|
|
905
|
+
});
|
|
906
|
+
this.failWithCliError({
|
|
907
|
+
message: say(edge.message),
|
|
908
|
+
code: edge.code,
|
|
909
|
+
status: e.status,
|
|
910
|
+
exit: e.status === 403 ? 3 : 5,
|
|
911
|
+
retryable: edge.retryable,
|
|
912
|
+
...(edge.requestId ? { details: { edgeRequestId: edge.requestId } } : {}),
|
|
913
|
+
});
|
|
914
|
+
}
|
|
890
915
|
else if (e.status === 403) {
|
|
891
916
|
// A 403 WITH a body is the API deciding; it says why, and we relay it.
|
|
892
917
|
//
|
|
@@ -30,7 +30,7 @@ class DedicatedMachinesAttach extends dedicated_lease_command_1.DedicatedLeaseCo
|
|
|
30
30
|
];
|
|
31
31
|
static args = {
|
|
32
32
|
lease: core_1.Args.string({
|
|
33
|
-
description:
|
|
33
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
34
34
|
required: true,
|
|
35
35
|
ignoreStdin: true,
|
|
36
36
|
}),
|
|
@@ -50,7 +50,8 @@ class DedicatedMachinesAttach extends dedicated_lease_command_1.DedicatedLeaseCo
|
|
|
50
50
|
async run() {
|
|
51
51
|
this.requireAuth();
|
|
52
52
|
const { args, flags } = await this.parse(DedicatedMachinesAttach);
|
|
53
|
-
const
|
|
53
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
54
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.getDedicatedRuntime)(leaseId, this.scopeFrom(flags)));
|
|
54
55
|
const lease = response?.lease;
|
|
55
56
|
if (!lease)
|
|
56
57
|
this.error('Dedicated Runtime lease not found.', { exit: 1 });
|
|
@@ -61,7 +62,7 @@ class DedicatedMachinesAttach extends dedicated_lease_command_1.DedicatedLeaseCo
|
|
|
61
62
|
}
|
|
62
63
|
const { harness } = selection;
|
|
63
64
|
if (!flags.json) {
|
|
64
|
-
process.stderr.write(`Attaching ${harness.provider} on ${
|
|
65
|
+
process.stderr.write(`Attaching ${harness.provider} on ${leaseId} (harness ${harness._id}, ${harness.status || 'status unknown'}).\n` +
|
|
65
66
|
'Everything the agent runs there acts as you: it shares the machine’s sign-ins and your skrr login.\n');
|
|
66
67
|
}
|
|
67
68
|
await attach_harness_1.default.run([
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr machines dedicated current` — which Dedicated Runtime am I running on?
|
|
4
|
+
*
|
|
5
|
+
* An agent working on the machine is the caller most likely to need its own
|
|
6
|
+
* lease — to snapshot before something risky, read the spend against the cap,
|
|
7
|
+
* or stop the machine when the work is done — and nothing in its environment
|
|
8
|
+
* names it. Every lease command also accepts `self`; this prints the answer so a
|
|
9
|
+
* script can hold it.
|
|
10
|
+
*/
|
|
11
|
+
export default class DedicatedMachinesCurrent extends DedicatedLeaseCommand {
|
|
12
|
+
static description: string;
|
|
13
|
+
static examples: string[];
|
|
14
|
+
static flags: {
|
|
15
|
+
id: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
16
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
17
|
+
};
|
|
18
|
+
run(): Promise<void>;
|
|
19
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
|
|
5
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
6
|
+
const harnesses_1 = require("../../../lib/harnesses");
|
|
7
|
+
/**
|
|
8
|
+
* `skrr machines dedicated current` — which Dedicated Runtime am I running on?
|
|
9
|
+
*
|
|
10
|
+
* An agent working on the machine is the caller most likely to need its own
|
|
11
|
+
* lease — to snapshot before something risky, read the spend against the cap,
|
|
12
|
+
* or stop the machine when the work is done — and nothing in its environment
|
|
13
|
+
* names it. Every lease command also accepts `self`; this prints the answer so a
|
|
14
|
+
* script can hold it.
|
|
15
|
+
*/
|
|
16
|
+
class DedicatedMachinesCurrent extends dedicated_lease_command_1.DedicatedLeaseCommand {
|
|
17
|
+
static description = 'Show the Dedicated Runtime this command is running on (every lease command also accepts `self`)';
|
|
18
|
+
static examples = [
|
|
19
|
+
'<%= config.bin %> machines dedicated current',
|
|
20
|
+
'<%= config.bin %> machines dedicated current --id',
|
|
21
|
+
'<%= config.bin %> machines dedicated snapshot self --wait',
|
|
22
|
+
];
|
|
23
|
+
static flags = {
|
|
24
|
+
id: core_1.Flags.boolean({ description: 'Print only the lease id', exclusive: ['json'] }),
|
|
25
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
26
|
+
};
|
|
27
|
+
async run() {
|
|
28
|
+
this.requireAuth();
|
|
29
|
+
const { flags } = await this.parse(DedicatedMachinesCurrent);
|
|
30
|
+
const leaseId = await this.resolveLeaseArg(dedicated_lease_command_1.DEDICATED_SELF_LEASE);
|
|
31
|
+
if (flags.id) {
|
|
32
|
+
this.log(leaseId);
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.getDedicatedRuntime)(leaseId));
|
|
36
|
+
if (flags.json) {
|
|
37
|
+
this.log(JSON.stringify(response, null, 2));
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
const lease = response?.lease;
|
|
41
|
+
if (!lease) {
|
|
42
|
+
this.error(`Dedicated Runtime ${leaseId} is not visible to this login.`, { exit: 1 });
|
|
43
|
+
}
|
|
44
|
+
const listed = await this.callDedicated(() => (0, harnesses_1.listHarnesses)());
|
|
45
|
+
for (const line of (0, dedicated_machines_1.describeDedicatedLease)(lease, listed?.harnesses ?? []))
|
|
46
|
+
this.log(line);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
exports.default = DedicatedMachinesCurrent;
|
|
@@ -12,7 +12,7 @@ class DedicatedMachinesDestroy extends dedicated_lease_command_1.DedicatedLeaseC
|
|
|
12
12
|
];
|
|
13
13
|
static args = {
|
|
14
14
|
lease: core_1.Args.string({
|
|
15
|
-
description:
|
|
15
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
16
16
|
required: true,
|
|
17
17
|
ignoreStdin: true,
|
|
18
18
|
}),
|
|
@@ -24,7 +24,7 @@ class DedicatedMachinesDestroy extends dedicated_lease_command_1.DedicatedLeaseC
|
|
|
24
24
|
exclusive: ['purge-storage'],
|
|
25
25
|
}),
|
|
26
26
|
'purge-storage': core_1.Flags.boolean({
|
|
27
|
-
description: '
|
|
27
|
+
description: 'Delete the workspace volume. It can be restored into a new machine for 7 days (`restore`), then every copy is deleted. Asks first unless --yes.',
|
|
28
28
|
exclusive: ['retain-storage'],
|
|
29
29
|
}),
|
|
30
30
|
yes: core_1.Flags.boolean({
|
|
@@ -37,6 +37,7 @@ class DedicatedMachinesDestroy extends dedicated_lease_command_1.DedicatedLeaseC
|
|
|
37
37
|
async run() {
|
|
38
38
|
this.requireAuth();
|
|
39
39
|
const { args, flags } = await this.parse(DedicatedMachinesDestroy);
|
|
40
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
40
41
|
// Only a destroy that DELETES the workspace asks, and that is not only
|
|
41
42
|
// `--purge-storage`: the server also purges when the lease is already
|
|
42
43
|
// archived, or when its retention class is `none` (or unset)
|
|
@@ -45,7 +46,7 @@ class DedicatedMachinesDestroy extends dedicated_lease_command_1.DedicatedLeaseC
|
|
|
45
46
|
// to PROMPT; the server still decides what happens.
|
|
46
47
|
let willPurge = Boolean(flags['purge-storage']);
|
|
47
48
|
if (!willPurge && !flags.yes) {
|
|
48
|
-
const current = await this.callDedicated(() => (0, dedicated_machines_1.getDedicatedRuntime)(
|
|
49
|
+
const current = await this.callDedicated(() => (0, dedicated_machines_1.getDedicatedRuntime)(leaseId, this.scopeFrom(flags)));
|
|
49
50
|
const lease = current?.lease;
|
|
50
51
|
willPurge =
|
|
51
52
|
lease?.state === 'archived' ||
|
|
@@ -53,9 +54,9 @@ class DedicatedMachinesDestroy extends dedicated_lease_command_1.DedicatedLeaseC
|
|
|
53
54
|
}
|
|
54
55
|
if (willPurge && !flags.yes) {
|
|
55
56
|
if (!process.stdin.isTTY) {
|
|
56
|
-
this.error('This destroy deletes the workspace volume
|
|
57
|
+
this.error('This destroy deletes the workspace volume. Pass --yes to confirm when not at a terminal.', { exit: 2 });
|
|
57
58
|
}
|
|
58
|
-
const confirmed = await this.confirm(`
|
|
59
|
+
const confirmed = await this.confirm(`Delete the workspace of ${leaseId}? You can restore it into a new machine for 7 days; after that its files, sign-ins and repositories are gone for good. [y/N] `);
|
|
59
60
|
if (!confirmed) {
|
|
60
61
|
this.log('Aborted.');
|
|
61
62
|
this.exit(1);
|
|
@@ -66,7 +67,7 @@ class DedicatedMachinesDestroy extends dedicated_lease_command_1.DedicatedLeaseC
|
|
|
66
67
|
retentionIntent = 'purge';
|
|
67
68
|
else if (flags['retain-storage'])
|
|
68
69
|
retentionIntent = 'retain';
|
|
69
|
-
const response = await this.callDedicated(() => (0, dedicated_machines_1.destroyDedicatedRuntime)(
|
|
70
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.destroyDedicatedRuntime)(leaseId, { ...this.scopeFrom(flags), retentionIntent }));
|
|
70
71
|
await this.reportLeaseAction(response, flags, { kind: 'destroyed' }, 'Destroying');
|
|
71
72
|
}
|
|
72
73
|
}
|
|
@@ -8,6 +8,9 @@ import { BaseCommand } from '../../../base-command';
|
|
|
8
8
|
* Machine's `connect` is that loop and has to say so in its own docs. The honest
|
|
9
9
|
* interactive surface is the terminal in the web app, which runs a real
|
|
10
10
|
* pseudo-terminal on the machine through the same daemon.
|
|
11
|
+
*
|
|
12
|
+
* The command is started and then observed (`lib/dedicated-exec.ts`), so it can
|
|
13
|
+
* run for its whole timeout whatever sits between the CLI and the API.
|
|
11
14
|
*/
|
|
12
15
|
export default class DedicatedMachinesExec extends BaseCommand {
|
|
13
16
|
static description: string;
|
|
@@ -21,6 +24,7 @@ export default class DedicatedMachinesExec extends BaseCommand {
|
|
|
21
24
|
command: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
25
|
cwd: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
26
|
timeout: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
27
|
+
'request-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
24
28
|
workspace: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
25
29
|
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
26
30
|
};
|
|
@@ -5,6 +5,7 @@ const base_command_1 = require("../../../base-command");
|
|
|
5
5
|
const shell_quote_1 = require("../../../lib/shell-quote");
|
|
6
6
|
const hosted_machines_1 = require("../../../lib/hosted-machines");
|
|
7
7
|
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
8
|
+
const dedicated_exec_1 = require("../../../lib/dedicated-exec");
|
|
8
9
|
const exec_1 = require("../hosted/exec");
|
|
9
10
|
/**
|
|
10
11
|
* `skrr machines dedicated exec` — the Run Command half of EC2 parity.
|
|
@@ -15,6 +16,9 @@ const exec_1 = require("../hosted/exec");
|
|
|
15
16
|
* Machine's `connect` is that loop and has to say so in its own docs. The honest
|
|
16
17
|
* interactive surface is the terminal in the web app, which runs a real
|
|
17
18
|
* pseudo-terminal on the machine through the same daemon.
|
|
19
|
+
*
|
|
20
|
+
* The command is started and then observed (`lib/dedicated-exec.ts`), so it can
|
|
21
|
+
* run for its whole timeout whatever sits between the CLI and the API.
|
|
18
22
|
*/
|
|
19
23
|
class DedicatedMachinesExec extends base_command_1.BaseCommand {
|
|
20
24
|
static description = 'Run one command on a Dedicated Runtime machine and return its output and exit code';
|
|
@@ -23,6 +27,7 @@ class DedicatedMachinesExec extends base_command_1.BaseCommand {
|
|
|
23
27
|
'<%= config.bin %> machines dedicated exec <lease-id> -- git -C repos/app status',
|
|
24
28
|
'<%= config.bin %> machines dedicated exec <lease-id> --cwd repos/app --timeout 5m -- npm test',
|
|
25
29
|
'<%= config.bin %> machines dedicated exec <lease-id> --command "ls -la user-data" --json',
|
|
30
|
+
'<%= config.bin %> machines dedicated exec <lease-id> --request-id deploy-42 -- ./deploy.sh',
|
|
26
31
|
];
|
|
27
32
|
static usage = 'machines dedicated exec <lease-id> [flags] -- <command...>';
|
|
28
33
|
static args = {
|
|
@@ -42,6 +47,9 @@ class DedicatedMachinesExec extends base_command_1.BaseCommand {
|
|
|
42
47
|
timeout: core_1.Flags.string({
|
|
43
48
|
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
49
|
}),
|
|
50
|
+
'request-id': core_1.Flags.string({
|
|
51
|
+
description: 'Idempotency key for this command. Repeating the invocation with the same id returns the run it already started (and its output, for 5 minutes after it ends) instead of running it again. Letters, digits and . _ : / - only.',
|
|
52
|
+
}),
|
|
45
53
|
workspace: core_1.Flags.string({ description: 'Workspace scope' }),
|
|
46
54
|
json: core_1.Flags.boolean({ description: 'Output the result as JSON' }),
|
|
47
55
|
};
|
|
@@ -60,6 +68,10 @@ class DedicatedMachinesExec extends base_command_1.BaseCommand {
|
|
|
60
68
|
if (!command.trim()) {
|
|
61
69
|
this.error('Command is required. Use --command or pass it after --.', { exit: 2 });
|
|
62
70
|
}
|
|
71
|
+
const requestId = flags['request-id'];
|
|
72
|
+
if (requestId !== undefined && !dedicated_exec_1.EXEC_REQUEST_ID_PATTERN.test(requestId)) {
|
|
73
|
+
this.error('--request-id must be 1-200 characters of letters, digits and . _ : / - (it is sent as an idempotency key).', { exit: 2 });
|
|
74
|
+
}
|
|
63
75
|
let timeoutMs;
|
|
64
76
|
try {
|
|
65
77
|
timeoutMs = (0, hosted_machines_1.parseDurationMs)(flags.timeout, '--timeout');
|
|
@@ -72,9 +84,14 @@ class DedicatedMachinesExec extends base_command_1.BaseCommand {
|
|
|
72
84
|
}
|
|
73
85
|
let result;
|
|
74
86
|
try {
|
|
75
|
-
result = await (0,
|
|
87
|
+
result = await (0, dedicated_exec_1.runDedicatedExec)(id, { command, ...(flags.cwd ? { cwd: flags.cwd } : {}), ...(timeoutMs ? { timeoutMs } : {}) }, { workspaceId: flags.workspace, ...(requestId ? { requestId } : {}) });
|
|
76
88
|
}
|
|
77
89
|
catch (err) {
|
|
90
|
+
if (err instanceof dedicated_exec_1.DedicatedExecContactLostError ||
|
|
91
|
+
err instanceof dedicated_exec_1.DedicatedExecStartUnconfirmedError ||
|
|
92
|
+
err instanceof dedicated_exec_1.DedicatedExecIdempotencyUnsupportedError) {
|
|
93
|
+
this.error(err.message, { exit: 1, code: err.code });
|
|
94
|
+
}
|
|
78
95
|
const message = (0, dedicated_machines_1.formatDedicatedRuntimeApiError)(err);
|
|
79
96
|
if (message)
|
|
80
97
|
this.error(message, { exit: 1, code: (0, dedicated_machines_1.dedicatedRuntimeApiErrorCode)(err) });
|
|
@@ -89,7 +106,7 @@ class DedicatedMachinesExec extends base_command_1.BaseCommand {
|
|
|
89
106
|
// About the invocation, not the command's output — stderr, so a caller
|
|
90
107
|
// piping stdout reads only what the machine printed.
|
|
91
108
|
if (result.truncated) {
|
|
92
|
-
process.stderr.write(
|
|
109
|
+
process.stderr.write(`\n${(0, dedicated_exec_1.describeTruncation)(result)}\n`);
|
|
93
110
|
}
|
|
94
111
|
if (result.timedOut) {
|
|
95
112
|
process.stderr.write(`\n[timed out after ${Math.round(result.durationMs / 1000)}s; the process group was killed]\n`);
|
|
@@ -11,7 +11,7 @@ class DedicatedMachinesGrow extends dedicated_lease_command_1.DedicatedLeaseComm
|
|
|
11
11
|
];
|
|
12
12
|
static args = {
|
|
13
13
|
lease: core_1.Args.string({
|
|
14
|
-
description:
|
|
14
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
15
15
|
required: true,
|
|
16
16
|
ignoreStdin: true,
|
|
17
17
|
}),
|
|
@@ -30,7 +30,8 @@ class DedicatedMachinesGrow extends dedicated_lease_command_1.DedicatedLeaseComm
|
|
|
30
30
|
async run() {
|
|
31
31
|
this.requireAuth();
|
|
32
32
|
const { args, flags } = await this.parse(DedicatedMachinesGrow);
|
|
33
|
-
const
|
|
33
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
34
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.growDedicatedRuntime)(leaseId, flags['storage-gb'], {
|
|
34
35
|
...this.scopeFrom(flags),
|
|
35
36
|
...(flags['request-id'] ? { requestId: flags['request-id'] } : {}),
|
|
36
37
|
}));
|
|
@@ -11,7 +11,7 @@ class DedicatedMachinesHealthCheck extends dedicated_lease_command_1.DedicatedLe
|
|
|
11
11
|
];
|
|
12
12
|
static args = {
|
|
13
13
|
lease: core_1.Args.string({
|
|
14
|
-
description:
|
|
14
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
15
15
|
required: true,
|
|
16
16
|
ignoreStdin: true,
|
|
17
17
|
}),
|
|
@@ -22,14 +22,15 @@ class DedicatedMachinesHealthCheck extends dedicated_lease_command_1.DedicatedLe
|
|
|
22
22
|
async run() {
|
|
23
23
|
this.requireAuth();
|
|
24
24
|
const { args, flags } = await this.parse(DedicatedMachinesHealthCheck);
|
|
25
|
-
const
|
|
25
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
26
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.performDedicatedLeaseAction)(leaseId, 'health-check', this.scopeFrom(flags)));
|
|
26
27
|
if (flags.json) {
|
|
27
28
|
this.log(JSON.stringify(response, null, 2));
|
|
28
29
|
return;
|
|
29
30
|
}
|
|
30
31
|
const lease = response?.lease;
|
|
31
32
|
if (!lease) {
|
|
32
|
-
this.log(`Dedicated Runtime ${
|
|
33
|
+
this.log(`Dedicated Runtime ${leaseId} ${(0, dedicated_machines_1.dedicatedLeaseState)(lease)}.`);
|
|
33
34
|
return;
|
|
34
35
|
}
|
|
35
36
|
// A health check exists to answer "can it take work, and if not why" — the
|
|
@@ -11,7 +11,7 @@ class DedicatedMachinesIncidentClose extends dedicated_lease_command_1.Dedicated
|
|
|
11
11
|
];
|
|
12
12
|
static args = {
|
|
13
13
|
lease: core_1.Args.string({
|
|
14
|
-
description:
|
|
14
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
15
15
|
required: true,
|
|
16
16
|
ignoreStdin: true,
|
|
17
17
|
}),
|
|
@@ -25,7 +25,8 @@ class DedicatedMachinesIncidentClose extends dedicated_lease_command_1.Dedicated
|
|
|
25
25
|
async run() {
|
|
26
26
|
this.requireAuth();
|
|
27
27
|
const { args, flags } = await this.parse(DedicatedMachinesIncidentClose);
|
|
28
|
-
const
|
|
28
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
29
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.closeDedicatedRuntimeIncidentHold)(leaseId, {
|
|
29
30
|
...this.scopeFrom(flags),
|
|
30
31
|
...(flags['request-id'] ? { requestId: flags['request-id'] } : {}),
|
|
31
32
|
}));
|
|
@@ -13,6 +13,7 @@ class DedicatedMachines extends core_1.Command {
|
|
|
13
13
|
'<%= config.bin %> machines dedicated create --name dev-box --size-preset standard --spending-limit-cents 20000 --wait',
|
|
14
14
|
'<%= config.bin %> machines dedicated list',
|
|
15
15
|
'<%= config.bin %> machines dedicated show <lease-id>',
|
|
16
|
+
'<%= config.bin %> machines dedicated snapshot self --wait',
|
|
16
17
|
'<%= config.bin %> machines dedicated attach <lease-id> --agent <agent-id>',
|
|
17
18
|
'<%= config.bin %> machines dedicated terminal <lease-id>',
|
|
18
19
|
'<%= config.bin %> machines dedicated sign-in <lease-id> github',
|
|
@@ -34,6 +35,7 @@ class DedicatedMachines extends core_1.Command {
|
|
|
34
35
|
['create', 'request a Dedicated Runtime'],
|
|
35
36
|
['list', 'list Dedicated Runtime leases'],
|
|
36
37
|
['show', 'state, size, spend, health and engines of one lease'],
|
|
38
|
+
['current', 'the lease of the machine this runs on (or pass `self`)'],
|
|
37
39
|
['attach', 'pin an agent so its work runs on the machine'],
|
|
38
40
|
['terminal', 'open an interactive shell on the machine'],
|
|
39
41
|
['sign-in', 'sign in to GitHub CLI, Claude Code or Codex there'],
|
|
@@ -12,7 +12,7 @@ class DedicatedMachinesRestart extends dedicated_lease_command_1.DedicatedLeaseC
|
|
|
12
12
|
];
|
|
13
13
|
static args = {
|
|
14
14
|
lease: core_1.Args.string({
|
|
15
|
-
description:
|
|
15
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
16
16
|
required: true,
|
|
17
17
|
ignoreStdin: true,
|
|
18
18
|
}),
|
|
@@ -24,7 +24,8 @@ class DedicatedMachinesRestart extends dedicated_lease_command_1.DedicatedLeaseC
|
|
|
24
24
|
async run() {
|
|
25
25
|
this.requireAuth();
|
|
26
26
|
const { args, flags } = await this.parse(DedicatedMachinesRestart);
|
|
27
|
-
const
|
|
27
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
28
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.performDedicatedLeaseAction)(leaseId, 'restart', this.scopeFrom(flags)));
|
|
28
29
|
await this.reportLeaseAction(response, flags, { kind: 'running' }, 'Restarting');
|
|
29
30
|
}
|
|
30
31
|
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { DedicatedLeaseCommand } from '../../../lib/dedicated-lease-command';
|
|
2
|
+
/**
|
|
3
|
+
* `skrr machines dedicated restore` — bring back a deleted Dedicated Runtime.
|
|
4
|
+
*
|
|
5
|
+
* Deleting a workspace keeps one final recovery point for a window (seven days
|
|
6
|
+
* by default), because whoever deleted it may have been an agent acting with
|
|
7
|
+
* the owner's authority. This builds a NEW machine from that point, with the
|
|
8
|
+
* deleted one's files; the deleted lease stays deleted.
|
|
9
|
+
*/
|
|
10
|
+
export default class DedicatedMachinesRestore extends DedicatedLeaseCommand {
|
|
11
|
+
static description: string;
|
|
12
|
+
static examples: string[];
|
|
13
|
+
static args: {
|
|
14
|
+
lease: import("@oclif/core/lib/interfaces").Arg<string, Record<string, unknown>>;
|
|
15
|
+
};
|
|
16
|
+
static flags: {
|
|
17
|
+
wait: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
18
|
+
timeout: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
19
|
+
interval: import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
20
|
+
name: import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
21
|
+
'spending-limit-cents': import("@oclif/core/lib/interfaces").OptionFlag<number | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
22
|
+
'request-id': import("@oclif/core/lib/interfaces").OptionFlag<string | undefined, import("@oclif/core/lib/interfaces").CustomOptions>;
|
|
23
|
+
json: import("@oclif/core/lib/interfaces").BooleanFlag<boolean>;
|
|
24
|
+
};
|
|
25
|
+
run(): Promise<void>;
|
|
26
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const core_1 = require("@oclif/core");
|
|
4
|
+
const node_crypto_1 = require("node:crypto");
|
|
5
|
+
const dedicated_lease_command_1 = require("../../../lib/dedicated-lease-command");
|
|
6
|
+
const dedicated_machines_1 = require("../../../lib/dedicated-machines");
|
|
7
|
+
/**
|
|
8
|
+
* `skrr machines dedicated restore` — bring back a deleted Dedicated Runtime.
|
|
9
|
+
*
|
|
10
|
+
* Deleting a workspace keeps one final recovery point for a window (seven days
|
|
11
|
+
* by default), because whoever deleted it may have been an agent acting with
|
|
12
|
+
* the owner's authority. This builds a NEW machine from that point, with the
|
|
13
|
+
* deleted one's files; the deleted lease stays deleted.
|
|
14
|
+
*/
|
|
15
|
+
class DedicatedMachinesRestore extends dedicated_lease_command_1.DedicatedLeaseCommand {
|
|
16
|
+
static description = 'Restore a deleted Dedicated Runtime into a new machine, from the recovery point its deletion kept. Only inside the recovery window, and once.';
|
|
17
|
+
static examples = [
|
|
18
|
+
'<%= config.bin %> machines dedicated restore <deleted-lease-id>',
|
|
19
|
+
'<%= config.bin %> machines dedicated restore <deleted-lease-id> --name research-box --wait',
|
|
20
|
+
];
|
|
21
|
+
static args = {
|
|
22
|
+
lease: core_1.Args.string({
|
|
23
|
+
description: 'The deleted Dedicated Runtime lease id (see `machines dedicated show`)',
|
|
24
|
+
required: true,
|
|
25
|
+
ignoreStdin: true,
|
|
26
|
+
}),
|
|
27
|
+
};
|
|
28
|
+
static flags = {
|
|
29
|
+
name: core_1.Flags.string({
|
|
30
|
+
description: 'Display name for the new machine (defaults to the deleted one, "(restored)")',
|
|
31
|
+
}),
|
|
32
|
+
'spending-limit-cents': core_1.Flags.integer({
|
|
33
|
+
description: "Monthly spending cap for the new machine (defaults to the deleted machine's)",
|
|
34
|
+
min: 1,
|
|
35
|
+
}),
|
|
36
|
+
'request-id': core_1.Flags.string({
|
|
37
|
+
description: 'Idempotency key. Reuse it to safely retry the same restore.',
|
|
38
|
+
}),
|
|
39
|
+
json: core_1.Flags.boolean({ description: 'Output as JSON' }),
|
|
40
|
+
...dedicated_lease_command_1.dedicatedWaitFlags,
|
|
41
|
+
};
|
|
42
|
+
async run() {
|
|
43
|
+
this.requireAuth();
|
|
44
|
+
const { args, flags } = await this.parse(DedicatedMachinesRestore);
|
|
45
|
+
const requestId = flags['request-id'] || `dedicated-restore:${Date.now()}:${(0, node_crypto_1.randomBytes)(6).toString('hex')}`;
|
|
46
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.restoreDeletedDedicatedRuntime)(args.lease, {
|
|
47
|
+
...this.scopeFrom(flags),
|
|
48
|
+
requestId,
|
|
49
|
+
...(flags.name ? { displayName: flags.name } : {}),
|
|
50
|
+
...(flags['spending-limit-cents'] !== undefined
|
|
51
|
+
? { monthlySpendingLimitCents: flags['spending-limit-cents'] }
|
|
52
|
+
: {}),
|
|
53
|
+
}));
|
|
54
|
+
if (!flags.json) {
|
|
55
|
+
const lease = response?.lease;
|
|
56
|
+
this.log(`Restoring ${args.lease} into ${(0, dedicated_machines_1.dedicatedLeaseDisplayName)(lease)} (${(0, dedicated_machines_1.dedicatedLeaseId)(lease) || 'unknown'}).`);
|
|
57
|
+
if (flags.wait && !flags['request-id']) {
|
|
58
|
+
process.stderr.write(`Request id ${requestId} (reuse it with --request-id to retry safely)\n`);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
await this.reportLeaseAction(response, flags, { kind: 'running' }, 'Restoring');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
exports.default = DedicatedMachinesRestore;
|
|
@@ -13,7 +13,7 @@ class DedicatedMachinesShow extends dedicated_lease_command_1.DedicatedLeaseComm
|
|
|
13
13
|
static args = {
|
|
14
14
|
lease: core_1.Args.string({
|
|
15
15
|
ignoreStdin: true,
|
|
16
|
-
description:
|
|
16
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
17
17
|
required: true,
|
|
18
18
|
}),
|
|
19
19
|
};
|
|
@@ -23,7 +23,8 @@ class DedicatedMachinesShow extends dedicated_lease_command_1.DedicatedLeaseComm
|
|
|
23
23
|
async run() {
|
|
24
24
|
this.requireAuth();
|
|
25
25
|
const { args, flags } = await this.parse(DedicatedMachinesShow);
|
|
26
|
-
const
|
|
26
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
27
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.getDedicatedRuntime)(leaseId, this.scopeFrom(flags)));
|
|
27
28
|
const lease = response?.lease;
|
|
28
29
|
if (!lease) {
|
|
29
30
|
this.error('Dedicated Runtime lease not found.', { exit: 1 });
|
|
@@ -12,7 +12,7 @@ class DedicatedMachinesSnapshot extends dedicated_lease_command_1.DedicatedLease
|
|
|
12
12
|
];
|
|
13
13
|
static args = {
|
|
14
14
|
lease: core_1.Args.string({
|
|
15
|
-
description:
|
|
15
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
16
16
|
required: true,
|
|
17
17
|
ignoreStdin: true,
|
|
18
18
|
}),
|
|
@@ -24,7 +24,8 @@ class DedicatedMachinesSnapshot extends dedicated_lease_command_1.DedicatedLease
|
|
|
24
24
|
async run() {
|
|
25
25
|
this.requireAuth();
|
|
26
26
|
const { args, flags } = await this.parse(DedicatedMachinesSnapshot);
|
|
27
|
-
const
|
|
27
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
28
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.performDedicatedLeaseAction)(leaseId, 'snapshot', this.scopeFrom(flags)));
|
|
28
29
|
// A snapshot returns the lease to the state it left, so the state cannot say
|
|
29
30
|
// whether it worked. The recovery point's timestamp can: the 202 carries the
|
|
30
31
|
// previous one, and success is a newer one.
|
|
@@ -20,7 +20,7 @@ class DedicatedMachinesSpendingLimit extends dedicated_lease_command_1.Dedicated
|
|
|
20
20
|
];
|
|
21
21
|
static args = {
|
|
22
22
|
lease: core_1.Args.string({
|
|
23
|
-
description:
|
|
23
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
24
24
|
required: true,
|
|
25
25
|
ignoreStdin: true,
|
|
26
26
|
}),
|
|
@@ -36,13 +36,14 @@ class DedicatedMachinesSpendingLimit extends dedicated_lease_command_1.Dedicated
|
|
|
36
36
|
async run() {
|
|
37
37
|
this.requireAuth();
|
|
38
38
|
const { args, flags } = await this.parse(DedicatedMachinesSpendingLimit);
|
|
39
|
-
const
|
|
39
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
40
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.setDedicatedRuntimeSpendingLimit)(leaseId, flags.cents, this.scopeFrom(flags)));
|
|
40
41
|
if (flags.json) {
|
|
41
42
|
this.log(JSON.stringify(response, null, 2));
|
|
42
43
|
return;
|
|
43
44
|
}
|
|
44
45
|
const lease = response?.lease;
|
|
45
|
-
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(lease) ||
|
|
46
|
+
this.log(`Dedicated Runtime ${(0, dedicated_machines_1.dedicatedLeaseId)(lease) || leaseId} spending cap updated.`);
|
|
46
47
|
if (lease)
|
|
47
48
|
this.log(` ${(0, dedicated_machines_1.dedicatedSpendSummary)(lease)}`);
|
|
48
49
|
}
|
|
@@ -12,7 +12,7 @@ class DedicatedMachinesStart extends dedicated_lease_command_1.DedicatedLeaseCom
|
|
|
12
12
|
];
|
|
13
13
|
static args = {
|
|
14
14
|
lease: core_1.Args.string({
|
|
15
|
-
description:
|
|
15
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
16
16
|
required: true,
|
|
17
17
|
ignoreStdin: true,
|
|
18
18
|
}),
|
|
@@ -24,7 +24,8 @@ class DedicatedMachinesStart extends dedicated_lease_command_1.DedicatedLeaseCom
|
|
|
24
24
|
async run() {
|
|
25
25
|
this.requireAuth();
|
|
26
26
|
const { args, flags } = await this.parse(DedicatedMachinesStart);
|
|
27
|
-
const
|
|
27
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
28
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.performDedicatedLeaseAction)(leaseId, 'start', this.scopeFrom(flags)));
|
|
28
29
|
await this.reportLeaseAction(response, flags, { kind: 'running' }, 'Starting');
|
|
29
30
|
}
|
|
30
31
|
}
|
|
@@ -12,7 +12,7 @@ class DedicatedMachinesStop extends dedicated_lease_command_1.DedicatedLeaseComm
|
|
|
12
12
|
];
|
|
13
13
|
static args = {
|
|
14
14
|
lease: core_1.Args.string({
|
|
15
|
-
description:
|
|
15
|
+
description: dedicated_lease_command_1.DEDICATED_LEASE_ARG_DESCRIPTION,
|
|
16
16
|
required: true,
|
|
17
17
|
ignoreStdin: true,
|
|
18
18
|
}),
|
|
@@ -24,7 +24,8 @@ class DedicatedMachinesStop extends dedicated_lease_command_1.DedicatedLeaseComm
|
|
|
24
24
|
async run() {
|
|
25
25
|
this.requireAuth();
|
|
26
26
|
const { args, flags } = await this.parse(DedicatedMachinesStop);
|
|
27
|
-
const
|
|
27
|
+
const leaseId = await this.resolveLeaseArg(args.lease);
|
|
28
|
+
const response = await this.callDedicated(() => (0, dedicated_machines_1.performDedicatedLeaseAction)(leaseId, 'stop', this.scopeFrom(flags)));
|
|
28
29
|
await this.reportLeaseAction(response, flags, { kind: 'stopped' }, 'Stopping');
|
|
29
30
|
}
|
|
30
31
|
}
|