@nocobase/cli 2.1.0-beta.23 → 2.1.0-beta.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.
Files changed (61) hide show
  1. package/README.md +24 -0
  2. package/README.zh-CN.md +4 -0
  3. package/dist/commands/app/down.js +12 -6
  4. package/dist/commands/app/logs.js +2 -2
  5. package/dist/commands/app/start.js +2 -1
  6. package/dist/commands/app/stop.js +2 -1
  7. package/dist/commands/app/upgrade.js +116 -129
  8. package/dist/commands/config/delete.js +30 -0
  9. package/dist/commands/config/get.js +29 -0
  10. package/dist/commands/config/index.js +20 -0
  11. package/dist/commands/config/list.js +29 -0
  12. package/dist/commands/config/set.js +35 -0
  13. package/dist/commands/db/check.js +238 -0
  14. package/dist/commands/db/logs.js +2 -2
  15. package/dist/commands/db/shared.js +6 -5
  16. package/dist/commands/db/start.js +2 -1
  17. package/dist/commands/db/stop.js +2 -1
  18. package/dist/commands/env/info.js +6 -2
  19. package/dist/commands/env/shared.js +1 -1
  20. package/dist/commands/init.js +0 -1
  21. package/dist/commands/install.js +87 -35
  22. package/dist/commands/license/activate.js +360 -0
  23. package/dist/commands/license/env.js +94 -0
  24. package/dist/commands/license/generate-id.js +108 -0
  25. package/dist/commands/license/id.js +56 -0
  26. package/dist/commands/license/index.js +20 -0
  27. package/dist/commands/license/plugins/clean.js +101 -0
  28. package/dist/commands/license/plugins/index.js +20 -0
  29. package/dist/commands/license/plugins/list.js +50 -0
  30. package/dist/commands/license/plugins/shared.js +325 -0
  31. package/dist/commands/license/plugins/sync.js +269 -0
  32. package/dist/commands/license/shared.js +414 -0
  33. package/dist/commands/license/status.js +50 -0
  34. package/dist/commands/plugin/disable.js +2 -0
  35. package/dist/commands/plugin/enable.js +2 -0
  36. package/dist/commands/source/dev.js +2 -1
  37. package/dist/lib/api-client.js +74 -3
  38. package/dist/lib/app-managed-resources.js +10 -6
  39. package/dist/lib/app-runtime.js +29 -11
  40. package/dist/lib/auth-store.js +36 -68
  41. package/dist/lib/bootstrap.js +0 -4
  42. package/dist/lib/build-config.js +8 -0
  43. package/dist/lib/builtin-db.js +86 -0
  44. package/dist/lib/cli-config.js +176 -0
  45. package/dist/lib/cli-home.js +6 -21
  46. package/dist/lib/db-connection-check.js +178 -0
  47. package/dist/lib/env-config.js +7 -0
  48. package/dist/lib/generated-command.js +24 -3
  49. package/dist/lib/plugin-storage.js +127 -0
  50. package/dist/lib/prompt-validators.js +4 -4
  51. package/dist/lib/run-npm.js +53 -0
  52. package/dist/lib/runtime-env-vars.js +32 -0
  53. package/dist/lib/runtime-generator.js +89 -10
  54. package/dist/lib/self-manager.js +57 -2
  55. package/dist/lib/skills-manager.js +2 -2
  56. package/dist/lib/startup-update.js +85 -7
  57. package/dist/lib/ui.js +3 -0
  58. package/dist/locale/en-US.json +16 -13
  59. package/dist/locale/zh-CN.json +16 -13
  60. package/nocobase-ctl.config.json +82 -0
  61. package/package.json +16 -4
