diff --git a/api.md b/api.md index 7103b9b..181ee20 100644 --- a/api.md +++ b/api.md @@ -111,7 +111,7 @@ dedalus machines reboot \ #### List SSH sessions ```sh -dedalus machines:ssh list \ +dedalus machines ssh list \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --max-items 10 @@ -120,7 +120,7 @@ dedalus machines:ssh list \ #### Create SSH session ```sh -dedalus machines:ssh create \ +dedalus machines ssh create \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --public-key '' @@ -129,7 +129,7 @@ dedalus machines:ssh create \ #### Get SSH session ```sh -dedalus machines:ssh retrieve \ +dedalus machines ssh retrieve \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --session-id 'session_id' @@ -138,7 +138,7 @@ dedalus machines:ssh retrieve \ #### Delete SSH session ```sh -dedalus machines:ssh delete \ +dedalus machines ssh delete \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --session-id 'session_id' @@ -149,7 +149,7 @@ dedalus machines:ssh delete \ #### List executions ```sh -dedalus machines:executions list \ +dedalus machines executions list \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --max-items 10 @@ -158,7 +158,7 @@ dedalus machines:executions list \ #### Create execution ```sh -dedalus machines:executions create \ +dedalus machines executions create \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --command '[""]' @@ -167,7 +167,7 @@ dedalus machines:executions create \ #### Get execution ```sh -dedalus machines:executions retrieve \ +dedalus machines executions retrieve \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --execution-id 'execution_id' @@ -176,7 +176,7 @@ dedalus machines:executions retrieve \ #### Delete execution ```sh -dedalus machines:executions delete \ +dedalus machines executions delete \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --execution-id 'execution_id' @@ -185,7 +185,7 @@ dedalus machines:executions delete \ #### Get execution output ```sh -dedalus machines:executions output \ +dedalus machines executions output \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --execution-id 'execution_id' @@ -194,7 +194,7 @@ dedalus machines:executions output \ #### List execution events ```sh -dedalus machines:executions events \ +dedalus machines executions events \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --execution-id 'execution_id' \ @@ -206,7 +206,7 @@ dedalus machines:executions events \ ##### Get execution log status ```sh -dedalus machines:executions:logs retrieve \ +dedalus machines executions logs retrieve \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --execution-id 'execution_id' @@ -215,7 +215,7 @@ dedalus machines:executions:logs retrieve \ ##### Reauthorize execution log publication ```sh -dedalus machines:executions:logs reauthorize \ +dedalus machines executions logs reauthorize \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --execution-id 'execution_id' @@ -224,7 +224,7 @@ dedalus machines:executions:logs reauthorize \ ##### Create execution log read token ```sh -dedalus machines:executions:logs create-token \ +dedalus machines executions logs create-token \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --execution-id 'execution_id' @@ -235,7 +235,7 @@ dedalus machines:executions:logs create-token \ #### Read this machine's RAM autoresizing settings ```sh -dedalus machines:autoresizing retrieve \ +dedalus machines autoresizing retrieve \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' ``` @@ -243,7 +243,7 @@ dedalus machines:autoresizing retrieve \ #### Set this machine's RAM autoresizing settings ```sh -dedalus machines:autoresizing update \ +dedalus machines autoresizing update \ --x-api-key "$DEDALUS_X_API_KEY" \ --machine-id '017f22e2-79b0-7cc3-98c4-dc0c0c07398f' \ --enabled @@ -256,11 +256,11 @@ dedalus machines:autoresizing update \ #### Read organization RAM autoresizing policy ```sh -dedalus organization:autoresizing retrieve --x-api-key "$DEDALUS_X_API_KEY" +dedalus organization autoresizing retrieve --x-api-key "$DEDALUS_X_API_KEY" ``` #### Set organization RAM autoresizing policy ```sh -dedalus organization:autoresizing update --x-api-key "$DEDALUS_X_API_KEY" --enabled +dedalus organization autoresizing update --x-api-key "$DEDALUS_X_API_KEY" --enabled ``` diff --git a/man/dedalus-machines-autoresizing-retrieve.1 b/man/dedalus-machines-autoresizing-retrieve.1 index 34fc89f..5461806 100644 --- a/man/dedalus-machines-autoresizing-retrieve.1 +++ b/man/dedalus-machines-autoresizing-retrieve.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-autoresizing\-retrieve \- Read this machine's RAM autoresizing settings .SH "SYNOPSIS" -.B dedalus machines:autoresizing retrieve +.B dedalus machines autoresizing retrieve \fB\-\-machine\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Read this machine's RAM autoresizing settings @@ -48,7 +48,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:autoresizing retrieve \e +dedalus machines autoresizing retrieve \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' .fi diff --git a/man/dedalus-machines-autoresizing-update.1 b/man/dedalus-machines-autoresizing-update.1 index 4af3360..15c885f 100644 --- a/man/dedalus-machines-autoresizing-update.1 +++ b/man/dedalus-machines-autoresizing-update.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-autoresizing\-update \- Set this machine's RAM autoresizing settings .SH "SYNOPSIS" -.B dedalus machines:autoresizing update +.B dedalus machines autoresizing update \fB\-\-machine\-id\fR \fI\fR \fB\-\-enabled\fR [\fIoptions\fR] .SH "DESCRIPTION" Set this machine's RAM autoresizing settings @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:autoresizing update \e +dedalus machines autoresizing update \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-enabled diff --git a/man/dedalus-machines-executions-create.1 b/man/dedalus-machines-executions-create.1 index c3bb903..ce60887 100644 --- a/man/dedalus-machines-executions-create.1 +++ b/man/dedalus-machines-executions-create.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-create \- Create execution .SH "SYNOPSIS" -.B dedalus machines:executions create +.B dedalus machines executions create \fB\-\-machine\-id\fR \fI\fR \fB\-\-command\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Create execution @@ -63,7 +63,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions create \e +dedalus machines executions create \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-command '[""]' diff --git a/man/dedalus-machines-executions-delete.1 b/man/dedalus-machines-executions-delete.1 index 1bfab93..84973ae 100644 --- a/man/dedalus-machines-executions-delete.1 +++ b/man/dedalus-machines-executions-delete.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-delete \- Delete execution .SH "SYNOPSIS" -.B dedalus machines:executions delete +.B dedalus machines executions delete \fB\-\-machine\-id\fR \fI\fR \fB\-\-execution\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Delete execution @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions delete \e +dedalus machines executions delete \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-execution\-id 'execution_id' diff --git a/man/dedalus-machines-executions-events.1 b/man/dedalus-machines-executions-events.1 index b865b9f..adef54c 100644 --- a/man/dedalus-machines-executions-events.1 +++ b/man/dedalus-machines-executions-events.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-events \- List execution events .SH "SYNOPSIS" -.B dedalus machines:executions events +.B dedalus machines executions events \fB\-\-machine\-id\fR \fI\fR \fB\-\-execution\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" List execution events @@ -60,7 +60,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions events \e +dedalus machines executions events \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-execution\-id 'execution_id' \e diff --git a/man/dedalus-machines-executions-list.1 b/man/dedalus-machines-executions-list.1 index 81881b7..356b467 100644 --- a/man/dedalus-machines-executions-list.1 +++ b/man/dedalus-machines-executions-list.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-list \- List executions .SH "SYNOPSIS" -.B dedalus machines:executions list +.B dedalus machines executions list \fB\-\-machine\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" List executions @@ -57,7 +57,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions list \e +dedalus machines executions list \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-max\-items 10 diff --git a/man/dedalus-machines-executions-logs-create-token.1 b/man/dedalus-machines-executions-logs-create-token.1 index e1eff7a..e783f17 100644 --- a/man/dedalus-machines-executions-logs-create-token.1 +++ b/man/dedalus-machines-executions-logs-create-token.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-logs\-create\-token \- Create execution log read token .SH "SYNOPSIS" -.B dedalus machines:executions:logs create\-token +.B dedalus machines executions logs create\-token \fB\-\-machine\-id\fR \fI\fR \fB\-\-execution\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Create execution log read token @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions:logs create\-token \e +dedalus machines executions logs create\-token \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-execution\-id 'execution_id' diff --git a/man/dedalus-machines-executions-logs-reauthorize.1 b/man/dedalus-machines-executions-logs-reauthorize.1 index 62cc456..e020eab 100644 --- a/man/dedalus-machines-executions-logs-reauthorize.1 +++ b/man/dedalus-machines-executions-logs-reauthorize.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-logs\-reauthorize \- Reauthorize execution log publication .SH "SYNOPSIS" -.B dedalus machines:executions:logs reauthorize +.B dedalus machines executions logs reauthorize \fB\-\-machine\-id\fR \fI\fR \fB\-\-execution\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Reauthorize execution log publication @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions:logs reauthorize \e +dedalus machines executions logs reauthorize \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-execution\-id 'execution_id' diff --git a/man/dedalus-machines-executions-logs-retrieve.1 b/man/dedalus-machines-executions-logs-retrieve.1 index d4a13f1..c534f06 100644 --- a/man/dedalus-machines-executions-logs-retrieve.1 +++ b/man/dedalus-machines-executions-logs-retrieve.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-logs\-retrieve \- Get execution log status .SH "SYNOPSIS" -.B dedalus machines:executions:logs retrieve +.B dedalus machines executions logs retrieve \fB\-\-machine\-id\fR \fI\fR \fB\-\-execution\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Get execution log status @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions:logs retrieve \e +dedalus machines executions logs retrieve \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-execution\-id 'execution_id' diff --git a/man/dedalus-machines-executions-output.1 b/man/dedalus-machines-executions-output.1 index 656a19d..a2c1b3f 100644 --- a/man/dedalus-machines-executions-output.1 +++ b/man/dedalus-machines-executions-output.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-output \- Get execution output .SH "SYNOPSIS" -.B dedalus machines:executions output +.B dedalus machines executions output \fB\-\-machine\-id\fR \fI\fR \fB\-\-execution\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Get execution output @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions output \e +dedalus machines executions output \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-execution\-id 'execution_id' diff --git a/man/dedalus-machines-executions-retrieve.1 b/man/dedalus-machines-executions-retrieve.1 index 278ec4e..fa7c952 100644 --- a/man/dedalus-machines-executions-retrieve.1 +++ b/man/dedalus-machines-executions-retrieve.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-executions\-retrieve \- Get execution .SH "SYNOPSIS" -.B dedalus machines:executions retrieve +.B dedalus machines executions retrieve \fB\-\-machine\-id\fR \fI\fR \fB\-\-execution\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Get execution @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:executions retrieve \e +dedalus machines executions retrieve \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-execution\-id 'execution_id' diff --git a/man/dedalus-machines-ssh-create.1 b/man/dedalus-machines-ssh-create.1 index 20a5107..27f11c7 100644 --- a/man/dedalus-machines-ssh-create.1 +++ b/man/dedalus-machines-ssh-create.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-ssh\-create \- Create SSH session .SH "SYNOPSIS" -.B dedalus machines:ssh create +.B dedalus machines ssh create \fB\-\-machine\-id\fR \fI\fR \fB\-\-public\-key\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Create SSH session @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:ssh create \e +dedalus machines ssh create \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-public\-key "@file://$HOME/.ssh/id_ed25519.pub" diff --git a/man/dedalus-machines-ssh-delete.1 b/man/dedalus-machines-ssh-delete.1 index d36c22a..ad9abe5 100644 --- a/man/dedalus-machines-ssh-delete.1 +++ b/man/dedalus-machines-ssh-delete.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-ssh\-delete \- Delete SSH session .SH "SYNOPSIS" -.B dedalus machines:ssh delete +.B dedalus machines ssh delete \fB\-\-machine\-id\fR \fI\fR \fB\-\-session\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Delete SSH session @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:ssh delete \e +dedalus machines ssh delete \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-session\-id 'session_id' diff --git a/man/dedalus-machines-ssh-list.1 b/man/dedalus-machines-ssh-list.1 index ed9fe0c..9e97c3d 100644 --- a/man/dedalus-machines-ssh-list.1 +++ b/man/dedalus-machines-ssh-list.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-ssh\-list \- List SSH sessions .SH "SYNOPSIS" -.B dedalus machines:ssh list +.B dedalus machines ssh list \fB\-\-machine\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" List SSH sessions @@ -57,7 +57,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:ssh list \e +dedalus machines ssh list \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-max\-items 10 diff --git a/man/dedalus-machines-ssh-retrieve.1 b/man/dedalus-machines-ssh-retrieve.1 index 6c1347a..7d70dab 100644 --- a/man/dedalus-machines-ssh-retrieve.1 +++ b/man/dedalus-machines-ssh-retrieve.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-machines\-ssh\-retrieve \- Get SSH session .SH "SYNOPSIS" -.B dedalus machines:ssh retrieve +.B dedalus machines ssh retrieve \fB\-\-machine\-id\fR \fI\fR \fB\-\-session\-id\fR \fI\fR [\fIoptions\fR] .SH "DESCRIPTION" Get SSH session @@ -51,7 +51,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus machines:ssh retrieve \e +dedalus machines ssh retrieve \e \-\-x\-api\-key "$DEDALUS_X_API_KEY" \e \-\-machine\-id '017f22e2\-79b0\-7cc3\-98c4\-dc0c0c07398f' \e \-\-session\-id 'session_id' diff --git a/man/dedalus-organization-autoresizing-retrieve.1 b/man/dedalus-organization-autoresizing-retrieve.1 index af093fb..feee792 100644 --- a/man/dedalus-organization-autoresizing-retrieve.1 +++ b/man/dedalus-organization-autoresizing-retrieve.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-organization\-autoresizing\-retrieve \- Read organization RAM autoresizing policy .SH "SYNOPSIS" -.B dedalus organization:autoresizing retrieve +.B dedalus organization autoresizing retrieve [\fIoptions\fR] .SH "DESCRIPTION" Read organization RAM autoresizing policy @@ -45,7 +45,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus organization:autoresizing retrieve \-\-x\-api\-key "$DEDALUS_X_API_KEY" +dedalus organization autoresizing retrieve \-\-x\-api\-key "$DEDALUS_X_API_KEY" .fi .RE .SH "ENVIRONMENT" diff --git a/man/dedalus-organization-autoresizing-update.1 b/man/dedalus-organization-autoresizing-update.1 index 7d377b9..62cb633 100644 --- a/man/dedalus-organization-autoresizing-update.1 +++ b/man/dedalus-organization-autoresizing-update.1 @@ -3,7 +3,7 @@ .SH "NAME" dedalus\-organization\-autoresizing\-update \- Set organization RAM autoresizing policy .SH "SYNOPSIS" -.B dedalus organization:autoresizing update +.B dedalus organization autoresizing update \fB\-\-enabled\fR [\fIoptions\fR] .SH "DESCRIPTION" Set organization RAM autoresizing policy @@ -48,7 +48,7 @@ Dedalus API key. Alternative to Bearer token. Can also be set with the DEDALUS_X .PP .RS 4 .nf -dedalus organization:autoresizing update \-\-x\-api\-key "$DEDALUS_X_API_KEY" \-\-enabled +dedalus organization autoresizing update \-\-x\-api\-key "$DEDALUS_X_API_KEY" \-\-enabled .fi .RE .SH "ENVIRONMENT" diff --git a/man/dedalus.1 b/man/dedalus.1 index e144f18..4da9910 100644 --- a/man/dedalus.1 +++ b/man/dedalus.1 @@ -69,55 +69,55 @@ Wake a sleeping machine. See dedalus\-machines\-wake(1). \fBdedalus machines reboot\fR Reboot a machine with fresh memory. See dedalus\-machines\-reboot(1). .TP -\fBdedalus machines:ssh list\fR +\fBdedalus machines ssh list\fR List SSH sessions. See dedalus\-machines\-ssh\-list(1). .TP -\fBdedalus machines:ssh create\fR +\fBdedalus machines ssh create\fR Create SSH session. See dedalus\-machines\-ssh\-create(1). .TP -\fBdedalus machines:ssh retrieve\fR +\fBdedalus machines ssh retrieve\fR Get SSH session. See dedalus\-machines\-ssh\-retrieve(1). .TP -\fBdedalus machines:ssh delete\fR +\fBdedalus machines ssh delete\fR Delete SSH session. See dedalus\-machines\-ssh\-delete(1). .TP -\fBdedalus machines:executions list\fR +\fBdedalus machines executions list\fR List executions. See dedalus\-machines\-executions\-list(1). .TP -\fBdedalus machines:executions create\fR +\fBdedalus machines executions create\fR Create execution. See dedalus\-machines\-executions\-create(1). .TP -\fBdedalus machines:executions retrieve\fR +\fBdedalus machines executions retrieve\fR Get execution. See dedalus\-machines\-executions\-retrieve(1). .TP -\fBdedalus machines:executions delete\fR +\fBdedalus machines executions delete\fR Delete execution. See dedalus\-machines\-executions\-delete(1). .TP -\fBdedalus machines:executions output\fR +\fBdedalus machines executions output\fR Get execution output. See dedalus\-machines\-executions\-output(1). .TP -\fBdedalus machines:executions events\fR +\fBdedalus machines executions events\fR List execution events. See dedalus\-machines\-executions\-events(1). .TP -\fBdedalus machines:executions:logs retrieve\fR +\fBdedalus machines executions logs retrieve\fR Get execution log status. See dedalus\-machines\-executions\-logs\-retrieve(1). .TP -\fBdedalus machines:executions:logs reauthorize\fR +\fBdedalus machines executions logs reauthorize\fR Reauthorize execution log publication. See dedalus\-machines\-executions\-logs\-reauthorize(1). .TP -\fBdedalus machines:executions:logs create\-token\fR +\fBdedalus machines executions logs create\-token\fR Create execution log read token. See dedalus\-machines\-executions\-logs\-create\-token(1). .TP -\fBdedalus machines:autoresizing retrieve\fR +\fBdedalus machines autoresizing retrieve\fR Read this machine's RAM autoresizing settings. See dedalus\-machines\-autoresizing\-retrieve(1). .TP -\fBdedalus machines:autoresizing update\fR +\fBdedalus machines autoresizing update\fR Set this machine's RAM autoresizing settings. See dedalus\-machines\-autoresizing\-update(1). .TP -\fBdedalus organization:autoresizing retrieve\fR +\fBdedalus organization autoresizing retrieve\fR Read organization RAM autoresizing policy. See dedalus\-organization\-autoresizing\-retrieve(1). .TP -\fBdedalus organization:autoresizing update\fR +\fBdedalus organization autoresizing update\fR Set organization RAM autoresizing policy. See dedalus\-organization\-autoresizing\-update(1). .TP \fBdedalus completion\fR diff --git a/package.json b/package.json index c1c8419..9da538b 100644 --- a/package.json +++ b/package.json @@ -63,7 +63,7 @@ "scripts": { "build": "node -e \"require('node:fs').rmSync('dist', { recursive: true, force: true })\" && tsc -p tsconfig.json && tsc -p tsconfig.cjs.json && node scripts/finalize-build.mjs", "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.cjs.json --noEmit", - "test": "node --test tests/feedback-*.test.mjs tests/execution-argv.test.mjs", + "test": "node --test tests/feedback-*.test.mjs tests/execution-argv.test.mjs tests/nesting.test.mjs", "ci:generate": "hollywood generate 'ci/**/*.ts' --source-root ci --output .", "test:package": "node scripts/verify-staging-package.mjs" }, diff --git a/scripts/verify-staging-package.mjs b/scripts/verify-staging-package.mjs index b94eca7..c30c9fc 100644 --- a/scripts/verify-staging-package.mjs +++ b/scripts/verify-staging-package.mjs @@ -43,7 +43,7 @@ try { [ '--test', ...readdirSync('tests') - .filter((name) => /^feedback-.*\.test\.mjs$/.test(name) || name === 'execution-argv.test.mjs') + .filter((name) => /^feedback-.*\.test\.mjs$/.test(name) || ['execution-argv.test.mjs', 'nesting.test.mjs'].includes(name)) .map((name) => join('tests', name)), ], { diff --git a/src/cli/runtime.ts b/src/cli/runtime.ts index 6ef7db1..5b5e8b4 100644 --- a/src/cli/runtime.ts +++ b/src/cli/runtime.ts @@ -171,6 +171,16 @@ export const createProgram = ({ program.option('--' + option.name + ' ', clientOptionDescription(option)); } + // @custom start + // Resource nesting is a public CLI contract; preserve it when regenerating. + commands = commands.map((definition) => ({ + ...definition, commandPath: definition.commandPath.flatMap((part) => part.split(':')), + })); + groups = groups?.map((group) => ({ + ...group, commandPath: group.commandPath.flatMap((part) => part.split(':')), + })); + // @custom end + for (const definition of commands) addGeneratedCommand(program, SDK, clientOptions, definition, groups, auth); diff --git a/src/custom/README.md b/src/custom/README.md index 5db143f..1b44c9b 100644 --- a/src/custom/README.md +++ b/src/custom/README.md @@ -26,8 +26,7 @@ python3 tests/ssh-picker-pty.py # Execution arguments Use `dedalus machines exec --machine-id -- [args...]` to -create an execution. `machines executions`, `machines:exec`, and -`machines:executions` accept the same arguments, with optional `create`. +create an execution. `machines executions` accepts the same arguments, with optional `create`. Arguments after `--` are literal: spaces, empty arguments, remote flags, and `@file` references are sent unchanged. The executable itself cannot be empty. Do not combine these arguments with `--command`. @@ -46,3 +45,11 @@ arguments never become local file reads. ```sh node --test tests/execution-argv.test.mjs ``` + +# Nested resources + +Resource levels use spaces: `machines ssh`, `machines executions logs`, +`machines autoresizing`, and `organization autoresizing`. The custom runtime path normalization +runs before execution shortcuts and creates missing parent groups without +changing API handlers or flags. Preserve that marked block when regenerating. Colon spellings are removed. +Help and shell completion follow the resulting command tree. diff --git a/src/custom/completion.ts b/src/custom/completion.ts new file mode 100644 index 0000000..91a857e --- /dev/null +++ b/src/custom/completion.ts @@ -0,0 +1,79 @@ +/** Complete the live command tree so custom nesting and aliases stay discoverable. */ +import type { Command } from 'commander' + +export const completionCandidates = (program: Command, words: readonly string[]): string[] => { + let command = program + const prefix = words.at(-1) ?? '' + const previous = words.slice(0, -1) + const options = (node: Command) => [...node.options, ...program.options] + for (let index = 0; index < previous.length; index++) { + const word = previous[index]! + if (word === '--') return [] + if (word.startsWith('-')) { + const option = options(command).find((entry) => entry.long === word.split('=')[0] || entry.short === word.split('=')[0]) + if (!option) return [] + if (!word.includes('=') && (option.required || option.optional)) { + if (index === previous.length - 1) return option.argChoices?.filter((choice) => choice.startsWith(prefix)) ?? [] + if (option.required || !previous[index + 1]!.startsWith('-')) index++ + } + continue + } + const child = command.commands.find((entry) => entry.name() === word || entry.aliases().includes(word)) + if (!child) return [] + command = child + } + const children = command.createHelp().visibleCommands(command) + const candidates = [ + ...(command.name() === 'completion' ? Object.keys(scripts) : []), + ...children.flatMap((child) => [child.name(), ...child.aliases()]), + ...options(command).flatMap((option) => [option.short, option.long].filter((flag): flag is string => !!flag)), + '--help', + ] + return [...new Set(candidates)].filter((candidate) => candidate.startsWith(prefix)) +} + +const scripts: Readonly> = { + bash: `__dedalus_completion() { + local candidate + COMPREPLY=() + while IFS= read -r candidate; do + COMPREPLY+=("$candidate") + done < <(dedalus __complete -- "\${COMP_WORDS[@]:1:COMP_CWORD}") +} +complete -F __dedalus_completion dedalus +`, + zsh: `#compdef dedalus +_dedalus() { + local -a candidates + candidates=("\${(@f)$(dedalus __complete -- "\${words[@]:1}")}") + (( \${#candidates} )) && compadd -- "\${candidates[@]}" +} +compdef _dedalus dedalus +`, + fish: `function __dedalus_candidates + set -l words (commandline -opc) + set -l current (commandline -ct | string collect --allow-empty) + dedalus __complete -- $words[2..-1] "$current" +end +complete -c dedalus -f -a '(__dedalus_candidates)' +`, +} + +export const registerTreeCompletion = (program: Command): void => { + const completion = program.commands.find((command) => command.name() === 'completion') + if (!completion) return + program.command('__complete', { hidden: true }) + .argument('[words...]') + .action((words: string[]) => { + const candidates = completionCandidates(program, words) + if (candidates.length) process.stdout.write(candidates.join('\n') + '\n') + }) + completion.action((shell: string) => { + if (!Object.hasOwn(scripts, shell)) { + process.stderr.write(`Unsupported shell '${shell}'. Supported shells: bash, zsh, fish\n`) + process.exitCode = 2 + return + } + process.stdout.write(scripts[shell]!) + }) +} diff --git a/src/custom/executions.ts b/src/custom/executions.ts index 80f90b4..6676515 100644 --- a/src/custom/executions.ts +++ b/src/custom/executions.ts @@ -1,10 +1,10 @@ /** Preserve remote argv without interpreting its flags or local file references. */ -import { Command } from 'commander' -import { LiteralCliValue, usageExitCode } from '../cli/runtime.js' +import type { Command } from 'commander' +import { LiteralCliValue } from '../cli/runtime.js' export const addExecutionArguments = (program: Command): void => { - const generated = program.commands.find((command) => command.name() === 'machines:executions') const machines = program.commands.find((command) => command.name() === 'machines') + const generated = machines?.commands.find((command) => command.name() === 'executions') if (!generated || !machines) return const create = generated.commands.find((command) => command.name() === 'create') if (!create) throw new Error('execution create command is missing') @@ -30,22 +30,11 @@ export const addExecutionArguments = (program: Command): void => { // Both resource spellings share the generated API handlers and options. machines.enablePositionalOptions() - generated.enablePositionalOptions().alias('machines:exec') - const nested = usageExitCode(new Command('executions')) - .enablePositionalOptions() - .alias('exec') - .description('Run commands on a machine or manage executions') - .showHelpAfterError() - for (const command of generated.commands) { - nested.addCommand(command) + generated.enablePositionalOptions().alias('exec') + const parse = generated.parseOptions.bind(generated) + generated.parseOptions = (args) => { + const first = args[0] + const implicit = first?.startsWith('-') && first !== '--help' && first !== '-h' + return parse(implicit ? ['create', ...args] : args) } - for (const group of [generated, nested]) { - const parse = group.parseOptions.bind(group) - group.parseOptions = (args) => { - const first = args[0] - const implicit = first?.startsWith('-') && first !== '--help' && first !== '-h' - return parse(implicit ? ['create', ...args] : args) - } - } - machines.addCommand(nested) } diff --git a/src/custom/machines.ts b/src/custom/machines.ts index 927d09a..34f6a07 100644 --- a/src/custom/machines.ts +++ b/src/custom/machines.ts @@ -7,6 +7,7 @@ import { type CliClientOptionDefinition, type GlobalOptions, sdkClientOptions, writeError, errorExitCode, normalizeFormat, usageExitCode, } from '../cli/runtime.js' +import { registerTreeCompletion } from './completion.js' import { addExecutionArguments } from './executions.js' import { pickSSHMachine } from './ssh-picker.js' import { connectMachine, type SSHAPI } from './ssh.js' @@ -40,6 +41,7 @@ export const addMachineAliases = ( clientOptions: readonly CliClientOptionDefinition[], options: AliasOptions = {}, ): Command => { + registerTreeCompletion(program) addExecutionArguments(program) const makeAPI = options.api ?? createMachineAPI const connect = options.connect ?? connectMachine diff --git a/tests/execution-argv.test.mjs b/tests/execution-argv.test.mjs index 1ea51e2..8ad9806 100644 --- a/tests/execution-argv.test.mjs +++ b/tests/execution-argv.test.mjs @@ -29,7 +29,7 @@ const withAPI = async (action) => { finally { await new Promise((resolve) => server.close(resolve)) } } -const resources = [['machines', 'exec'], ['machines', 'executions'], ['machines:exec'], ['machines:executions']] +const resources = [['machines', 'exec'], ['machines', 'executions']] test('invariant_execution_argv_reaches_the_wire_literally_for_every_resource_spelling', async () => { await withAPI(async (baseURL, requests) => { diff --git a/tests/nesting.test.mjs b/tests/nesting.test.mjs new file mode 100644 index 0000000..ef91917 --- /dev/null +++ b/tests/nesting.test.mjs @@ -0,0 +1,96 @@ +import assert from 'node:assert/strict' +import { spawn, spawnSync } from 'node:child_process' +import { createServer } from 'node:http' +import { resolve } from 'node:path' +import { test } from 'node:test' + +const binary = resolve(process.env.FEEDBACK_PACKAGE_ROOT ?? '.', 'dist/esm/bin.js') +const run = (...args) => spawnSync(process.execPath, [binary, ...args], { encoding: 'utf8', timeout: 5000, env: { PATH: process.env.PATH } }) +const groups = [ + ['machines ssh', ['list', 'create', 'retrieve', 'delete']], + ['machines executions', ['list', 'create', 'retrieve', 'delete', 'output', 'events']], + ['machines executions logs', ['retrieve', 'reauthorize', 'create-token']], + ['machines autoresizing', ['retrieve', 'update']], + ['organization autoresizing', ['retrieve', 'update']], +] + +test('invariant_every_resource_operation_is_discoverable_under_its_parent', () => { + for (const [path, verbs] of groups) { + const parent = run(...path.split(' '), '--help') + assert.equal(parent.status, 0, parent.stderr) + for (const verb of verbs) { + assert.match(parent.stdout, new RegExp(`\\b${verb}\\b`)) + const result = run(...path.split(' '), verb, '--help') + assert.equal(result.status, 0, result.stderr) + assert.ok(result.stdout.includes(`Usage: dedalus ${path} ${verb}`)) + assert.ok(!result.stdout.includes(path.replaceAll(' ', ':'))) + } + assert.equal(run(path.replaceAll(' ', ':'), verbs[0]).status, 2) + } + assert.match(run('machines', '--help').stdout, /ssh/) + assert.match(run('organization', '--help').stdout, /autoresizing/) +}) + +test('invariant_nesting_preserves_resource_routes_and_global_credentials', async () => { + const requests = [] + const server = createServer((req, res) => { + requests.push([req.url, req.headers.authorization]) + res.setHeader('content-type', 'application/json') + res.end(JSON.stringify({ items: [] })) + }) + await new Promise((done) => server.listen(0, '127.0.0.1', done)) + try { + for (const [args, route] of [ + [['machines', 'ssh', 'list', '--machine-id', 'machine'], '/v1/machines/machine/ssh'], + [['machines', 'executions', 'list', '--machine-id', 'machine'], '/v1/machines/machine/executions'], + [['machines', 'executions', 'logs', 'retrieve', '--machine-id', 'machine', '--execution-id', 'execution'], '/v1/machines/machine/executions/execution/logs'], + [['machines', 'autoresizing', 'retrieve', '--machine-id', 'machine'], '/v1/machines/machine/autoresizing'], + [['organization', 'autoresizing', 'retrieve'], '/v1/organization/autoresizing'], + ]) { + const child = spawn(process.execPath, [binary, '--api-key', 'test', '--base-url', `http://127.0.0.1:${server.address().port}`, ...args], { env: { PATH: process.env.PATH }, stdio: ['ignore', 'pipe', 'pipe'] }) + let stderr = '' + child.stdout.resume() + child.stderr.on('data', (data) => { stderr += data }) + const status = await new Promise((done, reject) => { child.on('close', done); child.on('error', reject) }) + assert.equal(status, 0, stderr) + assert.deepEqual(requests.at(-1), [route, 'Bearer test']) + } + } finally { await new Promise((done) => server.close(done)) } +}) + +test('invariant_completion_follows_nested_resources_aliases_and_option_values', () => { + for (const [words, expected] of [ + [[''], 'organization'], [['machines', ''], 'ssh'], [['machines', ''], 'exec'], + [['machines', 'exec', ''], 'logs'], [['organization', ''], 'autoresizing'], + [['machines', 'executions', 'logs', ''], 'retrieve'], + [['--api-key', 'machines', 'machines', 'ssh', 'list', '--m'], '--machine-id'], + ]) { + const result = run('__complete', '--', ...words) + assert.equal(result.status, 0, result.stderr) + assert.ok(result.stdout.split('\n').includes(expected), result.stdout) + assert.ok(!result.stdout.includes(':')) + assert.ok(!result.stdout.includes('__complete')) + } + for (const words of [['--api-key', ''], ['machines', 'exec', '--', '']]) { + assert.equal(run('__complete', '--', ...words).stdout, '') + } + for (const shell of ['bash', 'zsh', 'fish']) assert.equal(run('completion', shell).status, 0) + assert.equal(run('completion', 'constructor').status, 2) +}) + +for (const shell of ['bash', 'zsh']) { + test(`invariant_${shell}_completion_passes_each_resource_word_separately`, { + skip: spawnSync(shell, ['--version']).error?.code === 'ENOENT', + }, () => { + const completion = run('completion', shell).stdout + const invoke = shell === 'bash' + ? 'COMP_WORDS=(dedalus machines executions logs ""); COMP_CWORD=4; __dedalus_completion; printf "%s\\n" "${COMPREPLY[@]}"' + : 'words=(dedalus machines executions logs ""); _dedalus' + const result = spawnSync(shell, ['-c', `dedalus() { "$NODE" "$BINARY" "$@"; }\ncompdef() { :; }\ncompadd() { shift; printf '%s\\n' "$@"; }\n${completion}\n${invoke}`], { + encoding: 'utf8', env: { PATH: process.env.PATH, NODE: process.execPath, BINARY: binary }, + }) + assert.equal(result.status, 0, result.stderr) + assert.ok(result.stdout.split('\n').includes('retrieve'), result.stdout) + assert.ok(!result.stdout.includes(':')) + }) +}