@nocobase/cli 2.1.0-alpha.23 → 2.1.0-alpha.25
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/README.md +37 -2
- package/README.zh-CN.md +6 -2
- package/bin/run.js +28 -11
- package/dist/commands/db/shared.js +19 -5
- package/dist/commands/dev.js +8 -1
- package/dist/commands/down.js +10 -6
- package/dist/commands/env/add.js +14 -34
- package/dist/commands/env/auth.js +6 -13
- package/dist/commands/env/list.js +10 -15
- package/dist/commands/env/remove.js +4 -10
- package/dist/commands/env/update.js +7 -13
- package/dist/commands/env/use.js +5 -13
- package/dist/commands/init.js +190 -62
- package/dist/commands/install.js +101 -33
- package/dist/commands/logs.js +8 -1
- package/dist/commands/pm/list.js +8 -1
- package/dist/commands/ps.js +18 -15
- package/dist/commands/restart.js +74 -0
- package/dist/commands/self/check.js +71 -0
- package/dist/commands/self/index.js +20 -0
- package/dist/commands/self/update.js +86 -0
- package/dist/commands/skills/check.js +69 -0
- package/dist/commands/skills/index.js +20 -0
- package/dist/commands/skills/install.js +71 -0
- package/dist/commands/skills/update.js +71 -0
- package/dist/commands/start.js +8 -1
- package/dist/commands/stop.js +8 -1
- package/dist/commands/test.js +466 -0
- package/dist/commands/upgrade.js +12 -1
- package/dist/lib/api-client.js +3 -2
- package/dist/lib/app-runtime.js +16 -5
- package/dist/lib/auth-store.js +159 -43
- package/dist/lib/bootstrap.js +13 -12
- package/dist/lib/cli-home.js +33 -2
- package/dist/lib/env-auth.js +3 -3
- package/dist/lib/generated-command.js +10 -2
- package/dist/lib/http-request.js +49 -0
- package/dist/lib/resource-command.js +10 -2
- package/dist/lib/run-npm.js +82 -8
- package/dist/lib/runtime-generator.js +1 -1
- package/dist/lib/self-manager.js +246 -0
- package/dist/lib/skills-manager.js +269 -0
- package/dist/lib/startup-update.js +203 -0
- package/dist/locale/en-US.json +4 -1
- package/dist/locale/zh-CN.json +4 -1
- package/package.json +10 -4
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Command, loadHelpClass } from '@oclif/core';
|
|
10
|
+
export default class Self extends Command {
|
|
11
|
+
static summary = 'Inspect or update the NocoBase CLI itself';
|
|
12
|
+
async run() {
|
|
13
|
+
await this.parse(Self);
|
|
14
|
+
const Help = await loadHelpClass(this.config);
|
|
15
|
+
await new Help(this.config, this.config.pjson.oclif.helpOptions ?? this.config.pjson.helpOptions).showHelp([
|
|
16
|
+
this.id ?? 'self',
|
|
17
|
+
...this.argv,
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Command, Flags } from '@oclif/core';
|
|
10
|
+
import { confirmAction, setVerboseMode } from '../../lib/ui.js';
|
|
11
|
+
import { formatSelfUpdateUnavailableMessage, formatUnsupportedSelfUpdateMessage, inspectSelfStatus, updateSelf, } from '../../lib/self-manager.js';
|
|
12
|
+
export default class SelfUpdate extends Command {
|
|
13
|
+
static summary = 'Update the globally installed NocoBase CLI';
|
|
14
|
+
static description = 'Update the current NocoBase CLI install when it is managed by a standard global npm install.';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> <%= command.id %>',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> --yes',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> --channel alpha --json',
|
|
19
|
+
];
|
|
20
|
+
static flags = {
|
|
21
|
+
channel: Flags.string({
|
|
22
|
+
description: 'Release channel to update to. Defaults to the current CLI channel.',
|
|
23
|
+
options: ['auto', 'latest', 'beta', 'alpha'],
|
|
24
|
+
default: 'auto',
|
|
25
|
+
}),
|
|
26
|
+
yes: Flags.boolean({
|
|
27
|
+
char: 'y',
|
|
28
|
+
description: 'Skip the update confirmation prompt',
|
|
29
|
+
default: false,
|
|
30
|
+
}),
|
|
31
|
+
json: Flags.boolean({
|
|
32
|
+
description: 'Output the result as JSON',
|
|
33
|
+
default: false,
|
|
34
|
+
}),
|
|
35
|
+
verbose: Flags.boolean({
|
|
36
|
+
description: 'Show detailed update output',
|
|
37
|
+
default: false,
|
|
38
|
+
}),
|
|
39
|
+
};
|
|
40
|
+
async run() {
|
|
41
|
+
const { flags } = await this.parse(SelfUpdate);
|
|
42
|
+
setVerboseMode(flags.verbose);
|
|
43
|
+
const status = await inspectSelfStatus({
|
|
44
|
+
channel: flags.channel,
|
|
45
|
+
});
|
|
46
|
+
if (!status.updatable) {
|
|
47
|
+
this.error(formatUnsupportedSelfUpdateMessage(status));
|
|
48
|
+
}
|
|
49
|
+
if (!status.latestVersion && status.registryError) {
|
|
50
|
+
this.error(formatSelfUpdateUnavailableMessage(status));
|
|
51
|
+
}
|
|
52
|
+
if (!flags.yes && status.updateAvailable) {
|
|
53
|
+
const confirmed = await confirmAction(`Update ${status.packageName} from ${status.currentVersion} to ${status.latestVersion}?`, { defaultValue: false });
|
|
54
|
+
if (!confirmed) {
|
|
55
|
+
this.log('Skipped CLI update.');
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
const result = await updateSelf({
|
|
60
|
+
channel: flags.channel,
|
|
61
|
+
verbose: flags.verbose,
|
|
62
|
+
});
|
|
63
|
+
if (flags.json) {
|
|
64
|
+
this.log(JSON.stringify({
|
|
65
|
+
ok: true,
|
|
66
|
+
kind: 'self',
|
|
67
|
+
action: result.action,
|
|
68
|
+
packageName: result.status.packageName,
|
|
69
|
+
packageSpec: result.packageSpec,
|
|
70
|
+
channel: result.status.channel,
|
|
71
|
+
fromVersion: result.status.currentVersion,
|
|
72
|
+
toVersion: result.targetVersion,
|
|
73
|
+
}, null, 2));
|
|
74
|
+
return;
|
|
75
|
+
}
|
|
76
|
+
if (result.action === 'noop') {
|
|
77
|
+
this.log(flags.verbose
|
|
78
|
+
? `NocoBase CLI is already up to date at ${result.status.currentVersion}.`
|
|
79
|
+
: `NocoBase CLI is up to date: ${result.status.currentVersion}.`);
|
|
80
|
+
return;
|
|
81
|
+
}
|
|
82
|
+
this.log(flags.verbose
|
|
83
|
+
? `Updated NocoBase CLI from ${result.status.currentVersion} using ${result.packageSpec}${result.targetVersion ? ` (latest ${result.status.channel} resolves to ${result.targetVersion})` : ''}.`
|
|
84
|
+
: `Updated NocoBase CLI: ${result.status.currentVersion} -> ${result.targetVersion}.`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Command, Flags } from '@oclif/core';
|
|
10
|
+
import { inspectSkillsStatus } from '../../lib/skills-manager.js';
|
|
11
|
+
import { printInfo, renderTable } from '../../lib/ui.js';
|
|
12
|
+
export default class SkillsCheck extends Command {
|
|
13
|
+
static summary = 'Check the globally installed NocoBase AI coding skills';
|
|
14
|
+
static description = 'Inspect the global NocoBase AI coding skills and report whether they are managed by the CLI and whether an update is available.';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> <%= command.id %>',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> --json',
|
|
18
|
+
];
|
|
19
|
+
static flags = {
|
|
20
|
+
json: Flags.boolean({
|
|
21
|
+
description: 'Output the result as JSON',
|
|
22
|
+
default: false,
|
|
23
|
+
}),
|
|
24
|
+
};
|
|
25
|
+
async run() {
|
|
26
|
+
const { flags } = await this.parse(SkillsCheck);
|
|
27
|
+
const status = await inspectSkillsStatus();
|
|
28
|
+
if (flags.json) {
|
|
29
|
+
this.log(JSON.stringify({
|
|
30
|
+
ok: true,
|
|
31
|
+
kind: 'skills',
|
|
32
|
+
globalRoot: status.globalRoot,
|
|
33
|
+
workspaceRoot: status.workspaceRoot,
|
|
34
|
+
installed: status.installed,
|
|
35
|
+
managedByNb: status.managedByNb,
|
|
36
|
+
sourcePackage: status.sourcePackage,
|
|
37
|
+
npmPackageName: status.npmPackageName,
|
|
38
|
+
installedSkillNames: status.installedSkillNames,
|
|
39
|
+
installedVersion: status.installedVersion,
|
|
40
|
+
latestVersion: status.latestVersion,
|
|
41
|
+
installedRef: status.installedRef,
|
|
42
|
+
latestRef: status.latestRef,
|
|
43
|
+
updateAvailable: status.updateAvailable,
|
|
44
|
+
recommendedCommand: status.installed ? 'nb skills update --yes' : 'nb skills install --yes',
|
|
45
|
+
registryError: status.registryError,
|
|
46
|
+
}, null, 2));
|
|
47
|
+
return;
|
|
48
|
+
}
|
|
49
|
+
this.log(renderTable(['Field', 'Value'], [
|
|
50
|
+
['Skills home', status.globalRoot],
|
|
51
|
+
['Installed', status.installed ? 'yes' : 'no'],
|
|
52
|
+
['Managed by nb', status.managedByNb ? 'yes' : 'no'],
|
|
53
|
+
['Installed skills', status.installedSkillNames.length ? status.installedSkillNames.join(', ') : '(none)'],
|
|
54
|
+
['Installed version', status.installedVersion ?? '(unknown)'],
|
|
55
|
+
['Latest version', status.latestVersion ?? '(unknown)'],
|
|
56
|
+
['Update available', status.updateAvailable === null ? 'unknown' : status.updateAvailable ? 'yes' : 'no'],
|
|
57
|
+
]));
|
|
58
|
+
if (!status.installed) {
|
|
59
|
+
printInfo('Run `nb skills install` to install the NocoBase AI coding skills globally.');
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
if (status.updateAvailable) {
|
|
63
|
+
printInfo('Run `nb skills update` to refresh the global NocoBase AI coding skills.');
|
|
64
|
+
}
|
|
65
|
+
if (status.registryError) {
|
|
66
|
+
printInfo(`Update check warning: ${status.registryError}`);
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Command, loadHelpClass } from '@oclif/core';
|
|
10
|
+
export default class Skills extends Command {
|
|
11
|
+
static summary = 'Inspect or synchronize global NocoBase AI coding skills';
|
|
12
|
+
async run() {
|
|
13
|
+
await this.parse(Skills);
|
|
14
|
+
const Help = await loadHelpClass(this.config);
|
|
15
|
+
await new Help(this.config, this.config.pjson.oclif.helpOptions ?? this.config.pjson.helpOptions).showHelp([
|
|
16
|
+
this.id ?? 'skills',
|
|
17
|
+
...this.argv,
|
|
18
|
+
]);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Command, Flags } from '@oclif/core';
|
|
10
|
+
import { confirmAction, setVerboseMode } from '../../lib/ui.js';
|
|
11
|
+
import { installNocoBaseSkills } from '../../lib/skills-manager.js';
|
|
12
|
+
export default class SkillsInstall extends Command {
|
|
13
|
+
static summary = 'Install the NocoBase AI coding skills globally';
|
|
14
|
+
static description = 'Install the NocoBase AI coding skills globally. If they are already installed, this command does not update them.';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> <%= command.id %>',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> --yes',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> --json',
|
|
19
|
+
];
|
|
20
|
+
static flags = {
|
|
21
|
+
yes: Flags.boolean({
|
|
22
|
+
char: 'y',
|
|
23
|
+
description: 'Skip the install confirmation prompt',
|
|
24
|
+
default: false,
|
|
25
|
+
}),
|
|
26
|
+
json: Flags.boolean({
|
|
27
|
+
description: 'Output the result as JSON',
|
|
28
|
+
default: false,
|
|
29
|
+
}),
|
|
30
|
+
verbose: Flags.boolean({
|
|
31
|
+
description: 'Show detailed install output',
|
|
32
|
+
default: false,
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
async run() {
|
|
36
|
+
const { flags } = await this.parse(SkillsInstall);
|
|
37
|
+
setVerboseMode(flags.verbose);
|
|
38
|
+
if (!flags.yes) {
|
|
39
|
+
const confirmed = await confirmAction('Install the NocoBase AI coding skills globally?', { defaultValue: true });
|
|
40
|
+
if (!confirmed) {
|
|
41
|
+
this.log('Skipped skills install.');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const result = await installNocoBaseSkills({
|
|
46
|
+
verbose: flags.verbose,
|
|
47
|
+
});
|
|
48
|
+
if (flags.json) {
|
|
49
|
+
this.log(JSON.stringify({
|
|
50
|
+
ok: true,
|
|
51
|
+
kind: 'skills',
|
|
52
|
+
action: result.action,
|
|
53
|
+
globalRoot: result.status.globalRoot,
|
|
54
|
+
workspaceRoot: result.status.workspaceRoot,
|
|
55
|
+
installedSkillNames: result.status.installedSkillNames,
|
|
56
|
+
installedVersion: result.status.installedVersion,
|
|
57
|
+
installedRef: result.status.installedRef,
|
|
58
|
+
}, null, 2));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (result.action === 'noop') {
|
|
62
|
+
this.log(flags.verbose
|
|
63
|
+
? 'NocoBase AI coding skills are already installed globally. Run `nb skills update` to refresh them.'
|
|
64
|
+
: 'NocoBase AI coding skills are already installed globally.');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.log(flags.verbose
|
|
68
|
+
? 'Installed the NocoBase AI coding skills globally.'
|
|
69
|
+
: 'Installed NocoBase AI coding skills globally.');
|
|
70
|
+
}
|
|
71
|
+
}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* This file is part of the NocoBase (R) project.
|
|
3
|
+
* Copyright (c) 2020-2024 NocoBase Co., Ltd.
|
|
4
|
+
* Authors: NocoBase Team.
|
|
5
|
+
*
|
|
6
|
+
* This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
|
|
7
|
+
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
|
+
*/
|
|
9
|
+
import { Command, Flags } from '@oclif/core';
|
|
10
|
+
import { confirmAction, setVerboseMode } from '../../lib/ui.js';
|
|
11
|
+
import { updateNocoBaseSkills } from '../../lib/skills-manager.js';
|
|
12
|
+
export default class SkillsUpdate extends Command {
|
|
13
|
+
static summary = 'Update the globally installed NocoBase AI coding skills';
|
|
14
|
+
static description = 'Refresh the globally installed NocoBase AI coding skills. This command only updates an existing @nocobase/skills install.';
|
|
15
|
+
static examples = [
|
|
16
|
+
'<%= config.bin %> <%= command.id %>',
|
|
17
|
+
'<%= config.bin %> <%= command.id %> --yes',
|
|
18
|
+
'<%= config.bin %> <%= command.id %> --json',
|
|
19
|
+
];
|
|
20
|
+
static flags = {
|
|
21
|
+
yes: Flags.boolean({
|
|
22
|
+
char: 'y',
|
|
23
|
+
description: 'Skip the update confirmation prompt',
|
|
24
|
+
default: false,
|
|
25
|
+
}),
|
|
26
|
+
json: Flags.boolean({
|
|
27
|
+
description: 'Output the result as JSON',
|
|
28
|
+
default: false,
|
|
29
|
+
}),
|
|
30
|
+
verbose: Flags.boolean({
|
|
31
|
+
description: 'Show detailed update output',
|
|
32
|
+
default: false,
|
|
33
|
+
}),
|
|
34
|
+
};
|
|
35
|
+
async run() {
|
|
36
|
+
const { flags } = await this.parse(SkillsUpdate);
|
|
37
|
+
setVerboseMode(flags.verbose);
|
|
38
|
+
if (!flags.yes) {
|
|
39
|
+
const confirmed = await confirmAction('Update the globally installed NocoBase AI coding skills?', { defaultValue: true });
|
|
40
|
+
if (!confirmed) {
|
|
41
|
+
this.log('Skipped skills update.');
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
const result = await updateNocoBaseSkills({
|
|
46
|
+
verbose: flags.verbose,
|
|
47
|
+
});
|
|
48
|
+
if (flags.json) {
|
|
49
|
+
this.log(JSON.stringify({
|
|
50
|
+
ok: true,
|
|
51
|
+
kind: 'skills',
|
|
52
|
+
action: result.action,
|
|
53
|
+
globalRoot: result.status.globalRoot,
|
|
54
|
+
workspaceRoot: result.status.workspaceRoot,
|
|
55
|
+
installedSkillNames: result.status.installedSkillNames,
|
|
56
|
+
installedVersion: result.status.installedVersion,
|
|
57
|
+
installedRef: result.status.installedRef,
|
|
58
|
+
}, null, 2));
|
|
59
|
+
return;
|
|
60
|
+
}
|
|
61
|
+
if (result.action === 'noop') {
|
|
62
|
+
this.log(flags.verbose
|
|
63
|
+
? 'NocoBase AI coding skills are already up to date globally.'
|
|
64
|
+
: 'NocoBase AI coding skills are up to date.');
|
|
65
|
+
return;
|
|
66
|
+
}
|
|
67
|
+
this.log(flags.verbose
|
|
68
|
+
? 'Updated the global NocoBase AI coding skills.'
|
|
69
|
+
: 'Updated NocoBase AI coding skills globally.');
|
|
70
|
+
}
|
|
71
|
+
}
|
package/dist/commands/start.js
CHANGED
|
@@ -111,13 +111,20 @@ export default class Start extends Command {
|
|
|
111
111
|
if (!runtime) {
|
|
112
112
|
this.error(formatMissingManagedAppEnvMessage(requestedEnv));
|
|
113
113
|
}
|
|
114
|
-
if (runtime.kind === '
|
|
114
|
+
if (runtime.kind === 'http') {
|
|
115
115
|
this.error([
|
|
116
116
|
`Can't start "${runtime.envName}" from this machine.`,
|
|
117
117
|
'This env only has an API connection, so there is no saved local app or Docker runtime to launch here.',
|
|
118
118
|
'Connect it to a local checkout or reinstall it with npm, git, or Docker if you want CLI-managed start and stop.',
|
|
119
119
|
].join('\n'));
|
|
120
120
|
}
|
|
121
|
+
if (runtime.kind === 'ssh') {
|
|
122
|
+
this.error([
|
|
123
|
+
`Can't start "${runtime.envName}" yet.`,
|
|
124
|
+
'SSH env support is reserved but not implemented yet.',
|
|
125
|
+
'Use a local or Docker env if you need CLI-managed start and stop right now.',
|
|
126
|
+
].join('\n'));
|
|
127
|
+
}
|
|
121
128
|
if (runtime.kind === 'docker') {
|
|
122
129
|
const unsupportedFlags = [
|
|
123
130
|
flags.quickstart ? '--quickstart' : undefined,
|
package/dist/commands/stop.js
CHANGED
|
@@ -50,13 +50,20 @@ export default class Stop extends Command {
|
|
|
50
50
|
if (!runtime) {
|
|
51
51
|
this.error(formatMissingManagedAppEnvMessage(requestedEnv));
|
|
52
52
|
}
|
|
53
|
-
if (runtime.kind === '
|
|
53
|
+
if (runtime.kind === 'http') {
|
|
54
54
|
this.error([
|
|
55
55
|
`Can't stop "${runtime.envName}" from this machine.`,
|
|
56
56
|
'This env only has an API connection, so there is no saved local app or Docker runtime to stop here.',
|
|
57
57
|
'If the app is running on a server, stop it there or reconnect this env to a local runtime first.',
|
|
58
58
|
].join('\n'));
|
|
59
59
|
}
|
|
60
|
+
if (runtime.kind === 'ssh') {
|
|
61
|
+
this.error([
|
|
62
|
+
`Can't stop "${runtime.envName}" yet.`,
|
|
63
|
+
'SSH env support is reserved but not implemented yet.',
|
|
64
|
+
'Use a local or Docker env if you need CLI-managed stop right now.',
|
|
65
|
+
].join('\n'));
|
|
66
|
+
}
|
|
60
67
|
if (runtime.kind === 'docker') {
|
|
61
68
|
startTask(`Stopping NocoBase for "${runtime.envName}"...`);
|
|
62
69
|
try {
|