@@ -0,0 +1,29 @@
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 } from '@oclif/core';
10
+ import { listExplicitCliConfigValues, SUPPORTED_CLI_CONFIG_KEYS } from '../../lib/cli-config.js';
11
+ import { renderTable } from '../../lib/ui.js';
12
+ export default class ConfigList extends Command {
13
+ static summary = 'List explicitly configured CLI settings';
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %>',
16
+ ];
17
+ async run() {
18
+ await this.parse(ConfigList);
19
+ const values = await listExplicitCliConfigValues();
20
+ const rows = SUPPORTED_CLI_CONFIG_KEYS
21
+ .filter((key) => Boolean(values[key]))
22
+ .map((key) => [key, values[key] ?? '']);
23
+ if (!rows.length) {
24
+ this.log('No CLI config values are set.');
25
+ return;
26
+ }
27
+ this.log(renderTable(['Key', 'Value'], rows));
28
+ }
29
+ }
@@ -0,0 +1,35 @@
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 { Args, Command } from '@oclif/core';
10
+ import { assertSupportedCliConfigKey, setCliConfigValue } from '../../lib/cli-config.js';
11
+ export default class ConfigSet extends Command {
12
+ static summary = 'Set a CLI configuration value';
13
+ static description = 'Set a supported CLI configuration key. Supported keys: license.pkg-url, docker.network, docker.container-prefix.';
14
+ static examples = [
15
+ '<%= config.bin %> <%= command.id %> license.pkg-url https://pkg.nocobase.com/',
16
+ '<%= config.bin %> <%= command.id %> docker.network nocobase',
17
+ '<%= config.bin %> <%= command.id %> docker.container-prefix nb',
18
+ ];
19
+ static args = {
20
+ key: Args.string({
21
+ description: 'Configuration key',
22
+ required: true,
23
+ }),
24
+ value: Args.string({
25
+ description: 'Configuration value',
26
+ required: true,
27
+ }),
28
+ };
29
+ async run() {
30
+ const { args } = await this.parse(ConfigSet);
31
+ const key = assertSupportedCliConfigKey(args.key);
32
+ const value = await setCliConfigValue(key, args.value);
33
+ this.log(`${key}=${value}`);
34
+ }
35
+ }
@@ -0,0 +1,238 @@
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 { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime } from '../../lib/app-runtime.js';
11
+ import { resolveBuiltinDbConnection } from '../../lib/builtin-db.js';
12
+ import { checkExternalDbConnection, formatDbCheckAddress, readExternalDbConnectionConfig, } from "../../lib/db-connection-check.js";
13
+ import { commandOutput } from '../../lib/run-npm.js';
14
+ import { validateTcpPort } from "../../lib/prompt-validators.js";
15
+ const DEFAULT_DOCKER_REGISTRY = 'nocobase/nocobase';
16
+ const DEFAULT_DOCKER_VERSION = 'alpha';
17
+ function trimValue(value) {
18
+ const text = String(value ?? '').trim();
19
+ return text || undefined;
20
+ }
21
+ function resolveRequiredDbField(flagValue, envValue) {
22
+ return trimValue(flagValue) ?? trimValue(envValue);
23
+ }
24
+ function normalizeDockerPlatform(value) {
25
+ const text = trimValue(value);
26
+ if (!text || text === 'auto') {
27
+ return undefined;
28
+ }
29
+ if (text === 'linux/amd64' || text === 'linux/arm64') {
30
+ return text;
31
+ }
32
+ return undefined;
33
+ }
34
+ function formatMissingFieldsMessage(missing, hasEnv) {
35
+ return [
36
+ 'Missing database settings for connectivity check.',
37
+ `Required: ${missing.join(', ')}.`,
38
+ hasEnv
39
+ ? 'Pass `--env <name>` to reuse a saved env, or provide the missing `--db-*` flags explicitly.'
40
+ : 'Provide all required `--db-*` flags explicitly, or pass `--env <name>` to reuse a saved env.',
41
+ ].join('\n');
42
+ }
43
+ function resolveDbConfigFromFlags(flags, envConfig) {
44
+ return {
45
+ builtinDb: false,
46
+ dbDialect: resolveRequiredDbField(flags['db-dialect'], envConfig?.dbDialect),
47
+ dbHost: resolveRequiredDbField(flags['db-host'], envConfig?.dbHost),
48
+ dbPort: resolveRequiredDbField(flags['db-port'], envConfig?.dbPort),
49
+ dbDatabase: resolveRequiredDbField(flags['db-database'], envConfig?.dbDatabase),
50
+ dbUser: resolveRequiredDbField(flags['db-user'], envConfig?.dbUser),
51
+ dbPassword: flags['db-password'] !== undefined
52
+ ? String(flags['db-password'] ?? '')
53
+ : envConfig?.dbPassword !== undefined
54
+ ? String(envConfig.dbPassword ?? '')
55
+ : undefined,
56
+ };
57
+ }
58
+ function validateDbConfigOrThrow(command, dbConfig, hasEnv) {
59
+ const missing = [];
60
+ if (!dbConfig.dbDialect) {
61
+ missing.push('--db-dialect');
62
+ }
63
+ if (!dbConfig.dbHost) {
64
+ missing.push('--db-host');
65
+ }
66
+ if (!dbConfig.dbPort) {
67
+ missing.push('--db-port');
68
+ }
69
+ if (!dbConfig.dbDatabase) {
70
+ missing.push('--db-database');
71
+ }
72
+ if (!dbConfig.dbUser) {
73
+ missing.push('--db-user');
74
+ }
75
+ if (!dbConfig.dbPassword) {
76
+ missing.push('--db-password');
77
+ }
78
+ if (missing.length > 0) {
79
+ command.error(formatMissingFieldsMessage(missing, hasEnv));
80
+ }
81
+ const portError = validateTcpPort(dbConfig.dbPort);
82
+ if (portError) {
83
+ command.error(portError);
84
+ }
85
+ }
86
+ async function resolveDbCheckInput(command, flags) {
87
+ const envName = flags.env?.trim() || undefined;
88
+ if (!envName) {
89
+ const dbConfig = resolveDbConfigFromFlags(flags);
90
+ validateDbConfigOrThrow(command, dbConfig, false);
91
+ return {
92
+ dbConfig,
93
+ };
94
+ }
95
+ const runtime = await resolveManagedAppRuntime(envName);
96
+ if (!runtime) {
97
+ command.error(formatMissingManagedAppEnvMessage(envName));
98
+ }
99
+ const envConfig = { ...runtime.env.config };
100
+ if ((runtime.kind === 'local' || runtime.kind === 'docker') && runtime.env.config.builtinDb) {
101
+ const builtinDbConnection = await resolveBuiltinDbConnection(runtime);
102
+ envConfig.dbHost = builtinDbConnection.dbHost;
103
+ envConfig.dbPort = builtinDbConnection.dbPort;
104
+ envConfig.dbDialect = builtinDbConnection.dbDialect;
105
+ }
106
+ const dbConfig = resolveDbConfigFromFlags(flags, envConfig);
107
+ validateDbConfigOrThrow(command, dbConfig, true);
108
+ return {
109
+ envName: runtime.envName,
110
+ kind: runtime.kind,
111
+ runtime: runtime,
112
+ dbConfig,
113
+ };
114
+ }
115
+ function buildConnectionConfigOrThrow(command, dbConfig) {
116
+ const connectionConfig = readExternalDbConnectionConfig(dbConfig);
117
+ if (!connectionConfig) {
118
+ command.error('Unsupported or incomplete database settings for connectivity check.');
119
+ }
120
+ return connectionConfig;
121
+ }
122
+ async function runExplicitDbCheck(command, dbConfig) {
123
+ const connectionConfig = buildConnectionConfigOrThrow(command, dbConfig);
124
+ const address = formatDbCheckAddress(connectionConfig);
125
+ const validationError = await checkExternalDbConnection(connectionConfig);
126
+ return {
127
+ ok: !validationError,
128
+ dialect: connectionConfig.dialect,
129
+ address,
130
+ error: validationError ?? null,
131
+ };
132
+ }
133
+ async function runDockerDbCheck(command, runtime, dbConfig) {
134
+ const connectionConfig = buildConnectionConfigOrThrow(command, dbConfig);
135
+ const config = runtime.env.config ?? {};
136
+ const imageRef = `${trimValue(config.dockerRegistry) || DEFAULT_DOCKER_REGISTRY}:${trimValue(config.downloadVersion) || DEFAULT_DOCKER_VERSION}`;
137
+ const args = [
138
+ 'run',
139
+ '--rm',
140
+ '--network',
141
+ runtime.dockerNetworkName || runtime.workspaceName,
142
+ ];
143
+ const dockerPlatform = normalizeDockerPlatform(config.dockerPlatform);
144
+ if (dockerPlatform) {
145
+ args.push('--platform', dockerPlatform);
146
+ }
147
+ args.push('--entrypoint', 'nb', imageRef, 'db', 'check', '--db-dialect', connectionConfig.dialect, '--db-host', connectionConfig.host, '--db-port', String(connectionConfig.port), '--db-database', connectionConfig.database, '--db-user', connectionConfig.user, '--db-password', connectionConfig.password, '--json');
148
+ const output = await commandOutput('docker', args, {
149
+ errorName: 'docker run',
150
+ });
151
+ let payload;
152
+ try {
153
+ payload = JSON.parse(output);
154
+ }
155
+ catch {
156
+ command.error(`Failed to parse database check response from Docker: ${output}`);
157
+ }
158
+ const ok = Boolean(payload.ok);
159
+ const dialect = trimValue(payload.dialect) || connectionConfig.dialect;
160
+ const address = trimValue(payload.address) || formatDbCheckAddress(connectionConfig);
161
+ const error = trimValue(payload.error) || null;
162
+ return {
163
+ ok,
164
+ dialect,
165
+ address,
166
+ error,
167
+ };
168
+ }
169
+ async function runDbCheckForRuntime(command, runtime, dbConfig) {
170
+ if (runtime.kind === 'docker') {
171
+ return await runDockerDbCheck(command, runtime, dbConfig);
172
+ }
173
+ if (runtime.kind === 'local') {
174
+ return await runExplicitDbCheck(command, dbConfig);
175
+ }
176
+ command.error(`Env "${runtime.envName}" does not support automatic database connectivity checks.`);
177
+ }
178
+ export default class DbCheck extends Command {
179
+ static description = 'Check whether a database is reachable using the selected env settings or explicit `--db-*` flags.';
180
+ static examples = [
181
+ '<%= config.bin %> <%= command.id %> --env app1',
182
+ '<%= config.bin %> <%= command.id %> --env app1 --db-password new-secret --json',
183
+ '<%= config.bin %> <%= command.id %> --db-dialect postgres --db-host 127.0.0.1 --db-port 5432 --db-database nocobase --db-user nocobase --db-password secret',
184
+ ];
185
+ static flags = {
186
+ env: Flags.string({
187
+ char: 'e',
188
+ description: 'CLI env name to read saved database settings from. Defaults to the current env when omitted.',
189
+ }),
190
+ 'db-dialect': Flags.string({
191
+ description: 'Database dialect: postgres, kingbase, mysql, or mariadb.',
192
+ options: ['postgres', 'kingbase', 'mysql', 'mariadb'],
193
+ }),
194
+ 'db-host': Flags.string({
195
+ description: 'Database host name or IP address.',
196
+ }),
197
+ 'db-port': Flags.string({
198
+ description: 'Database TCP port.',
199
+ }),
200
+ 'db-database': Flags.string({
201
+ description: 'Database name.',
202
+ }),
203
+ 'db-user': Flags.string({
204
+ description: 'Database username.',
205
+ }),
206
+ 'db-password': Flags.string({
207
+ description: 'Database password.',
208
+ }),
209
+ json: Flags.boolean({
210
+ description: 'Output the check result as JSON.',
211
+ default: false,
212
+ }),
213
+ };
214
+ async run() {
215
+ const { flags } = await this.parse(DbCheck);
216
+ const input = await resolveDbCheckInput(this, flags);
217
+ const result = input.runtime
218
+ ? await runDbCheckForRuntime(this, input.runtime, input.dbConfig)
219
+ : await runExplicitDbCheck(this, input.dbConfig);
220
+ if (flags.json) {
221
+ this.log(JSON.stringify({
222
+ ok: result.ok,
223
+ env: input.envName,
224
+ kind: input.kind,
225
+ dialect: result.dialect,
226
+ address: result.address,
227
+ error: result.error,
228
+ }, null, 2));
229
+ return;
230
+ }
231
+ if (!result.ok) {
232
+ this.error(result.error ?? 'Database check failed.');
233
+ }
234
+ this.log(input.envName
235
+ ? `Database check passed for env "${input.envName}" (${result.dialect} ${result.address}).`
236
+ : `Database check passed (${result.dialect} ${result.address}).`);
237
+ }
238
+ }
@@ -47,7 +47,7 @@ export default class DbLogs extends Command {
47
47
  follow: Flags.boolean({
48
48
  char: 'f',
49
49
  description: 'Keep streaming new log lines',
50
- default: true,
50
+ default: false,
51
51
  allowNo: true,
52
52
  }),
53
53
  };
