@nocobase/cli 2.1.0-alpha.35 → 2.1.0-alpha.36
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/commands/app/down.js +10 -13
- package/dist/commands/app/logs.js +0 -1
- package/dist/commands/app/restart.js +0 -1
- package/dist/commands/app/start.js +0 -1
- package/dist/commands/app/stop.js +0 -1
- package/dist/commands/app/upgrade.js +0 -1
- package/dist/commands/env/add.js +3 -4
- package/dist/commands/env/auth.js +3 -2
- package/dist/commands/env/remove.js +38 -13
- package/dist/commands/env/update.js +9 -2
- package/dist/commands/examples/prompts-stages.js +4 -4
- package/dist/commands/examples/prompts-test.js +4 -4
- package/dist/commands/init.js +38 -31
- package/dist/commands/install.js +89 -61
- package/dist/commands/license/activate.js +66 -64
- package/dist/commands/license/id.js +0 -1
- package/dist/commands/license/plugins/clean.js +0 -1
- package/dist/commands/license/plugins/list.js +0 -1
- package/dist/commands/license/plugins/sync.js +0 -1
- package/dist/commands/license/shared.js +3 -3
- package/dist/commands/license/status.js +0 -1
- package/dist/commands/plugin/disable.js +0 -1
- package/dist/commands/plugin/enable.js +0 -1
- package/dist/commands/plugin/list.js +0 -1
- package/dist/commands/self/update.js +12 -3
- package/dist/commands/skills/install.js +12 -3
- package/dist/commands/skills/remove.js +12 -3
- package/dist/commands/skills/update.js +12 -3
- package/dist/commands/source/dev.js +0 -1
- package/dist/commands/source/download.js +29 -17
- package/dist/lib/bootstrap.js +12 -3
- package/dist/lib/db-connection-check.js +3 -23
- package/dist/lib/env-auth.js +4 -3
- package/dist/lib/env-guard.js +8 -7
- package/dist/lib/generated-command.js +0 -1
- package/dist/lib/inquirer-theme.js +17 -0
- package/dist/lib/inquirer.js +244 -0
- package/dist/lib/object-utils.js +76 -0
- package/dist/lib/prompt-catalog-core.js +185 -0
- package/dist/lib/prompt-catalog-terminal.js +375 -0
- package/dist/lib/prompt-catalog.js +2 -573
- package/dist/lib/prompt-validators.js +56 -1
- package/dist/lib/resource-command.js +0 -1
- package/dist/lib/skills-manager.js +75 -11
- package/dist/lib/startup-update.js +12 -8
- package/dist/lib/ui.js +28 -51
- package/dist/locale/en-US.json +8 -3
- package/dist/locale/zh-CN.json +8 -3
- package/dist/post-processors/data-modeling.js +25 -7
- package/dist/post-processors/data-source-manager.js +24 -0
- package/nocobase-ctl.config.json +20 -1
- package/package.json +7 -5
|
@@ -6,7 +6,6 @@
|
|
|
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 * as p from '@clack/prompts';
|
|
10
9
|
import { Command, Flags } from '@oclif/core';
|
|
11
10
|
import fsp from 'node:fs/promises';
|
|
12
11
|
import os from 'node:os';
|
|
@@ -15,6 +14,7 @@ import { buildDockerDbContainerName, formatMissingManagedAppEnvMessage, resolveM
|
|
|
15
14
|
import { getCurrentEnvName, removeEnv } from '../../lib/auth-store.js';
|
|
16
15
|
import { resolveConfiguredEnvPath } from '../../lib/cli-home.js';
|
|
17
16
|
import { ensureCrossEnvConfirmed, hasExplicitEnvSelection } from '../../lib/env-guard.js';
|
|
17
|
+
import { confirm } from "../../lib/inquirer.js";
|
|
18
18
|
import { commandOutput, commandSucceeds, run } from '../../lib/run-npm.js';
|
|
19
19
|
import { failTask, isInteractiveTerminal, printInfo, startTask, succeedTask, } from '../../lib/ui.js';
|
|
20
20
|
function resolveConfiguredPath(value) {
|
|
@@ -109,19 +109,17 @@ async function confirmDownAll(envName, force, options) {
|
|
|
109
109
|
}
|
|
110
110
|
throw new Error(`\`nb app down --all\` needs confirmation. Re-run with --force to delete everything for "${envName}" in non-interactive mode.`);
|
|
111
111
|
}
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
p.cancel('Down cancelled.');
|
|
112
|
+
try {
|
|
113
|
+
return await confirm({
|
|
114
|
+
message: usedCurrentEnv
|
|
115
|
+
? `Delete everything for current env "${envName}"? This removes the app, managed containers, storage data, and the saved CLI env config.`
|
|
116
|
+
: `Delete everything for "${envName}"? This removes the app, managed containers, storage data, and the saved CLI env config.`,
|
|
117
|
+
default: false,
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
catch {
|
|
122
121
|
return false;
|
|
123
122
|
}
|
|
124
|
-
return answer;
|
|
125
123
|
}
|
|
126
124
|
function formatDownCrossEnvForceRequiredMessage(currentEnv, requestedEnv) {
|
|
127
125
|
return [
|
|
@@ -191,7 +189,6 @@ export default class AppDown extends Command {
|
|
|
191
189
|
yes: flags.yes,
|
|
192
190
|
});
|
|
193
191
|
if (!confirmed) {
|
|
194
|
-
this.log('Canceled.');
|
|
195
192
|
return;
|
|
196
193
|
}
|
|
197
194
|
}
|
package/dist/commands/env/add.js
CHANGED
|
@@ -13,8 +13,7 @@ import { buildStoredEnvConfig, } from '../../lib/env-config.js';
|
|
|
13
13
|
import { runPromptCatalog, } from '../../lib/prompt-catalog.js';
|
|
14
14
|
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, localeText, } from '../../lib/cli-locale.js';
|
|
15
15
|
import { validateApiBaseUrl } from '../../lib/prompt-validators.js';
|
|
16
|
-
import { printVerbose, setVerboseMode } from '../../lib/ui.js';
|
|
17
|
-
import * as p from '@clack/prompts';
|
|
16
|
+
import { printStage, printSuccess, printVerbose, setVerboseMode } from '../../lib/ui.js';
|
|
18
17
|
const ENV_RUNTIME_FLAG_MAP = {
|
|
19
18
|
source: 'source',
|
|
20
19
|
'download-version': 'downloadVersion',
|
|
@@ -292,7 +291,7 @@ export default class EnvAdd extends Command {
|
|
|
292
291
|
applyCliLocale(parsedFlags.locale);
|
|
293
292
|
setVerboseMode(parsedFlags.verbose);
|
|
294
293
|
if (!parsedFlags['no-intro']) {
|
|
295
|
-
|
|
294
|
+
printStage('Connect to NocoBase');
|
|
296
295
|
}
|
|
297
296
|
const results = await runPromptCatalog(EnvAdd.prompts, {
|
|
298
297
|
values: this.buildPromptValues(args.name, parsedFlags),
|
|
@@ -308,6 +307,6 @@ export default class EnvAdd extends Command {
|
|
|
308
307
|
await this.config.runCommand('env:auth', [envName]);
|
|
309
308
|
}
|
|
310
309
|
await this.config.runCommand('env:update', [envName]);
|
|
311
|
-
|
|
310
|
+
printSuccess(`✔ Env "${envName}" is ready.`);
|
|
312
311
|
}
|
|
313
312
|
}
|
|
@@ -10,7 +10,7 @@ import { Args, Command, Flags } from '@oclif/core';
|
|
|
10
10
|
import { getCurrentEnvName } from '../../lib/auth-store.js';
|
|
11
11
|
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
12
12
|
import { authenticateEnvWithOauth } from '../../lib/env-auth.js';
|
|
13
|
-
import { failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
13
|
+
import { failTask, printStage, startTask, succeedTask } from '../../lib/ui.js';
|
|
14
14
|
export default class EnvAuth extends Command {
|
|
15
15
|
static summary = 'Sign in to a saved NocoBase environment with OAuth';
|
|
16
16
|
static examples = [
|
|
@@ -39,13 +39,14 @@ export default class EnvAuth extends Command {
|
|
|
39
39
|
this.error(`Environment name was provided both as the argument ("${nameArg}") and as --env ("${nameFlag}"). Please use only one.`);
|
|
40
40
|
}
|
|
41
41
|
const envName = nameArg || nameFlag || (await getCurrentEnvName({ scope: resolveDefaultConfigScope() }));
|
|
42
|
+
printStage('Signing in');
|
|
42
43
|
startTask(`Starting browser sign-in for "${envName}"...`);
|
|
43
44
|
try {
|
|
44
45
|
await authenticateEnvWithOauth({
|
|
45
46
|
envName,
|
|
46
47
|
scope: resolveDefaultConfigScope(),
|
|
47
48
|
});
|
|
48
|
-
succeedTask(
|
|
49
|
+
succeedTask(`✔ Signed in to "${envName}".`);
|
|
49
50
|
}
|
|
50
51
|
catch (error) {
|
|
51
52
|
failTask(`Sign-in failed for "${envName}".`);
|
|
@@ -7,19 +7,26 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
10
|
-
import { getCurrentEnvName, removeEnv } from '../../lib/auth-store.js';
|
|
10
|
+
import { getCurrentEnvName, loadAuthConfig, removeEnv } from '../../lib/auth-store.js';
|
|
11
11
|
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
12
|
-
import {
|
|
12
|
+
import { confirm } from "../../lib/inquirer.js";
|
|
13
|
+
import { isInteractiveTerminal, printVerbose, setVerboseMode } from '../../lib/ui.js';
|
|
13
14
|
export default class EnvRemove extends Command {
|
|
14
15
|
static summary = 'Remove a configured environment';
|
|
16
|
+
static description = 'Remove the saved CLI env config for an environment. This command does not clean local app files, containers, or storage data.';
|
|
15
17
|
static examples = [
|
|
16
18
|
'<%= config.bin %> <%= command.id %> staging',
|
|
17
|
-
'<%= config.bin %> <%= command.id %> staging
|
|
19
|
+
'<%= config.bin %> <%= command.id %> staging --yes',
|
|
18
20
|
];
|
|
19
21
|
static flags = {
|
|
22
|
+
yes: Flags.boolean({
|
|
23
|
+
char: 'y',
|
|
24
|
+
description: 'Skip confirmation and remove the saved CLI env config',
|
|
25
|
+
default: false,
|
|
26
|
+
}),
|
|
20
27
|
force: Flags.boolean({
|
|
21
28
|
char: 'f',
|
|
22
|
-
|
|
29
|
+
hidden: true,
|
|
23
30
|
default: false,
|
|
24
31
|
}),
|
|
25
32
|
verbose: Flags.boolean({
|
|
@@ -36,24 +43,42 @@ export default class EnvRemove extends Command {
|
|
|
36
43
|
async run() {
|
|
37
44
|
const { args, flags } = await this.parse(EnvRemove);
|
|
38
45
|
setVerboseMode(flags.verbose);
|
|
39
|
-
const
|
|
40
|
-
|
|
46
|
+
const scope = resolveDefaultConfigScope();
|
|
47
|
+
const config = await loadAuthConfig({ scope });
|
|
48
|
+
if (!config.envs[args.name]) {
|
|
49
|
+
this.error(`Env "${args.name}" is not configured`);
|
|
50
|
+
}
|
|
51
|
+
const currentEnv = await getCurrentEnvName({ scope });
|
|
52
|
+
const skipConfirmation = flags.yes || flags.force;
|
|
53
|
+
if (!skipConfirmation) {
|
|
41
54
|
if (!isInteractiveTerminal()) {
|
|
42
|
-
this.error(
|
|
55
|
+
this.error(`Refusing to remove env "${args.name}" without confirmation in non-interactive mode. Re-run with \`--yes\` to remove only the saved CLI env config.`);
|
|
56
|
+
}
|
|
57
|
+
const subject = args.name === currentEnv ? `current env "${args.name}"` : `env "${args.name}"`;
|
|
58
|
+
let confirmed = false;
|
|
59
|
+
try {
|
|
60
|
+
confirmed = await confirm({
|
|
61
|
+
message: `Remove ${subject}? Only the saved CLI env config will be removed.`,
|
|
62
|
+
default: false,
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return;
|
|
43
67
|
}
|
|
44
|
-
const confirmed = await confirmAction(`Remove current env "${args.name}"?`, { defaultValue: false });
|
|
45
68
|
if (!confirmed) {
|
|
46
|
-
this.log('Canceled.');
|
|
47
69
|
return;
|
|
48
70
|
}
|
|
49
71
|
}
|
|
50
72
|
printVerbose(`Removing env "${args.name}"`);
|
|
51
|
-
const result = await removeEnv(args.name, { scope
|
|
52
|
-
this.log(`Removed env "${result.removed}".`);
|
|
73
|
+
const result = await removeEnv(args.name, { scope });
|
|
53
74
|
if (result.hasEnvs) {
|
|
54
|
-
|
|
75
|
+
if (args.name === currentEnv) {
|
|
76
|
+
this.log(`Removed env "${result.removed}". Switched current env to "${await getCurrentEnvName({ scope })}".`);
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
this.log(`Removed env "${result.removed}".`);
|
|
55
80
|
return;
|
|
56
81
|
}
|
|
57
|
-
this.log(
|
|
82
|
+
this.log(`Removed env "${result.removed}". No envs configured.`);
|
|
58
83
|
}
|
|
59
84
|
}
|
|
@@ -12,7 +12,7 @@ import { Args, Command, Flags } from '@oclif/core';
|
|
|
12
12
|
import { getCurrentEnvName } from '../../lib/auth-store.js';
|
|
13
13
|
import { updateEnvRuntime } from '../../lib/bootstrap.js';
|
|
14
14
|
import { resolveDefaultConfigScope } from '../../lib/cli-home.js';
|
|
15
|
-
import { failTask, startTask, succeedTask } from '../../lib/ui.js';
|
|
15
|
+
import { failTask, printVerbose, setVerboseMode, startTask, stopTask, succeedTask } from '../../lib/ui.js';
|
|
16
16
|
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
17
17
|
export default class EnvUpdate extends Command {
|
|
18
18
|
static summary = 'Refresh an environment runtime from swagger:get and persist connection overrides';
|
|
@@ -44,6 +44,7 @@ export default class EnvUpdate extends Command {
|
|
|
44
44
|
};
|
|
45
45
|
async run() {
|
|
46
46
|
const { args, flags } = await this.parse(EnvUpdate);
|
|
47
|
+
setVerboseMode(Boolean(flags.verbose));
|
|
47
48
|
const envName = args.name;
|
|
48
49
|
const envLabel = envName ?? (await getCurrentEnvName({ scope: resolveDefaultConfigScope() }));
|
|
49
50
|
startTask(`Updating env runtime: ${envLabel}`);
|
|
@@ -57,7 +58,13 @@ export default class EnvUpdate extends Command {
|
|
|
57
58
|
configFile: path.join(path.dirname(path.dirname(path.dirname(__dirname))), 'nocobase-ctl.config.json'),
|
|
58
59
|
verbose: flags.verbose,
|
|
59
60
|
});
|
|
60
|
-
|
|
61
|
+
if (flags.verbose) {
|
|
62
|
+
succeedTask(`Updated env "${envLabel}" to runtime "${runtime.version}".`);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
stopTask();
|
|
66
|
+
printVerbose(`Updated env "${envLabel}" to runtime "${runtime.version}".`);
|
|
67
|
+
}
|
|
61
68
|
}
|
|
62
69
|
catch (error) {
|
|
63
70
|
failTask(`Failed to update env "${envLabel}".`);
|
|
@@ -44,8 +44,8 @@ function buildWebUiStagesFromTestPrompts(c) {
|
|
|
44
44
|
}
|
|
45
45
|
/**
|
|
46
46
|
* With `--ui`: `runPromptCatalogWebUI` using `stages` + `sectionTitle`, then
|
|
47
|
-
* `runPromptCatalog` on the same catalog as `prompts-test`. Without `--ui`, same terminal
|
|
48
|
-
* as `prompts-test` (handy for comparing).
|
|
47
|
+
* `runPromptCatalog` on the same catalog as `prompts-test`. Without `--ui`, the same terminal prompt
|
|
48
|
+
* behavior as `prompts-test` (handy for comparing).
|
|
49
49
|
*/
|
|
50
50
|
export default class PromptsStages extends Command {
|
|
51
51
|
static hidden = true;
|
|
@@ -60,12 +60,12 @@ export default class PromptsStages extends Command {
|
|
|
60
60
|
];
|
|
61
61
|
static flags = {
|
|
62
62
|
ui: Flags.boolean({
|
|
63
|
-
description: 'Open the localhost form: `runPromptCatalogWebUI` with `stages` and `sectionTitle` (vs `prompts-test --ui`, which uses one `catalog`). Without --ui, behavior matches `prompts-test` (
|
|
63
|
+
description: 'Open the localhost form: `runPromptCatalogWebUI` with `stages` and `sectionTitle` (vs `prompts-test --ui`, which uses one `catalog`). Without --ui, behavior matches `prompts-test` (terminal prompt layer in TTY / presets).',
|
|
64
64
|
default: false,
|
|
65
65
|
}),
|
|
66
66
|
yes: Flags.boolean({
|
|
67
67
|
char: 'y',
|
|
68
|
-
description: 'Accept defaults only in the terminal (no
|
|
68
|
+
description: 'Accept defaults only in the terminal (no extra interactive prompts after submit); same semantics as `prompts-test` when used with the submitted or default preset.',
|
|
69
69
|
default: false,
|
|
70
70
|
}),
|
|
71
71
|
locale: Flags.string({
|
|
@@ -6,10 +6,10 @@
|
|
|
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 * as p from '@clack/prompts';
|
|
10
9
|
import { Args, Command, Flags } from '@oclif/core';
|
|
11
10
|
import { runPromptCatalog, } from "../../lib/prompt-catalog.js";
|
|
12
11
|
import { applyCliLocale, CLI_LOCALE_FLAG_DESCRIPTION, CLI_LOCALE_FLAG_OPTIONS, } from "../../lib/cli-locale.js";
|
|
12
|
+
import { printInfo } from "../../lib/ui.js";
|
|
13
13
|
import { runPromptCatalogWebUI, } from "../../lib/prompt-web-ui.js";
|
|
14
14
|
export default class PromptsTest extends Command {
|
|
15
15
|
static hidden = true;
|
|
@@ -84,7 +84,7 @@ export default class PromptsTest extends Command {
|
|
|
84
84
|
initialValue: 'world',
|
|
85
85
|
placeholder: 'Your name',
|
|
86
86
|
/**
|
|
87
|
-
* Example: async validation (
|
|
87
|
+
* Example: async validation (the terminal prompt layer re-prompts; Web UI returns 400 on submit with this message).
|
|
88
88
|
*/
|
|
89
89
|
validate: async (v) => {
|
|
90
90
|
if (String(v).trim().length < 2) {
|
|
@@ -109,7 +109,7 @@ export default class PromptsTest extends Command {
|
|
|
109
109
|
type: 'run',
|
|
110
110
|
when: (values) => values.select === 'option1',
|
|
111
111
|
run: (values) => {
|
|
112
|
-
|
|
112
|
+
printInfo(`run block: select is option1 (current keys: ${Object.keys(values).join(', ')})`);
|
|
113
113
|
},
|
|
114
114
|
},
|
|
115
115
|
password: {
|
|
@@ -154,7 +154,7 @@ export default class PromptsTest extends Command {
|
|
|
154
154
|
});
|
|
155
155
|
this.log(JSON.stringify(results, null, 2));
|
|
156
156
|
}
|
|
157
|
-
/** Map oclif parse result into `values` presets: each key here skips that prompt (no
|
|
157
|
+
/** Map oclif parse result into `values` presets: each key here skips that prompt (no terminal prompt UI). */
|
|
158
158
|
buildPresetValuesFromParsed(args, flags) {
|
|
159
159
|
const preset = {};
|
|
160
160
|
const file = args.file ?? flags.file;
|
package/dist/commands/init.js
CHANGED
|
@@ -7,7 +7,6 @@
|
|
|
7
7
|
* For more information, please refer to: https://www.nocobase.com/agreement.
|
|
8
8
|
*/
|
|
9
9
|
import { Command, Flags } from '@oclif/core';
|
|
10
|
-
import * as p from '@clack/prompts';
|
|
11
10
|
import pc from 'picocolors';
|
|
12
11
|
import { existsSync } from 'node:fs';
|
|
13
12
|
import path from 'node:path';
|
|
@@ -19,10 +18,11 @@ import { resolveDefaultConfigScope } from '../lib/cli-home.js';
|
|
|
19
18
|
import { runPromptCatalogWebUI, } from "../lib/prompt-web-ui.js";
|
|
20
19
|
import { validateApiBaseUrl, validateEnvKey } from "../lib/prompt-validators.js";
|
|
21
20
|
import { inspectSkillsStatus, installNocoBaseSkills, updateNocoBaseSkills, } from '../lib/skills-manager.js';
|
|
21
|
+
import { omitKeys, pickKeys } from "../lib/object-utils.js";
|
|
22
|
+
import { printInfo, printStage, printVerbose, printWarning } from '../lib/ui.js';
|
|
22
23
|
import Download from "./download.js";
|
|
23
24
|
import EnvAdd from "./env/add.js";
|
|
24
25
|
import Install, { defaultDbPortForDialect } from "./install.js";
|
|
25
|
-
import _ from 'lodash';
|
|
26
26
|
const DEFAULT_INIT_API_BASE_URL = 'http://localhost:13000/api';
|
|
27
27
|
const DEFAULT_INIT_APP_NAME = 'local';
|
|
28
28
|
const DOWNLOAD_OUTPUT_DIR_PROMPT = Download.prompts.outputDir;
|
|
@@ -129,15 +129,18 @@ function shellQuoteArg(value) {
|
|
|
129
129
|
: `'${value.replace(/'/g, `'\\''`)}'`;
|
|
130
130
|
}
|
|
131
131
|
function initTitle() {
|
|
132
|
-
return
|
|
132
|
+
return 'Set up NocoBase';
|
|
133
|
+
}
|
|
134
|
+
function logInitStage(title) {
|
|
135
|
+
printStage(title);
|
|
133
136
|
}
|
|
134
137
|
function logInitUiReady(command, url) {
|
|
135
|
-
|
|
136
|
-
|
|
138
|
+
command.log(translateCli('commands.init.messages.uiReady'));
|
|
139
|
+
command.log(translateCli('commands.init.messages.uiReadyHelp'));
|
|
137
140
|
command.log(`URL: ${url}`);
|
|
138
141
|
}
|
|
139
142
|
function logInitUiBrowserOpenFallback() {
|
|
140
|
-
|
|
143
|
+
printWarning(translateCli('commands.init.messages.uiOpenBrowserFallback'));
|
|
141
144
|
}
|
|
142
145
|
function formatBrowserOpenError(error) {
|
|
143
146
|
if (error instanceof Error) {
|
|
@@ -313,8 +316,8 @@ Prompt modes:
|
|
|
313
316
|
min: 0,
|
|
314
317
|
max: 65535,
|
|
315
318
|
}),
|
|
316
|
-
...
|
|
317
|
-
...
|
|
319
|
+
...pickKeys(EnvAdd.flags, INIT_ENV_ADD_FLAG_NAMES),
|
|
320
|
+
...omitKeys(Install.flags, ['yes', 'env']),
|
|
318
321
|
};
|
|
319
322
|
async run() {
|
|
320
323
|
const parsedResult = await this.parse(Init);
|
|
@@ -337,10 +340,10 @@ Prompt modes:
|
|
|
337
340
|
if (normalizedFlags.resume) {
|
|
338
341
|
const envName = String(normalizedFlags.env ?? '').trim();
|
|
339
342
|
if (!envName) {
|
|
340
|
-
|
|
343
|
+
this.error(formatResumeEnvRequiredMessage());
|
|
341
344
|
this.exit(1);
|
|
342
345
|
}
|
|
343
|
-
|
|
346
|
+
logInitStage(initTitle());
|
|
344
347
|
await this.syncNocoBaseSkills({
|
|
345
348
|
skip: Boolean(normalizedFlags['skip-skills']),
|
|
346
349
|
});
|
|
@@ -351,7 +354,6 @@ Prompt modes:
|
|
|
351
354
|
const message = error instanceof Error ? error.message : String(error);
|
|
352
355
|
this.error(message);
|
|
353
356
|
}
|
|
354
|
-
p.outro('Workspace init finished.');
|
|
355
357
|
return;
|
|
356
358
|
}
|
|
357
359
|
const interactive = Boolean(stdinStream.isTTY && stdoutStream.isTTY);
|
|
@@ -377,21 +379,21 @@ Prompt modes:
|
|
|
377
379
|
}
|
|
378
380
|
if (normalizedFlags.yes && !String(presetValues.appName ?? '').trim()) {
|
|
379
381
|
const formatted = formatSkippedAppNameRequiredMessage();
|
|
380
|
-
|
|
382
|
+
this.error(highlightInitValidationMessage(formatted));
|
|
381
383
|
this.exit(1);
|
|
382
384
|
}
|
|
383
385
|
const appName = String(presetValues.appName ?? '').trim();
|
|
384
386
|
if (useBrowserUi) {
|
|
385
|
-
|
|
386
|
-
|
|
387
|
+
logInitStage(initTitle());
|
|
388
|
+
this.log(translateCli('commands.init.messages.uiOpening'));
|
|
387
389
|
}
|
|
388
390
|
else {
|
|
389
|
-
|
|
391
|
+
logInitStage(initTitle());
|
|
390
392
|
if (normalizedFlags.yes) {
|
|
391
|
-
|
|
393
|
+
printInfo(`Non-interactive setup for env "${appName}" (--yes).`);
|
|
392
394
|
}
|
|
393
395
|
else if (!interactive) {
|
|
394
|
-
|
|
396
|
+
printWarning('No interactive terminal detected. NocoBase will be installed using the provided flags and safe defaults.');
|
|
395
397
|
}
|
|
396
398
|
}
|
|
397
399
|
const dynamicInitialValues = await Init.buildDynamicInitialValuesForInstall(normalizedFlags, presetValues);
|
|
@@ -412,7 +414,7 @@ Prompt modes:
|
|
|
412
414
|
},
|
|
413
415
|
onOpenBrowserError: (_url, err) => {
|
|
414
416
|
logInitUiBrowserOpenFallback();
|
|
415
|
-
|
|
417
|
+
this.log(`Browser open error: ${formatBrowserOpenError(err)}`);
|
|
416
418
|
},
|
|
417
419
|
});
|
|
418
420
|
}
|
|
@@ -422,12 +424,11 @@ Prompt modes:
|
|
|
422
424
|
yes: normalizedFlags.yes || useBrowserUi || !interactive,
|
|
423
425
|
hooks: {
|
|
424
426
|
onCancel: () => {
|
|
425
|
-
p.cancel('Init cancelled.');
|
|
426
427
|
this.exit(0);
|
|
427
428
|
},
|
|
428
429
|
onMissingNonInteractive: (message) => {
|
|
429
430
|
const formatted = formatInitValidationMessage(message);
|
|
430
|
-
|
|
431
|
+
this.error(highlightInitValidationMessage(formatted));
|
|
431
432
|
this.exit(1);
|
|
432
433
|
},
|
|
433
434
|
},
|
|
@@ -438,7 +439,7 @@ Prompt modes:
|
|
|
438
439
|
? await getEnv(String(results.appName ?? '').trim(), { scope: resolveDefaultConfigScope() })
|
|
439
440
|
: undefined;
|
|
440
441
|
if (existingEnv && Boolean(normalizedFlags.force)) {
|
|
441
|
-
|
|
442
|
+
printWarning(`Reconfiguring existing env ${pc.cyan(pc.bold(`"${existingEnv.name}"`))} from the global config because ${pc.bold('--force')} was set. The env config will be updated before install starts, then refreshed again after install succeeds.`);
|
|
442
443
|
}
|
|
443
444
|
await this.syncNocoBaseSkills({
|
|
444
445
|
skip: Boolean(normalizedFlags['skip-skills']),
|
|
@@ -447,14 +448,16 @@ Prompt modes:
|
|
|
447
448
|
try {
|
|
448
449
|
// oclif explicit registry keys use `:` (e.g. `env:add`); users still type `nb env add`.
|
|
449
450
|
if (hasNocobase) {
|
|
450
|
-
|
|
451
|
+
logInitStage('Connecting to the env');
|
|
452
|
+
printVerbose('Running nb env add');
|
|
451
453
|
await this.config.runCommand('env:add', this.buildEnvAddArgv(results));
|
|
452
454
|
}
|
|
453
455
|
else {
|
|
454
|
-
|
|
456
|
+
logInitStage('Saving env config');
|
|
455
457
|
await this.persistManagedEnvConfig(results, normalizedFlags);
|
|
456
458
|
managedInstallResults = results;
|
|
457
|
-
|
|
459
|
+
printInfo(`Saved env config for "${String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME}".`);
|
|
460
|
+
printVerbose('Running nb init');
|
|
458
461
|
await this.config.runCommand('install', this.buildInstallArgv(results, normalizedFlags));
|
|
459
462
|
}
|
|
460
463
|
}
|
|
@@ -463,10 +466,9 @@ Prompt modes:
|
|
|
463
466
|
const formatted = managedInstallResults
|
|
464
467
|
? this.formatManagedInstallFailureMessage(message, managedInstallResults, normalizedFlags)
|
|
465
468
|
: message;
|
|
466
|
-
|
|
469
|
+
this.error(pc.red(formatted));
|
|
467
470
|
this.exit(1);
|
|
468
471
|
}
|
|
469
|
-
p.outro('Workspace init finished.');
|
|
470
472
|
}
|
|
471
473
|
static async buildDynamicInitialValuesForInstall(flags, presetValues) {
|
|
472
474
|
const out = {};
|
|
@@ -706,22 +708,25 @@ Prompt modes:
|
|
|
706
708
|
}
|
|
707
709
|
async syncNocoBaseSkills(options) {
|
|
708
710
|
if (options?.skip) {
|
|
709
|
-
|
|
711
|
+
printVerbose('Skipped agent skills sync.');
|
|
710
712
|
return;
|
|
711
713
|
}
|
|
712
714
|
try {
|
|
715
|
+
logInitStage('Syncing agent skills');
|
|
713
716
|
const status = await inspectSkillsStatus();
|
|
714
717
|
if (!status.installed) {
|
|
715
|
-
|
|
718
|
+
printVerbose('Installing NocoBase agent skills (nb skills install)');
|
|
716
719
|
await installNocoBaseSkills();
|
|
720
|
+
printInfo('Agent skills ready.');
|
|
717
721
|
return;
|
|
718
722
|
}
|
|
719
|
-
|
|
723
|
+
printVerbose('Updating NocoBase agent skills (nb skills update)');
|
|
720
724
|
await updateNocoBaseSkills();
|
|
725
|
+
printInfo('Agent skills ready.');
|
|
721
726
|
}
|
|
722
727
|
catch (error) {
|
|
723
728
|
const message = error instanceof Error ? error.message : String(error);
|
|
724
|
-
|
|
729
|
+
this.error(pc.red(`Skills sync failed: ${message}`));
|
|
725
730
|
this.exit(1);
|
|
726
731
|
}
|
|
727
732
|
}
|
|
@@ -798,9 +803,11 @@ Prompt modes:
|
|
|
798
803
|
if (options?.nonInteractive ?? true) {
|
|
799
804
|
argv.unshift('-y');
|
|
800
805
|
}
|
|
806
|
+
argv.push('--skip-save-env-log');
|
|
801
807
|
const processArgv = process.argv.slice(2);
|
|
802
808
|
const envName = String(results.appName ?? DEFAULT_INIT_APP_NAME).trim() || DEFAULT_INIT_APP_NAME;
|
|
803
809
|
const source = String(results.source ?? '').trim();
|
|
810
|
+
const hasNocobase = String(results.hasNocobase ?? '').trim() === 'yes';
|
|
804
811
|
const apiBaseUrl = String(results.apiBaseUrl ?? '').trim();
|
|
805
812
|
const authType = String(results.authType ?? '').trim();
|
|
806
813
|
const accessToken = String(results.accessToken ?? '');
|
|
@@ -811,7 +818,7 @@ Prompt modes:
|
|
|
811
818
|
if (Boolean(flags.verbose)) {
|
|
812
819
|
argv.push('--verbose');
|
|
813
820
|
}
|
|
814
|
-
if (apiBaseUrl) {
|
|
821
|
+
if (hasNocobase && apiBaseUrl) {
|
|
815
822
|
argv.push('--api-base-url', apiBaseUrl);
|
|
816
823
|
}
|
|
817
824
|
if (authType) {
|