@agentuity/cli 2.0.11 → 2.0.13
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/cache/resource-region.d.ts.map +1 -1
- package/dist/cache/resource-region.js +48 -25
- package/dist/cache/resource-region.js.map +1 -1
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +15 -8
- package/dist/cli.js.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.d.ts +20 -0
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +62 -4
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/build/vite/index.d.ts +0 -1
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +0 -1
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/static-renderer.d.ts +17 -0
- package/dist/cmd/build/vite/static-renderer.d.ts.map +1 -1
- package/dist/cmd/build/vite/static-renderer.js +18 -6
- package/dist/cmd/build/vite/static-renderer.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.js +34 -27
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.d.ts +9 -0
- package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server.js +5 -1
- package/dist/cmd/build/vite/vite-asset-server.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +12 -1
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite/ws-proxy.d.ts +15 -1
- package/dist/cmd/build/vite/ws-proxy.d.ts.map +1 -1
- package/dist/cmd/build/vite/ws-proxy.js +33 -0
- package/dist/cmd/build/vite/ws-proxy.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +98 -39
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/create.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/delete.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/list.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/restore.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/checkpoint/restore.js +3 -4
- package/dist/cmd/cloud/sandbox/checkpoint/restore.js.map +1 -1
- package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/create.js +13 -4
- package/dist/cmd/cloud/sandbox/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.js +3 -4
- package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/env.js +3 -5
- package/dist/cmd/cloud/sandbox/env.js.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/exec.js +114 -41
- package/dist/cmd/cloud/sandbox/exec.js.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/execution/list.js +3 -5
- package/dist/cmd/cloud/sandbox/execution/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/cp.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/cp.js +61 -113
- package/dist/cmd/cloud/sandbox/fs/cp.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/download.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/download.js +11 -22
- package/dist/cmd/cloud/sandbox/fs/download.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/ls.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/ls.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/ls.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/mkdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/mkdir.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/mkdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rm.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rm.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/rm.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rmdir.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/rmdir.js +3 -5
- package/dist/cmd/cloud/sandbox/fs/rmdir.js.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/upload.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/fs/upload.js +7 -8
- package/dist/cmd/cloud/sandbox/fs/upload.js.map +1 -1
- package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/get.js +21 -7
- package/dist/cmd/cloud/sandbox/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/create.js +3 -4
- package/dist/cmd/cloud/sandbox/job/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/destroy.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/destroy.js +3 -4
- package/dist/cmd/cloud/sandbox/job/destroy.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/get.js +3 -4
- package/dist/cmd/cloud/sandbox/job/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/list.js +3 -4
- package/dist/cmd/cloud/sandbox/job/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/job/logs.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/job/logs.js +4 -4
- package/dist/cmd/cloud/sandbox/job/logs.js.map +1 -1
- package/dist/cmd/cloud/sandbox/pause.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/pause.js +21 -5
- package/dist/cmd/cloud/sandbox/pause.js.map +1 -1
- package/dist/cmd/cloud/sandbox/resume.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/resume.js +3 -4
- package/dist/cmd/cloud/sandbox/resume.js.map +1 -1
- package/dist/cmd/cloud/sandbox/run.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/run.js +36 -7
- package/dist/cmd/cloud/sandbox/run.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/create.js +4 -4
- package/dist/cmd/cloud/sandbox/snapshot/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/util.d.ts +19 -0
- package/dist/cmd/cloud/sandbox/util.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/util.js +40 -2
- package/dist/cmd/cloud/sandbox/util.js.map +1 -1
- package/dist/cmd/coder/create.js +7 -7
- package/dist/cmd/coder/create.js.map +1 -1
- package/dist/cmd/coder/start.d.ts.map +1 -1
- package/dist/cmd/coder/start.js +3 -0
- package/dist/cmd/coder/start.js.map +1 -1
- package/dist/cmd/coder/tui-init.js +1 -1
- package/dist/cmd/coder/tui-init.js.map +1 -1
- package/dist/cmd/coder/update.js +8 -8
- package/dist/cmd/coder/update.js.map +1 -1
- package/dist/cmd/coder/workspace/common.d.ts +29 -0
- package/dist/cmd/coder/workspace/common.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/common.js +83 -0
- package/dist/cmd/coder/workspace/common.js.map +1 -0
- package/dist/cmd/coder/workspace/create.d.ts.map +1 -1
- package/dist/cmd/coder/workspace/create.js +57 -32
- package/dist/cmd/coder/workspace/create.js.map +1 -1
- package/dist/cmd/coder/workspace/get.d.ts.map +1 -1
- package/dist/cmd/coder/workspace/get.js +2 -5
- package/dist/cmd/coder/workspace/get.js.map +1 -1
- package/dist/cmd/coder/workspace/index.d.ts.map +1 -1
- package/dist/cmd/coder/workspace/index.js +11 -1
- package/dist/cmd/coder/workspace/index.js.map +1 -1
- package/dist/cmd/coder/workspace/list.d.ts.map +1 -1
- package/dist/cmd/coder/workspace/list.js +4 -0
- package/dist/cmd/coder/workspace/list.js.map +1 -1
- package/dist/cmd/coder/workspace/refresh.d.ts +2 -0
- package/dist/cmd/coder/workspace/refresh.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/refresh.js +59 -0
- package/dist/cmd/coder/workspace/refresh.js.map +1 -0
- package/dist/cmd/coder/workspace/update.d.ts +2 -0
- package/dist/cmd/coder/workspace/update.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/update.js +131 -0
- package/dist/cmd/coder/workspace/update.js.map +1 -0
- package/dist/cmd/coder/workspace/validate-dependencies.d.ts +2 -0
- package/dist/cmd/coder/workspace/validate-dependencies.d.ts.map +1 -0
- package/dist/cmd/coder/workspace/validate-dependencies.js +70 -0
- package/dist/cmd/coder/workspace/validate-dependencies.js.map +1 -0
- package/dist/cmd/dev/dev-lock.d.ts.map +1 -1
- package/dist/cmd/dev/dev-lock.js +43 -17
- package/dist/cmd/dev/dev-lock.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +211 -125
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/dev/process-manager.d.ts +41 -1
- package/dist/cmd/dev/process-manager.d.ts.map +1 -1
- package/dist/cmd/dev/process-manager.js +160 -31
- package/dist/cmd/dev/process-manager.js.map +1 -1
- package/dist/cmd/project/create.d.ts.map +1 -1
- package/dist/cmd/project/create.js +0 -2
- package/dist/cmd/project/create.js.map +1 -1
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/index.js +0 -3
- package/dist/cmd/project/index.js.map +1 -1
- package/dist/cmd/project/random-name.d.ts +17 -0
- package/dist/cmd/project/random-name.d.ts.map +1 -0
- package/dist/cmd/project/random-name.js +144 -0
- package/dist/cmd/project/random-name.js.map +1 -0
- package/dist/cmd/project/template-flow.d.ts +0 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +180 -275
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/dist/composite-logger.d.ts.map +1 -1
- package/dist/composite-logger.js +19 -0
- package/dist/composite-logger.js.map +1 -1
- package/dist/config.d.ts +18 -16
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +46 -16
- package/dist/config.js.map +1 -1
- package/dist/tui/prompt.d.ts +29 -0
- package/dist/tui/prompt.d.ts.map +1 -1
- package/dist/tui/prompt.js +180 -8
- package/dist/tui/prompt.js.map +1 -1
- package/package.json +7 -7
- package/src/cache/resource-region.ts +68 -44
- package/src/cli.ts +30 -8
- package/src/cmd/ai/prompt/web.md +43 -17
- package/src/cmd/build/vite/bun-dev-server.ts +92 -6
- package/src/cmd/build/vite/index.ts +0 -1
- package/src/cmd/build/vite/static-renderer.ts +18 -7
- package/src/cmd/build/vite/vite-asset-server-config.ts +37 -27
- package/src/cmd/build/vite/vite-asset-server.ts +5 -1
- package/src/cmd/build/vite/vite-builder.ts +12 -1
- package/src/cmd/build/vite/ws-proxy.ts +52 -3
- package/src/cmd/cloud/deploy.ts +117 -49
- package/src/cmd/cloud/sandbox/checkpoint/create.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/delete.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/list.ts +10 -4
- package/src/cmd/cloud/sandbox/checkpoint/restore.ts +10 -4
- package/src/cmd/cloud/sandbox/create.ts +14 -4
- package/src/cmd/cloud/sandbox/delete.ts +10 -4
- package/src/cmd/cloud/sandbox/env.ts +10 -5
- package/src/cmd/cloud/sandbox/exec.ts +157 -42
- package/src/cmd/cloud/sandbox/execution/list.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/cp.ts +94 -126
- package/src/cmd/cloud/sandbox/fs/download.ts +18 -25
- package/src/cmd/cloud/sandbox/fs/ls.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/mkdir.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/rm.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/rmdir.ts +10 -5
- package/src/cmd/cloud/sandbox/fs/upload.ts +14 -8
- package/src/cmd/cloud/sandbox/get.ts +28 -7
- package/src/cmd/cloud/sandbox/job/create.ts +10 -4
- package/src/cmd/cloud/sandbox/job/destroy.ts +10 -4
- package/src/cmd/cloud/sandbox/job/get.ts +10 -4
- package/src/cmd/cloud/sandbox/job/list.ts +10 -4
- package/src/cmd/cloud/sandbox/job/logs.ts +11 -4
- package/src/cmd/cloud/sandbox/pause.ts +31 -5
- package/src/cmd/cloud/sandbox/resume.ts +10 -4
- package/src/cmd/cloud/sandbox/run.ts +49 -11
- package/src/cmd/cloud/sandbox/snapshot/create.ts +6 -6
- package/src/cmd/cloud/sandbox/util.ts +63 -2
- package/src/cmd/coder/create.ts +8 -8
- package/src/cmd/coder/start.ts +3 -0
- package/src/cmd/coder/tui-init.ts +1 -1
- package/src/cmd/coder/update.ts +7 -7
- package/src/cmd/coder/workspace/common.ts +103 -0
- package/src/cmd/coder/workspace/create.ts +84 -37
- package/src/cmd/coder/workspace/get.ts +2 -5
- package/src/cmd/coder/workspace/index.ts +13 -1
- package/src/cmd/coder/workspace/list.ts +4 -0
- package/src/cmd/coder/workspace/refresh.ts +63 -0
- package/src/cmd/coder/workspace/update.ts +154 -0
- package/src/cmd/coder/workspace/validate-dependencies.ts +75 -0
- package/src/cmd/dev/dev-lock.ts +50 -16
- package/src/cmd/dev/index.ts +249 -134
- package/src/cmd/dev/process-manager.ts +173 -33
- package/src/cmd/project/create.ts +0 -2
- package/src/cmd/project/index.ts +0 -3
- package/src/cmd/project/random-name.ts +152 -0
- package/src/cmd/project/template-flow.ts +196 -305
- package/src/composite-logger.ts +20 -0
- package/src/config.ts +69 -19
- package/src/tui/prompt.ts +214 -8
- package/dist/cmd/build/vite/public-asset-path-plugin.d.ts +0 -45
- package/dist/cmd/build/vite/public-asset-path-plugin.d.ts.map +0 -1
- package/dist/cmd/build/vite/public-asset-path-plugin.js +0 -166
- package/dist/cmd/build/vite/public-asset-path-plugin.js.map +0 -1
- package/dist/cmd/project/auth/generate.d.ts +0 -5
- package/dist/cmd/project/auth/generate.d.ts.map +0 -1
- package/dist/cmd/project/auth/generate.js +0 -102
- package/dist/cmd/project/auth/generate.js.map +0 -1
- package/dist/cmd/project/auth/index.d.ts +0 -2
- package/dist/cmd/project/auth/index.d.ts.map +0 -1
- package/dist/cmd/project/auth/index.js +0 -21
- package/dist/cmd/project/auth/index.js.map +0 -1
- package/dist/cmd/project/auth/init.d.ts +0 -2
- package/dist/cmd/project/auth/init.d.ts.map +0 -1
- package/dist/cmd/project/auth/init.js +0 -213
- package/dist/cmd/project/auth/init.js.map +0 -1
- package/dist/cmd/project/auth/shared.d.ts +0 -93
- package/dist/cmd/project/auth/shared.d.ts.map +0 -1
- package/dist/cmd/project/auth/shared.js +0 -475
- package/dist/cmd/project/auth/shared.js.map +0 -1
- package/src/cmd/build/vite/public-asset-path-plugin.ts +0 -209
- package/src/cmd/project/auth/generate.ts +0 -116
- package/src/cmd/project/auth/index.ts +0 -21
- package/src/cmd/project/auth/init.ts +0 -256
- package/src/cmd/project/auth/shared.ts +0 -591
|
@@ -11,11 +11,13 @@ import { playSound } from '../../sound';
|
|
|
11
11
|
import * as tui from '../../tui';
|
|
12
12
|
import { createPrompt, note } from '../../tui';
|
|
13
13
|
import { getGithubBotIdentity } from '../git/api';
|
|
14
|
-
import { ensureAuthDependencies, generateAuthFileContent, generateAuthSchemaSql, printIntegrationExamples, runAuthMigrations, } from './auth/shared';
|
|
15
14
|
import { downloadTemplate, initGitRepo, setupProject } from './download';
|
|
15
|
+
import { suggestBucketName, suggestDatabaseName } from './random-name';
|
|
16
16
|
import { fetchTemplates } from './templates';
|
|
17
|
+
// Domain validator shared between the multi-select branch and the standalone prompt.
|
|
18
|
+
const DOMAIN_REGEX = /^(?=.{1,253}$)(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[A-Za-z]{2,63}$/;
|
|
17
19
|
export async function runCreateFlow(options) {
|
|
18
|
-
const { projectName: initialProjectName, dir: targetDir, template: initialTemplate, templateDir, templateBranch, skipPrompts, logger, auth, config, orgId: selectedOrgId, region, apiClient, domains, database: databaseOption, storage: storageOption,
|
|
20
|
+
const { projectName: initialProjectName, dir: targetDir, template: initialTemplate, templateDir, templateBranch, skipPrompts, logger, auth, config, orgId: selectedOrgId, region, apiClient, domains, database: databaseOption, storage: storageOption, } = options;
|
|
19
21
|
const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY;
|
|
20
22
|
const isInteractive = !skipPrompts && !isHeadless;
|
|
21
23
|
// Fetch available templates
|
|
@@ -188,7 +190,7 @@ export async function runCreateFlow(options) {
|
|
|
188
190
|
error: 'Project setup completed with errors',
|
|
189
191
|
};
|
|
190
192
|
}
|
|
191
|
-
//
|
|
193
|
+
// Resource provisioning gates
|
|
192
194
|
const canProvision = auth && apiClient && catalystClient && orgId && region;
|
|
193
195
|
// Only count as resource flags if actually requesting provisioning (not explicit skip)
|
|
194
196
|
const hasResourceFlags = (databaseOption !== undefined && databaseOption.toLowerCase() !== 'skip') ||
|
|
@@ -204,17 +206,57 @@ export async function runCreateFlow(options) {
|
|
|
204
206
|
logger.fatal('Cannot provision database/storage without being authenticated and registering the project.\n' +
|
|
205
207
|
'Remove --no-register or omit --database/--storage flags.', ErrorCode.VALIDATION_FAILED);
|
|
206
208
|
}
|
|
207
|
-
// Validate that --enable-auth requires authentication and registration
|
|
208
|
-
if (enableAuthOption && !canProvision) {
|
|
209
|
-
logger.fatal('Cannot enable Agentuity Auth without being authenticated and registering the project.\n' +
|
|
210
|
-
'Remove --no-register or omit --enable-auth flag.', ErrorCode.VALIDATION_FAILED);
|
|
211
|
-
}
|
|
212
209
|
if (canProvision) {
|
|
213
|
-
//
|
|
210
|
+
// CLI flags pre-resolve their respective per-resource decision; the multi-select
|
|
211
|
+
// is only used for resources where the user didn't pass a flag.
|
|
212
|
+
const dbFlagAction = resolveFlagAction(databaseOption, 'database');
|
|
213
|
+
const storageFlagAction = resolveFlagAction(storageOption, 'storage');
|
|
214
|
+
const domainFlagProvided = (domains?.length ?? 0) > 0;
|
|
215
|
+
// Determine which resources should run through the configuration phase.
|
|
216
|
+
// In interactive mode, ask the user via a single multi-select.
|
|
217
|
+
// In headless / non-interactive mode, only flagged resources are considered.
|
|
218
|
+
let wantDb = dbFlagAction !== undefined && dbFlagAction !== 'Skip';
|
|
219
|
+
let wantStorage = storageFlagAction !== undefined && storageFlagAction !== 'Skip';
|
|
220
|
+
let wantDomain = domainFlagProvided;
|
|
221
|
+
if (isInteractive) {
|
|
222
|
+
// Build multi-select options dynamically: only show resources the user hasn't
|
|
223
|
+
// already decided about via CLI flags. If all three came from flags, skip the prompt.
|
|
224
|
+
const msOptions = [];
|
|
225
|
+
if (dbFlagAction === undefined) {
|
|
226
|
+
msOptions.push({ value: 'database', label: 'SQL Database', hint: 'PostgreSQL' });
|
|
227
|
+
}
|
|
228
|
+
if (storageFlagAction === undefined) {
|
|
229
|
+
msOptions.push({ value: 'storage', label: 'Storage Bucket', hint: 'S3-compatible' });
|
|
230
|
+
}
|
|
231
|
+
if (!domainFlagProvided) {
|
|
232
|
+
msOptions.push({ value: 'domain', label: 'Custom Domain', hint: 'BYO domain' });
|
|
233
|
+
}
|
|
234
|
+
if (msOptions.length > 0) {
|
|
235
|
+
const picked = await prompt.multiselect({
|
|
236
|
+
message: 'What would you like to set up? (all optional)',
|
|
237
|
+
options: msOptions,
|
|
238
|
+
initial: [],
|
|
239
|
+
});
|
|
240
|
+
if (dbFlagAction === undefined)
|
|
241
|
+
wantDb = picked.includes('database');
|
|
242
|
+
if (storageFlagAction === undefined)
|
|
243
|
+
wantStorage = picked.includes('storage');
|
|
244
|
+
if (!domainFlagProvided)
|
|
245
|
+
wantDomain = picked.includes('domain');
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
// Fetch existing resources only if we'll actually need them.
|
|
249
|
+
// Need them when:
|
|
250
|
+
// - user wants db/storage in interactive mode (to offer "use existing")
|
|
251
|
+
// - a CLI flag pointed at an existing resource by name
|
|
214
252
|
let resources;
|
|
215
|
-
const needResources = isInteractive ||
|
|
216
|
-
(databaseOption
|
|
217
|
-
|
|
253
|
+
const needResources = (isInteractive && (wantDb || wantStorage)) ||
|
|
254
|
+
(databaseOption !== undefined &&
|
|
255
|
+
dbFlagAction !== 'Create New' &&
|
|
256
|
+
dbFlagAction !== 'Skip') ||
|
|
257
|
+
(storageOption !== undefined &&
|
|
258
|
+
storageFlagAction !== 'Create New' &&
|
|
259
|
+
storageFlagAction !== 'Skip');
|
|
218
260
|
if (needResources) {
|
|
219
261
|
resources = await tui.spinner({
|
|
220
262
|
message: 'Fetching resources',
|
|
@@ -227,301 +269,162 @@ export async function runCreateFlow(options) {
|
|
|
227
269
|
logger.debug(`Resources for org ${orgId} in region ${region}: ${resources.db.length} databases, ${resources.s3.length} storage buckets`);
|
|
228
270
|
logger.debug(`Database names: ${resources.db.map((d) => d.name).join(', ') || '(none)'}`);
|
|
229
271
|
logger.debug(`Storage buckets: ${resources.s3.map((b) => b.bucket_name).join(', ') || '(none)'}`);
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
db_action = 'Create New';
|
|
237
|
-
}
|
|
238
|
-
else if (databaseOption.toLowerCase() === 'skip') {
|
|
239
|
-
db_action = 'Skip';
|
|
272
|
+
// Validate flag-supplied resource names against the fetched list.
|
|
273
|
+
if (databaseOption !== undefined &&
|
|
274
|
+
dbFlagAction !== 'Create New' &&
|
|
275
|
+
dbFlagAction !== 'Skip' &&
|
|
276
|
+
!resources.db.find((d) => d.name === dbFlagAction)) {
|
|
277
|
+
logger.fatal(`Database '${databaseOption}' not found. Use 'new' to create a new database or 'skip' to skip.`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
240
278
|
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
}
|
|
247
|
-
db_action = databaseOption;
|
|
279
|
+
if (storageOption !== undefined &&
|
|
280
|
+
storageFlagAction !== 'Create New' &&
|
|
281
|
+
storageFlagAction !== 'Skip' &&
|
|
282
|
+
!resources.s3.find((b) => b.bucket_name === storageFlagAction)) {
|
|
283
|
+
logger.fatal(`Storage bucket '${storageOption}' not found. Use 'new' to create a new bucket or 'skip' to skip.`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
248
284
|
}
|
|
249
285
|
}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
if (storageOption.toLowerCase() === 'new') {
|
|
272
|
-
s3_action = 'Create New';
|
|
273
|
-
}
|
|
274
|
-
else if (storageOption.toLowerCase() === 'skip') {
|
|
275
|
-
s3_action = 'Skip';
|
|
276
|
-
}
|
|
277
|
-
else {
|
|
278
|
-
// Existing bucket name - validate it exists
|
|
279
|
-
const existingBucket = resources?.s3.find((b) => b.bucket_name === storageOption);
|
|
280
|
-
if (!existingBucket) {
|
|
281
|
-
logger.fatal(`Storage bucket '${storageOption}' not found. Use 'new' to create a new bucket or 'skip' to skip.`, ErrorCode.RESOURCE_NOT_FOUND);
|
|
286
|
+
// === Configure each selected resource: Database → Storage → Domain ===
|
|
287
|
+
// Database
|
|
288
|
+
if (wantDb) {
|
|
289
|
+
let dbAction = dbFlagAction;
|
|
290
|
+
if (dbAction === undefined && isInteractive) {
|
|
291
|
+
const existing = resources?.db ?? [];
|
|
292
|
+
if (existing.length > 0) {
|
|
293
|
+
dbAction = await prompt.select({
|
|
294
|
+
message: 'SQL Database',
|
|
295
|
+
options: [
|
|
296
|
+
{ value: 'Create New', label: 'Create a new database' },
|
|
297
|
+
...existing.map((db) => ({
|
|
298
|
+
value: db.name,
|
|
299
|
+
label: `Use database: ${tui.tuiColors.primary(db.name)}`,
|
|
300
|
+
})),
|
|
301
|
+
],
|
|
302
|
+
});
|
|
303
|
+
}
|
|
304
|
+
else {
|
|
305
|
+
// No existing databases — user already opted in via the multi-select, so create new.
|
|
306
|
+
dbAction = 'Create New';
|
|
282
307
|
}
|
|
283
|
-
s3_action = storageOption;
|
|
284
|
-
}
|
|
285
|
-
}
|
|
286
|
-
else if (isInteractive) {
|
|
287
|
-
s3_action = await prompt.select({
|
|
288
|
-
message: 'Create Storage Bucket?',
|
|
289
|
-
options: [
|
|
290
|
-
{ value: 'Skip', label: 'Skip or Setup later' },
|
|
291
|
-
{ value: 'Create New', label: 'Create a new bucket' },
|
|
292
|
-
...resources.s3.map((bucket) => ({
|
|
293
|
-
value: bucket.bucket_name,
|
|
294
|
-
label: `Use bucket: ${tui.tuiColors.primary(bucket.bucket_name)}`,
|
|
295
|
-
})),
|
|
296
|
-
],
|
|
297
|
-
});
|
|
298
|
-
}
|
|
299
|
-
else {
|
|
300
|
-
// Headless without flag - skip
|
|
301
|
-
s3_action = 'Skip';
|
|
302
|
-
}
|
|
303
|
-
// Custom DNS: only prompt in interactive mode if not already provided
|
|
304
|
-
if (!domains?.length && isInteractive) {
|
|
305
|
-
const customDns = await prompt.text({
|
|
306
|
-
message: 'Setup custom DNS?',
|
|
307
|
-
hint: 'Enter a domain name or press Enter to skip',
|
|
308
|
-
validate: (val) => val === ''
|
|
309
|
-
? true
|
|
310
|
-
: /^(?=.{1,253}$)(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[A-Za-z]{2,63}$/.test(val),
|
|
311
|
-
});
|
|
312
|
-
if (customDns) {
|
|
313
|
-
_domains = [customDns];
|
|
314
308
|
}
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
case 'Create New': {
|
|
319
|
-
let bucketName;
|
|
320
|
-
let bucketDescription;
|
|
321
|
-
// Only prompt for name/description in interactive mode
|
|
309
|
+
if (dbAction === 'Create New') {
|
|
310
|
+
let dbName;
|
|
311
|
+
let dbDescription;
|
|
322
312
|
if (isInteractive) {
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
|
|
313
|
+
const suggestion = suggestDatabaseName(projectName);
|
|
314
|
+
const dbNameInput = await prompt.text({
|
|
315
|
+
message: 'Database name',
|
|
316
|
+
hint: 'Optional · lowercase letters, digits, underscores',
|
|
317
|
+
placeholder: suggestion,
|
|
326
318
|
validate: (value) => {
|
|
327
319
|
const trimmed = value.trim();
|
|
328
320
|
if (trimmed === '')
|
|
329
321
|
return true;
|
|
330
|
-
const result =
|
|
322
|
+
const result = validateDatabaseName(trimmed);
|
|
331
323
|
return result.valid ? true : result.error;
|
|
332
324
|
},
|
|
333
325
|
});
|
|
334
|
-
|
|
335
|
-
|
|
326
|
+
dbName = dbNameInput.trim() || undefined;
|
|
327
|
+
dbDescription =
|
|
336
328
|
(await prompt.text({
|
|
337
|
-
message: '
|
|
338
|
-
hint: 'Optional
|
|
329
|
+
message: 'Database description',
|
|
330
|
+
hint: 'Optional · press Enter to skip',
|
|
339
331
|
})) || undefined;
|
|
340
332
|
}
|
|
341
333
|
const created = await tui.spinner({
|
|
342
|
-
message: 'Provisioning New
|
|
334
|
+
message: 'Provisioning New SQL Database',
|
|
343
335
|
clearOnSuccess: true,
|
|
344
336
|
callback: async () => {
|
|
345
337
|
return createResources(catalystClient, orgId, region, [
|
|
346
|
-
{
|
|
347
|
-
type: 's3',
|
|
348
|
-
name: bucketName,
|
|
349
|
-
description: bucketDescription,
|
|
350
|
-
},
|
|
338
|
+
{ type: 'db', name: dbName, description: dbDescription },
|
|
351
339
|
]);
|
|
352
340
|
},
|
|
353
341
|
});
|
|
354
|
-
|
|
355
|
-
if (created[0]?.env) {
|
|
342
|
+
if (created[0]?.env)
|
|
356
343
|
Object.assign(resourceEnvVars, created[0].env);
|
|
357
|
-
}
|
|
358
|
-
break;
|
|
359
344
|
}
|
|
360
|
-
|
|
361
|
-
|
|
345
|
+
else if (dbAction && dbAction !== 'Skip') {
|
|
346
|
+
// Existing database selected — reuse its env vars.
|
|
347
|
+
const selectedDb = resources?.db.find((d) => d.name === dbAction);
|
|
348
|
+
if (selectedDb?.env)
|
|
349
|
+
Object.assign(resourceEnvVars, selectedDb.env);
|
|
362
350
|
}
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
351
|
+
}
|
|
352
|
+
// Storage
|
|
353
|
+
if (wantStorage) {
|
|
354
|
+
let s3Action = storageFlagAction;
|
|
355
|
+
if (s3Action === undefined && isInteractive) {
|
|
356
|
+
const existing = resources?.s3 ?? [];
|
|
357
|
+
if (existing.length > 0) {
|
|
358
|
+
s3Action = await prompt.select({
|
|
359
|
+
message: 'Storage Bucket',
|
|
360
|
+
options: [
|
|
361
|
+
{ value: 'Create New', label: 'Create a new bucket' },
|
|
362
|
+
...existing.map((bucket) => ({
|
|
363
|
+
value: bucket.bucket_name,
|
|
364
|
+
label: `Use bucket: ${tui.tuiColors.primary(bucket.bucket_name)}`,
|
|
365
|
+
})),
|
|
366
|
+
],
|
|
367
|
+
});
|
|
368
|
+
}
|
|
369
|
+
else {
|
|
370
|
+
s3Action = 'Create New';
|
|
368
371
|
}
|
|
369
|
-
break;
|
|
370
372
|
}
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
case 'Create New': {
|
|
375
|
-
let dbName;
|
|
376
|
-
let dbDescription;
|
|
377
|
-
// Only prompt for name/description in interactive mode
|
|
373
|
+
if (s3Action === 'Create New') {
|
|
374
|
+
let bucketName;
|
|
375
|
+
let bucketDescription;
|
|
378
376
|
if (isInteractive) {
|
|
379
|
-
const
|
|
380
|
-
|
|
381
|
-
|
|
377
|
+
const suggestion = suggestBucketName(projectName);
|
|
378
|
+
const bucketNameInput = await prompt.text({
|
|
379
|
+
message: 'Bucket name',
|
|
380
|
+
hint: 'Optional · lowercase letters, digits, hyphens',
|
|
381
|
+
placeholder: suggestion,
|
|
382
382
|
validate: (value) => {
|
|
383
383
|
const trimmed = value.trim();
|
|
384
384
|
if (trimmed === '')
|
|
385
385
|
return true;
|
|
386
|
-
const result =
|
|
386
|
+
const result = validateBucketName(trimmed);
|
|
387
387
|
return result.valid ? true : result.error;
|
|
388
388
|
},
|
|
389
389
|
});
|
|
390
|
-
|
|
391
|
-
|
|
390
|
+
bucketName = bucketNameInput.trim() || undefined;
|
|
391
|
+
bucketDescription =
|
|
392
392
|
(await prompt.text({
|
|
393
|
-
message: '
|
|
394
|
-
hint: 'Optional
|
|
393
|
+
message: 'Bucket description',
|
|
394
|
+
hint: 'Optional · press Enter to skip',
|
|
395
395
|
})) || undefined;
|
|
396
396
|
}
|
|
397
397
|
const created = await tui.spinner({
|
|
398
|
-
message: 'Provisioning New
|
|
398
|
+
message: 'Provisioning New Bucket',
|
|
399
399
|
clearOnSuccess: true,
|
|
400
400
|
callback: async () => {
|
|
401
401
|
return createResources(catalystClient, orgId, region, [
|
|
402
|
-
{
|
|
403
|
-
type: 'db',
|
|
404
|
-
name: dbName,
|
|
405
|
-
description: dbDescription,
|
|
406
|
-
},
|
|
402
|
+
{ type: 's3', name: bucketName, description: bucketDescription },
|
|
407
403
|
]);
|
|
408
404
|
},
|
|
409
405
|
});
|
|
410
|
-
|
|
411
|
-
if (created[0]?.env) {
|
|
406
|
+
if (created[0]?.env)
|
|
412
407
|
Object.assign(resourceEnvVars, created[0].env);
|
|
413
|
-
}
|
|
414
|
-
break;
|
|
415
|
-
}
|
|
416
|
-
case 'Skip': {
|
|
417
|
-
break;
|
|
418
|
-
}
|
|
419
|
-
default: {
|
|
420
|
-
// User selected an existing database - get env vars from the resources list
|
|
421
|
-
const selectedDb = resources?.db.find((d) => d.name === db_action);
|
|
422
|
-
if (selectedDb?.env) {
|
|
423
|
-
Object.assign(resourceEnvVars, selectedDb.env);
|
|
424
|
-
}
|
|
425
|
-
break;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
}
|
|
429
|
-
// Auth setup - either from template, CLI flag, or user choice
|
|
430
|
-
const templateHasAuth = selectedTemplate.id === 'agentuity-auth';
|
|
431
|
-
let authEnabled = templateHasAuth; // Auth templates have auth enabled by default
|
|
432
|
-
let authDatabaseName;
|
|
433
|
-
let authDatabaseUrl;
|
|
434
|
-
// Handle auth enablement: CLI flag > interactive prompt > disabled (headless)
|
|
435
|
-
if (enableAuthOption !== undefined) {
|
|
436
|
-
// CLI flag provided
|
|
437
|
-
authEnabled = enableAuthOption;
|
|
438
|
-
}
|
|
439
|
-
else if (canProvision && isInteractive && !templateHasAuth) {
|
|
440
|
-
// For non-auth templates in interactive mode, ask if they want to enable auth
|
|
441
|
-
const enableAuth = await prompt.select({
|
|
442
|
-
message: 'Enable Agentuity Authentication?',
|
|
443
|
-
options: [
|
|
444
|
-
{ value: 'no', label: "No, I'll add auth later" },
|
|
445
|
-
{ value: 'yes', label: 'Yes, set up Agentuity Auth' },
|
|
446
|
-
],
|
|
447
|
-
});
|
|
448
|
-
if (enableAuth === 'yes') {
|
|
449
|
-
authEnabled = true;
|
|
450
|
-
}
|
|
451
|
-
}
|
|
452
|
-
// In headless mode without --enable-auth flag, authEnabled stays false (unless template has auth)
|
|
453
|
-
// Set up database and secret for any auth-enabled project
|
|
454
|
-
if (authEnabled && canProvision) {
|
|
455
|
-
// If a database was already selected/created above, use it for auth
|
|
456
|
-
if (resourceEnvVars.DATABASE_URL) {
|
|
457
|
-
authDatabaseUrl = resourceEnvVars.DATABASE_URL;
|
|
458
|
-
// Extract database name from URL using proper URL parsing
|
|
459
|
-
try {
|
|
460
|
-
const dbUrl = new URL(authDatabaseUrl);
|
|
461
|
-
const dbName = dbUrl.pathname.replace(/^\/+/, ''); // Remove leading slashes
|
|
462
|
-
// Validate: non-empty and contains only safe characters
|
|
463
|
-
if (dbName && /^[A-Za-z0-9_-]+$/.test(dbName)) {
|
|
464
|
-
authDatabaseName = dbName;
|
|
465
|
-
}
|
|
466
|
-
}
|
|
467
|
-
catch {
|
|
468
|
-
// Invalid URL format, authDatabaseName stays undefined
|
|
469
|
-
}
|
|
470
|
-
}
|
|
471
|
-
else {
|
|
472
|
-
// No database selected yet, create one for auth
|
|
473
|
-
const created = await tui.spinner({
|
|
474
|
-
message: 'Provisioning database for auth',
|
|
475
|
-
clearOnSuccess: true,
|
|
476
|
-
callback: async () => {
|
|
477
|
-
return createResources(catalystClient, orgId, region, [{ type: 'db' }]);
|
|
478
|
-
},
|
|
479
|
-
});
|
|
480
|
-
const createdDb = created[0];
|
|
481
|
-
if (!createdDb) {
|
|
482
|
-
logger.fatal('Failed to create database for auth', ErrorCode.RESOURCE_NOT_FOUND);
|
|
483
|
-
return undefined;
|
|
484
408
|
}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
// Also add to resourceEnvVars if not already set
|
|
490
|
-
if (!resourceEnvVars.DATABASE_URL) {
|
|
491
|
-
Object.assign(resourceEnvVars, createdDb.env);
|
|
492
|
-
}
|
|
493
|
-
}
|
|
494
|
-
}
|
|
495
|
-
// Install auth dependencies (skip for agentuity-auth template which has them)
|
|
496
|
-
if (!templateHasAuth) {
|
|
497
|
-
await ensureAuthDependencies({ projectDir: dest, logger });
|
|
498
|
-
// Generate auth.ts
|
|
499
|
-
const authFilePath = resolve(dest, 'src', 'auth.ts');
|
|
500
|
-
if (!existsSync(authFilePath)) {
|
|
501
|
-
const srcDir = resolve(dest, 'src');
|
|
502
|
-
if (!existsSync(srcDir)) {
|
|
503
|
-
await Bun.write(resolve(srcDir, '.gitkeep'), '');
|
|
504
|
-
}
|
|
505
|
-
await Bun.write(authFilePath, generateAuthFileContent());
|
|
506
|
-
tui.success('Created src/auth.ts');
|
|
409
|
+
else if (s3Action && s3Action !== 'Skip') {
|
|
410
|
+
const selectedBucket = resources?.s3.find((b) => b.bucket_name === s3Action);
|
|
411
|
+
if (selectedBucket?.env)
|
|
412
|
+
Object.assign(resourceEnvVars, selectedBucket.env);
|
|
507
413
|
}
|
|
508
414
|
}
|
|
509
|
-
//
|
|
510
|
-
if (
|
|
511
|
-
const
|
|
512
|
-
message: '
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
orgId,
|
|
520
|
-
region,
|
|
521
|
-
databaseName: authDatabaseName,
|
|
522
|
-
sql,
|
|
523
|
-
config,
|
|
415
|
+
// Custom Domain
|
|
416
|
+
if (wantDomain && !domainFlagProvided && isInteractive) {
|
|
417
|
+
const customDns = await prompt.text({
|
|
418
|
+
message: 'Custom domain',
|
|
419
|
+
hint: 'e.g. agents.example.com',
|
|
420
|
+
validate: (val) => val === ''
|
|
421
|
+
? 'Domain is required (or go back and uncheck Custom Domain)'
|
|
422
|
+
: DOMAIN_REGEX.test(val)
|
|
423
|
+
? true
|
|
424
|
+
: 'Invalid domain',
|
|
524
425
|
});
|
|
426
|
+
if (customDns)
|
|
427
|
+
_domains = [customDns];
|
|
525
428
|
}
|
|
526
429
|
}
|
|
527
430
|
let projectId;
|
|
@@ -558,24 +461,9 @@ export async function runCreateFlow(options) {
|
|
|
558
461
|
});
|
|
559
462
|
},
|
|
560
463
|
});
|
|
561
|
-
// Add auth secret to resourceEnvVars if auth is enabled
|
|
562
|
-
if (authEnabled && !resourceEnvVars.AGENTUITY_AUTH_SECRET) {
|
|
563
|
-
const devSecret = `dev-${crypto.randomUUID()}`;
|
|
564
|
-
resourceEnvVars.AGENTUITY_AUTH_SECRET = devSecret;
|
|
565
|
-
}
|
|
566
464
|
// Write resource environment variables to .env
|
|
567
465
|
if (Object.keys(resourceEnvVars).length > 0) {
|
|
568
466
|
await addResourceEnvVars(dest, resourceEnvVars);
|
|
569
|
-
// Show user feedback for auth-related env vars
|
|
570
|
-
if (authEnabled) {
|
|
571
|
-
if (resourceEnvVars.DATABASE_URL) {
|
|
572
|
-
tui.success('DATABASE_URL added to .env');
|
|
573
|
-
}
|
|
574
|
-
if (resourceEnvVars.AGENTUITY_AUTH_SECRET) {
|
|
575
|
-
tui.success('AGENTUITY_AUTH_SECRET added to .env');
|
|
576
|
-
tui.info(`Generate one with: ${tui.muted('npx @better-auth/cli secret')} or ${tui.muted('openssl rand -hex 32')}`);
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
467
|
}
|
|
580
468
|
// After registration, push any existing env/secrets from .env
|
|
581
469
|
if (projectId) {
|
|
@@ -659,10 +547,6 @@ export async function runCreateFlow(options) {
|
|
|
659
547
|
await promptForDNS(projectId, _domains, cloudRegion, config);
|
|
660
548
|
}
|
|
661
549
|
}
|
|
662
|
-
// Print auth integration examples if auth was enabled (skip for auth template - already set up)
|
|
663
|
-
if (authEnabled && !templateHasAuth) {
|
|
664
|
-
printIntegrationExamples();
|
|
665
|
-
}
|
|
666
550
|
return {
|
|
667
551
|
projectId,
|
|
668
552
|
orgId,
|
|
@@ -676,6 +560,27 @@ export async function runCreateFlow(options) {
|
|
|
676
560
|
error: setupResult.success ? undefined : 'Project setup completed with errors',
|
|
677
561
|
};
|
|
678
562
|
}
|
|
563
|
+
/**
|
|
564
|
+
* Normalize a CLI flag value (`--database` / `--storage`) into the same
|
|
565
|
+
* action vocabulary the interactive flow uses:
|
|
566
|
+
* - 'new' -> 'Create New'
|
|
567
|
+
* - 'skip' -> 'Skip'
|
|
568
|
+
* - any other string -> treated as an existing-resource name (returned as-is)
|
|
569
|
+
* - undefined -> undefined (no flag passed; multi-select decides)
|
|
570
|
+
*
|
|
571
|
+
* The existence check for named resources happens later, after the resource
|
|
572
|
+
* list is fetched.
|
|
573
|
+
*/
|
|
574
|
+
function resolveFlagAction(flag, _kind) {
|
|
575
|
+
if (flag === undefined)
|
|
576
|
+
return undefined;
|
|
577
|
+
const lower = flag.toLowerCase();
|
|
578
|
+
if (lower === 'new')
|
|
579
|
+
return 'Create New';
|
|
580
|
+
if (lower === 'skip')
|
|
581
|
+
return 'Skip';
|
|
582
|
+
return flag;
|
|
583
|
+
}
|
|
679
584
|
/**
|
|
680
585
|
* Sanitize a project name to create a safe directory/package name
|
|
681
586
|
* - Converts to lowercase
|