@@ -62,7 +62,7 @@ export default class DbLogs extends Command {
62
62
  this.error(formatUnmanagedDbLogsMessage(runtime));
63
63
  }
64
64
  const tail = String(flags.tail ?? 100);
65
- const follow = flags.follow !== false;
65
+ const follow = flags.follow === true;
66
66
  printInfo(follow
67
67
  ? `Showing built-in database logs for "${runtime.envName}" (press Ctrl+C to stop).`
68
68
  : `Showing recent built-in database logs for "${runtime.envName}".`);
@@ -6,7 +6,8 @@
6
6
  * This project is dual-licensed under AGPL-3.0 and NocoBase Commercial License.
7
7
  * For more information, please refer to: https://www.nocobase.com/agreement.
8
8
  */
9
- import { buildDockerDbContainerName, dockerContainerExists, dockerContainerIsRunning, resolveManagedAppRuntime, } from '../../lib/app-runtime.js';
9
+ import { dockerContainerExists, dockerContainerIsRunning, resolveManagedAppRuntime, } from '../../lib/app-runtime.js';
10
+ import { resolveBuiltinDbConnection } from '../../lib/builtin-db.js';
10
11
  function formatAddress(host, port, fallbackHost) {
11
12
  const normalizedHost = String(host ?? '').trim() || String(fallbackHost ?? '').trim();
12
13
  const normalizedPort = String(port ?? '').trim();
@@ -23,14 +24,14 @@ export async function resolveDbRuntime(envName) {
23
24
  const source = runtime.kind === 'http' || runtime.kind === 'ssh' ? runtime.kind : runtime.source;
24
25
  const dbDialect = String(runtime.env.config.dbDialect ?? 'postgres').trim() || 'postgres';
25
26
  if ((runtime.kind === 'local' || runtime.kind === 'docker') && runtime.env.config.builtinDb) {
26
- const containerName = buildDockerDbContainerName(runtime.envName, dbDialect, runtime.workspaceName);
27
+ const connection = await resolveBuiltinDbConnection(runtime);
27
28
  return {
28
29
  kind: 'builtin',
29
30
  envName: runtime.envName,
30
31
  source,
31
- dbDialect,
32
- containerName,
33
- address: formatAddress(runtime.env.config.dbHost, runtime.env.config.dbPort, containerName),
32
+ dbDialect: connection.dbDialect,
33
+ containerName: connection.containerName,
34
+ address: formatAddress(connection.dbHost, connection.dbPort, connection.containerName),
34
35
  appRuntime: runtime,
35
36
  };
36
37
  }
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
10
  import { formatMissingManagedAppEnvMessage, startDockerContainer, } from '../../lib/app-runtime.js';
11
- import { failTask, startTask, succeedTask } from '../../lib/ui.js';
11
+ import { announceTargetEnv, failTask, startTask, succeedTask } from '../../lib/ui.js';
12
12
  import { formatUnmanagedDbMessage, resolveDbRuntime } from './shared.js';
13
13
  function formatDbStartFailure(envName, message) {
14
14
  if (/does not exist/i.test(message)) {
@@ -52,6 +52,7 @@ export default class DbStart extends Command {
52
52
  if (runtime.kind !== 'builtin') {
53
53
  this.error(formatUnmanagedDbMessage('start', runtime));
54
54
  }
55
+ announceTargetEnv(runtime.envName);
55
56
  startTask(`Starting the built-in database for "${runtime.envName}"...`);
56
57
  try {
57
58
  const state = await startDockerContainer(runtime.containerName, {
@@ -8,7 +8,7 @@
8
8
  */
9
9
  import { Command, Flags } from '@oclif/core';
10
10
  import { formatMissingManagedAppEnvMessage, stopDockerContainer, } from '../../lib/app-runtime.js';
11
- import { failTask, startTask, succeedTask } from '../../lib/ui.js';
11
+ import { announceTargetEnv, failTask, startTask, succeedTask } from '../../lib/ui.js';
12
12
  import { formatUnmanagedDbMessage, resolveDbRuntime } from './shared.js';
13
13
  function formatDbStopFailure(envName, message) {
14
14
  if (/does not exist/i.test(message)) {
@@ -52,6 +52,7 @@ export default class DbStop extends Command {
52
52
  if (runtime.kind !== 'builtin') {
53
53
  this.error(formatUnmanagedDbMessage('stop', runtime));
54
54
  }
55
+ announceTargetEnv(runtime.envName);
55
56
  startTask(`Stopping the built-in database for "${runtime.envName}"...`);
56
57
  try {
57
58
  const state = await stopDockerContainer(runtime.containerName, {
@@ -8,6 +8,7 @@
8
8
  */
9
9
  import { Args, Command, Flags } from '@oclif/core';
10
10
  import { formatMissingManagedAppEnvMessage, resolveManagedAppRuntime } from '../../lib/app-runtime.js';
11
+ import { resolveBuiltinDbConnection } from '../../lib/builtin-db.js';
11
12
  import { renderTable } from '../../lib/ui.js';
12
13
  import { appRootPath, dbStatus, runtimeStatus, storagePath } from './shared.js';
13
14
  function normalizeJsonValue(value) {
@@ -85,6 +86,9 @@ export default class EnvInfo extends Command {
85
86
  this.error(formatMissingManagedAppEnvMessage(requestedEnv));
86
87
  }
87
88
  const auth = runtime.env.auth;
89
+ const builtinDbConnection = (runtime.kind === 'local' || runtime.kind === 'docker') && runtime.env.config.builtinDb
90
+ ? await resolveBuiltinDbConnection(runtime)
91
+ : undefined;
88
92
  const appGroup = {
89
93
  appRootPath: appRootPath(runtime),
90
94
  storagePath: storagePath(runtime),
@@ -101,8 +105,8 @@ export default class EnvInfo extends Command {
101
105
  builtinDb: runtime.env.config.builtinDb,
102
106
  dbDialect: runtime.env.config.dbDialect,
103
107
  builtinDbImage: runtime.env.config.builtinDbImage,
104
- dbHost: runtime.env.config.dbHost,
105
- dbPort: runtime.env.config.dbPort,
108
+ dbHost: builtinDbConnection?.dbHost ?? runtime.env.config.dbHost,
109
+ dbPort: builtinDbConnection?.dbPort ?? runtime.env.config.dbPort,
106
110
  dbDatabase: runtime.env.config.dbDatabase,
107
111
  dbUser: runtime.env.config.dbUser,
108
112
  dbPassword: maskSecret(runtime.env.config.dbPassword, showSecrets),
@@ -141,7 +141,7 @@ export async function dbStatus(runtime) {
141
141
  return '-';
142
142
  }
143
143
  const dbDialect = String(runtime.env.config.dbDialect ?? 'postgres').trim() || 'postgres';
144
- const containerName = buildDockerDbContainerName(runtime.envName, dbDialect, runtime.workspaceName);
144
+ const containerName = buildDockerDbContainerName(runtime.envName, dbDialect, runtime.dockerContainerPrefix || runtime.workspaceName);
145
145
  return await dockerStatus(containerName);
146
146
  }
147
147
  export async function runtimeStatus(runtime) {
@@ -303,7 +303,6 @@ Prompt modes:
303
303
  }),
304
304
  'skip-skills': Flags.boolean({
305
305
  description: 'Skip installing or updating NocoBase AI coding skills during init',
306
- hidden: true,
307
306
  default: false,
308
307
  }),
309
308
  'ui-host': Flags.string({