@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
|
@@ -31,16 +31,14 @@ import * as tui from '../../tui';
|
|
|
31
31
|
import { createPrompt, note } from '../../tui';
|
|
32
32
|
import type { AuthData, Config } from '../../types';
|
|
33
33
|
import { getGithubBotIdentity } from '../git/api';
|
|
34
|
-
import {
|
|
35
|
-
ensureAuthDependencies,
|
|
36
|
-
generateAuthFileContent,
|
|
37
|
-
generateAuthSchemaSql,
|
|
38
|
-
printIntegrationExamples,
|
|
39
|
-
runAuthMigrations,
|
|
40
|
-
} from './auth/shared';
|
|
41
34
|
import { downloadTemplate, initGitRepo, setupProject } from './download';
|
|
35
|
+
import { suggestBucketName, suggestDatabaseName } from './random-name';
|
|
42
36
|
import { fetchTemplates, type TemplateInfo } from './templates';
|
|
43
37
|
|
|
38
|
+
// Domain validator shared between the multi-select branch and the standalone prompt.
|
|
39
|
+
const DOMAIN_REGEX =
|
|
40
|
+
/^(?=.{1,253}$)(?:[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?\.)+[A-Za-z]{2,63}$/;
|
|
41
|
+
|
|
44
42
|
interface CreateFlowOptions {
|
|
45
43
|
projectName?: string;
|
|
46
44
|
dir?: string;
|
|
@@ -59,7 +57,6 @@ interface CreateFlowOptions {
|
|
|
59
57
|
apiClient?: APIClient;
|
|
60
58
|
database?: string;
|
|
61
59
|
storage?: string;
|
|
62
|
-
enableAuth?: boolean;
|
|
63
60
|
}
|
|
64
61
|
|
|
65
62
|
export interface CreateFlowResult {
|
|
@@ -92,7 +89,6 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
|
|
|
92
89
|
domains,
|
|
93
90
|
database: databaseOption,
|
|
94
91
|
storage: storageOption,
|
|
95
|
-
enableAuth: enableAuthOption,
|
|
96
92
|
} = options;
|
|
97
93
|
|
|
98
94
|
const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY;
|
|
@@ -290,7 +286,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
|
|
|
290
286
|
};
|
|
291
287
|
}
|
|
292
288
|
|
|
293
|
-
//
|
|
289
|
+
// Resource provisioning gates
|
|
294
290
|
const canProvision = auth && apiClient && catalystClient && orgId && region;
|
|
295
291
|
// Only count as resource flags if actually requesting provisioning (not explicit skip)
|
|
296
292
|
const hasResourceFlags =
|
|
@@ -314,23 +310,63 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
|
|
|
314
310
|
);
|
|
315
311
|
}
|
|
316
312
|
|
|
317
|
-
// Validate that --enable-auth requires authentication and registration
|
|
318
|
-
if (enableAuthOption && !canProvision) {
|
|
319
|
-
logger.fatal(
|
|
320
|
-
'Cannot enable Agentuity Auth without being authenticated and registering the project.\n' +
|
|
321
|
-
'Remove --no-register or omit --enable-auth flag.',
|
|
322
|
-
ErrorCode.VALIDATION_FAILED
|
|
323
|
-
);
|
|
324
|
-
}
|
|
325
|
-
|
|
326
313
|
if (canProvision) {
|
|
327
|
-
//
|
|
328
|
-
|
|
314
|
+
// CLI flags pre-resolve their respective per-resource decision; the multi-select
|
|
315
|
+
// is only used for resources where the user didn't pass a flag.
|
|
316
|
+
const dbFlagAction = resolveFlagAction(databaseOption, 'database');
|
|
317
|
+
const storageFlagAction = resolveFlagAction(storageOption, 'storage');
|
|
318
|
+
const domainFlagProvided = (domains?.length ?? 0) > 0;
|
|
319
|
+
|
|
320
|
+
// Determine which resources should run through the configuration phase.
|
|
321
|
+
// In interactive mode, ask the user via a single multi-select.
|
|
322
|
+
// In headless / non-interactive mode, only flagged resources are considered.
|
|
323
|
+
let wantDb = dbFlagAction !== undefined && dbFlagAction !== 'Skip';
|
|
324
|
+
let wantStorage = storageFlagAction !== undefined && storageFlagAction !== 'Skip';
|
|
325
|
+
let wantDomain = domainFlagProvided;
|
|
329
326
|
|
|
327
|
+
if (isInteractive) {
|
|
328
|
+
// Build multi-select options dynamically: only show resources the user hasn't
|
|
329
|
+
// already decided about via CLI flags. If all three came from flags, skip the prompt.
|
|
330
|
+
const msOptions: {
|
|
331
|
+
value: 'database' | 'storage' | 'domain';
|
|
332
|
+
label: string;
|
|
333
|
+
hint?: string;
|
|
334
|
+
}[] = [];
|
|
335
|
+
if (dbFlagAction === undefined) {
|
|
336
|
+
msOptions.push({ value: 'database', label: 'SQL Database', hint: 'PostgreSQL' });
|
|
337
|
+
}
|
|
338
|
+
if (storageFlagAction === undefined) {
|
|
339
|
+
msOptions.push({ value: 'storage', label: 'Storage Bucket', hint: 'S3-compatible' });
|
|
340
|
+
}
|
|
341
|
+
if (!domainFlagProvided) {
|
|
342
|
+
msOptions.push({ value: 'domain', label: 'Custom Domain', hint: 'BYO domain' });
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
if (msOptions.length > 0) {
|
|
346
|
+
const picked = await prompt.multiselect<'database' | 'storage' | 'domain'>({
|
|
347
|
+
message: 'What would you like to set up? (all optional)',
|
|
348
|
+
options: msOptions,
|
|
349
|
+
initial: [],
|
|
350
|
+
});
|
|
351
|
+
if (dbFlagAction === undefined) wantDb = picked.includes('database');
|
|
352
|
+
if (storageFlagAction === undefined) wantStorage = picked.includes('storage');
|
|
353
|
+
if (!domainFlagProvided) wantDomain = picked.includes('domain');
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
// Fetch existing resources only if we'll actually need them.
|
|
358
|
+
// Need them when:
|
|
359
|
+
// - user wants db/storage in interactive mode (to offer "use existing")
|
|
360
|
+
// - a CLI flag pointed at an existing resource by name
|
|
361
|
+
let resources: Awaited<ReturnType<typeof listResources>> | undefined;
|
|
330
362
|
const needResources =
|
|
331
|
-
isInteractive ||
|
|
332
|
-
(databaseOption
|
|
333
|
-
|
|
363
|
+
(isInteractive && (wantDb || wantStorage)) ||
|
|
364
|
+
(databaseOption !== undefined &&
|
|
365
|
+
dbFlagAction !== 'Create New' &&
|
|
366
|
+
dbFlagAction !== 'Skip') ||
|
|
367
|
+
(storageOption !== undefined &&
|
|
368
|
+
storageFlagAction !== 'Create New' &&
|
|
369
|
+
storageFlagAction !== 'Skip');
|
|
334
370
|
|
|
335
371
|
if (needResources) {
|
|
336
372
|
resources = await tui.spinner({
|
|
@@ -348,316 +384,173 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
|
|
|
348
384
|
logger.debug(
|
|
349
385
|
`Storage buckets: ${resources.s3.map((b) => b.bucket_name).join(', ') || '(none)'}`
|
|
350
386
|
);
|
|
351
|
-
}
|
|
352
387
|
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
if (!existingDb) {
|
|
365
|
-
logger.fatal(
|
|
366
|
-
`Database '${databaseOption}' not found. Use 'new' to create a new database or 'skip' to skip.`,
|
|
367
|
-
ErrorCode.RESOURCE_NOT_FOUND
|
|
368
|
-
);
|
|
369
|
-
}
|
|
370
|
-
db_action = databaseOption;
|
|
388
|
+
// Validate flag-supplied resource names against the fetched list.
|
|
389
|
+
if (
|
|
390
|
+
databaseOption !== undefined &&
|
|
391
|
+
dbFlagAction !== 'Create New' &&
|
|
392
|
+
dbFlagAction !== 'Skip' &&
|
|
393
|
+
!resources.db.find((d) => d.name === dbFlagAction)
|
|
394
|
+
) {
|
|
395
|
+
logger.fatal(
|
|
396
|
+
`Database '${databaseOption}' not found. Use 'new' to create a new database or 'skip' to skip.`,
|
|
397
|
+
ErrorCode.RESOURCE_NOT_FOUND
|
|
398
|
+
);
|
|
371
399
|
}
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
],
|
|
383
|
-
});
|
|
384
|
-
} else {
|
|
385
|
-
// Headless without flag - skip
|
|
386
|
-
db_action = 'Skip';
|
|
387
|
-
}
|
|
388
|
-
|
|
389
|
-
// Determine storage action: CLI flag > interactive prompt > skip (headless)
|
|
390
|
-
let s3_action: string;
|
|
391
|
-
if (storageOption !== undefined) {
|
|
392
|
-
// CLI flag provided - normalize to expected values
|
|
393
|
-
if (storageOption.toLowerCase() === 'new') {
|
|
394
|
-
s3_action = 'Create New';
|
|
395
|
-
} else if (storageOption.toLowerCase() === 'skip') {
|
|
396
|
-
s3_action = 'Skip';
|
|
397
|
-
} else {
|
|
398
|
-
// Existing bucket name - validate it exists
|
|
399
|
-
const existingBucket = resources?.s3.find((b) => b.bucket_name === storageOption);
|
|
400
|
-
if (!existingBucket) {
|
|
401
|
-
logger.fatal(
|
|
402
|
-
`Storage bucket '${storageOption}' not found. Use 'new' to create a new bucket or 'skip' to skip.`,
|
|
403
|
-
ErrorCode.RESOURCE_NOT_FOUND
|
|
404
|
-
);
|
|
405
|
-
}
|
|
406
|
-
s3_action = storageOption;
|
|
400
|
+
if (
|
|
401
|
+
storageOption !== undefined &&
|
|
402
|
+
storageFlagAction !== 'Create New' &&
|
|
403
|
+
storageFlagAction !== 'Skip' &&
|
|
404
|
+
!resources.s3.find((b) => b.bucket_name === storageFlagAction)
|
|
405
|
+
) {
|
|
406
|
+
logger.fatal(
|
|
407
|
+
`Storage bucket '${storageOption}' not found. Use 'new' to create a new bucket or 'skip' to skip.`,
|
|
408
|
+
ErrorCode.RESOURCE_NOT_FOUND
|
|
409
|
+
);
|
|
407
410
|
}
|
|
408
|
-
} else if (isInteractive) {
|
|
409
|
-
s3_action = await prompt.select({
|
|
410
|
-
message: 'Create Storage Bucket?',
|
|
411
|
-
options: [
|
|
412
|
-
{ value: 'Skip', label: 'Skip or Setup later' },
|
|
413
|
-
{ value: 'Create New', label: 'Create a new bucket' },
|
|
414
|
-
...resources!.s3.map((bucket) => ({
|
|
415
|
-
value: bucket.bucket_name,
|
|
416
|
-
label: `Use bucket: ${tui.tuiColors.primary(bucket.bucket_name)}`,
|
|
417
|
-
})),
|
|
418
|
-
],
|
|
419
|
-
});
|
|
420
|
-
} else {
|
|
421
|
-
// Headless without flag - skip
|
|
422
|
-
s3_action = 'Skip';
|
|
423
411
|
}
|
|
424
412
|
|
|
425
|
-
//
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
413
|
+
// === Configure each selected resource: Database → Storage → Domain ===
|
|
414
|
+
|
|
415
|
+
// Database
|
|
416
|
+
if (wantDb) {
|
|
417
|
+
let dbAction = dbFlagAction;
|
|
418
|
+
if (dbAction === undefined && isInteractive) {
|
|
419
|
+
const existing = resources?.db ?? [];
|
|
420
|
+
if (existing.length > 0) {
|
|
421
|
+
dbAction = await prompt.select<string>({
|
|
422
|
+
message: 'SQL Database',
|
|
423
|
+
options: [
|
|
424
|
+
{ value: 'Create New', label: 'Create a new database' },
|
|
425
|
+
...existing.map((db) => ({
|
|
426
|
+
value: db.name,
|
|
427
|
+
label: `Use database: ${tui.tuiColors.primary(db.name)}`,
|
|
428
|
+
})),
|
|
429
|
+
],
|
|
430
|
+
});
|
|
431
|
+
} else {
|
|
432
|
+
// No existing databases — user already opted in via the multi-select, so create new.
|
|
433
|
+
dbAction = 'Create New';
|
|
434
|
+
}
|
|
439
435
|
}
|
|
440
|
-
}
|
|
441
436
|
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
let bucketName: string | undefined;
|
|
446
|
-
let bucketDescription: string | undefined;
|
|
437
|
+
if (dbAction === 'Create New') {
|
|
438
|
+
let dbName: string | undefined;
|
|
439
|
+
let dbDescription: string | undefined;
|
|
447
440
|
|
|
448
|
-
// Only prompt for name/description in interactive mode
|
|
449
441
|
if (isInteractive) {
|
|
450
|
-
const
|
|
451
|
-
|
|
452
|
-
|
|
442
|
+
const suggestion = suggestDatabaseName(projectName);
|
|
443
|
+
const dbNameInput = await prompt.text({
|
|
444
|
+
message: 'Database name',
|
|
445
|
+
hint: 'Optional · lowercase letters, digits, underscores',
|
|
446
|
+
placeholder: suggestion,
|
|
453
447
|
validate: (value: string) => {
|
|
454
448
|
const trimmed = value.trim();
|
|
455
449
|
if (trimmed === '') return true;
|
|
456
|
-
const result =
|
|
450
|
+
const result = validateDatabaseName(trimmed);
|
|
457
451
|
return result.valid ? true : result.error!;
|
|
458
452
|
},
|
|
459
453
|
});
|
|
460
|
-
|
|
461
|
-
|
|
454
|
+
dbName = dbNameInput.trim() || undefined;
|
|
455
|
+
dbDescription =
|
|
462
456
|
(await prompt.text({
|
|
463
|
-
message: '
|
|
464
|
-
hint: 'Optional
|
|
457
|
+
message: 'Database description',
|
|
458
|
+
hint: 'Optional · press Enter to skip',
|
|
465
459
|
})) || undefined;
|
|
466
460
|
}
|
|
467
461
|
|
|
468
462
|
const created = await tui.spinner({
|
|
469
|
-
message: 'Provisioning New
|
|
463
|
+
message: 'Provisioning New SQL Database',
|
|
470
464
|
clearOnSuccess: true,
|
|
471
465
|
callback: async () => {
|
|
472
466
|
return createResources(catalystClient!, orgId!, region!, [
|
|
473
|
-
{
|
|
474
|
-
type: 's3',
|
|
475
|
-
name: bucketName,
|
|
476
|
-
description: bucketDescription,
|
|
477
|
-
},
|
|
467
|
+
{ type: 'db', name: dbName, description: dbDescription },
|
|
478
468
|
]);
|
|
479
469
|
},
|
|
480
470
|
});
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
}
|
|
487
|
-
case 'Skip': {
|
|
488
|
-
break;
|
|
471
|
+
if (created[0]?.env) Object.assign(resourceEnvVars, created[0].env);
|
|
472
|
+
} else if (dbAction && dbAction !== 'Skip') {
|
|
473
|
+
// Existing database selected — reuse its env vars.
|
|
474
|
+
const selectedDb = resources?.db.find((d) => d.name === dbAction);
|
|
475
|
+
if (selectedDb?.env) Object.assign(resourceEnvVars, selectedDb.env);
|
|
489
476
|
}
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
477
|
+
}
|
|
478
|
+
|
|
479
|
+
// Storage
|
|
480
|
+
if (wantStorage) {
|
|
481
|
+
let s3Action = storageFlagAction;
|
|
482
|
+
if (s3Action === undefined && isInteractive) {
|
|
483
|
+
const existing = resources?.s3 ?? [];
|
|
484
|
+
if (existing.length > 0) {
|
|
485
|
+
s3Action = await prompt.select<string>({
|
|
486
|
+
message: 'Storage Bucket',
|
|
487
|
+
options: [
|
|
488
|
+
{ value: 'Create New', label: 'Create a new bucket' },
|
|
489
|
+
...existing.map((bucket) => ({
|
|
490
|
+
value: bucket.bucket_name,
|
|
491
|
+
label: `Use bucket: ${tui.tuiColors.primary(bucket.bucket_name)}`,
|
|
492
|
+
})),
|
|
493
|
+
],
|
|
494
|
+
});
|
|
495
|
+
} else {
|
|
496
|
+
s3Action = 'Create New';
|
|
495
497
|
}
|
|
496
|
-
break;
|
|
497
498
|
}
|
|
498
|
-
}
|
|
499
499
|
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
let dbName: string | undefined;
|
|
504
|
-
let dbDescription: string | undefined;
|
|
500
|
+
if (s3Action === 'Create New') {
|
|
501
|
+
let bucketName: string | undefined;
|
|
502
|
+
let bucketDescription: string | undefined;
|
|
505
503
|
|
|
506
|
-
// Only prompt for name/description in interactive mode
|
|
507
504
|
if (isInteractive) {
|
|
508
|
-
const
|
|
509
|
-
|
|
510
|
-
|
|
505
|
+
const suggestion = suggestBucketName(projectName);
|
|
506
|
+
const bucketNameInput = await prompt.text({
|
|
507
|
+
message: 'Bucket name',
|
|
508
|
+
hint: 'Optional · lowercase letters, digits, hyphens',
|
|
509
|
+
placeholder: suggestion,
|
|
511
510
|
validate: (value: string) => {
|
|
512
511
|
const trimmed = value.trim();
|
|
513
512
|
if (trimmed === '') return true;
|
|
514
|
-
const result =
|
|
513
|
+
const result = validateBucketName(trimmed);
|
|
515
514
|
return result.valid ? true : result.error!;
|
|
516
515
|
},
|
|
517
516
|
});
|
|
518
|
-
|
|
519
|
-
|
|
517
|
+
bucketName = bucketNameInput.trim() || undefined;
|
|
518
|
+
bucketDescription =
|
|
520
519
|
(await prompt.text({
|
|
521
|
-
message: '
|
|
522
|
-
hint: 'Optional
|
|
520
|
+
message: 'Bucket description',
|
|
521
|
+
hint: 'Optional · press Enter to skip',
|
|
523
522
|
})) || undefined;
|
|
524
523
|
}
|
|
525
524
|
|
|
526
525
|
const created = await tui.spinner({
|
|
527
|
-
message: 'Provisioning New
|
|
526
|
+
message: 'Provisioning New Bucket',
|
|
528
527
|
clearOnSuccess: true,
|
|
529
528
|
callback: async () => {
|
|
530
529
|
return createResources(catalystClient!, orgId!, region!, [
|
|
531
|
-
{
|
|
532
|
-
type: 'db',
|
|
533
|
-
name: dbName,
|
|
534
|
-
description: dbDescription,
|
|
535
|
-
},
|
|
530
|
+
{ type: 's3', name: bucketName, description: bucketDescription },
|
|
536
531
|
]);
|
|
537
532
|
},
|
|
538
533
|
});
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
break;
|
|
544
|
-
}
|
|
545
|
-
case 'Skip': {
|
|
546
|
-
break;
|
|
547
|
-
}
|
|
548
|
-
default: {
|
|
549
|
-
// User selected an existing database - get env vars from the resources list
|
|
550
|
-
const selectedDb = resources?.db.find((d) => d.name === db_action);
|
|
551
|
-
if (selectedDb?.env) {
|
|
552
|
-
Object.assign(resourceEnvVars, selectedDb.env);
|
|
553
|
-
}
|
|
554
|
-
break;
|
|
555
|
-
}
|
|
556
|
-
}
|
|
557
|
-
}
|
|
558
|
-
|
|
559
|
-
// Auth setup - either from template, CLI flag, or user choice
|
|
560
|
-
const templateHasAuth = selectedTemplate.id === 'agentuity-auth';
|
|
561
|
-
|
|
562
|
-
let authEnabled = templateHasAuth; // Auth templates have auth enabled by default
|
|
563
|
-
let authDatabaseName: string | undefined;
|
|
564
|
-
let authDatabaseUrl: string | undefined;
|
|
565
|
-
|
|
566
|
-
// Handle auth enablement: CLI flag > interactive prompt > disabled (headless)
|
|
567
|
-
if (enableAuthOption !== undefined) {
|
|
568
|
-
// CLI flag provided
|
|
569
|
-
authEnabled = enableAuthOption;
|
|
570
|
-
} else if (canProvision && isInteractive && !templateHasAuth) {
|
|
571
|
-
// For non-auth templates in interactive mode, ask if they want to enable auth
|
|
572
|
-
const enableAuth = await prompt.select({
|
|
573
|
-
message: 'Enable Agentuity Authentication?',
|
|
574
|
-
options: [
|
|
575
|
-
{ value: 'no', label: "No, I'll add auth later" },
|
|
576
|
-
{ value: 'yes', label: 'Yes, set up Agentuity Auth' },
|
|
577
|
-
],
|
|
578
|
-
});
|
|
579
|
-
|
|
580
|
-
if (enableAuth === 'yes') {
|
|
581
|
-
authEnabled = true;
|
|
582
|
-
}
|
|
583
|
-
}
|
|
584
|
-
// In headless mode without --enable-auth flag, authEnabled stays false (unless template has auth)
|
|
585
|
-
|
|
586
|
-
// Set up database and secret for any auth-enabled project
|
|
587
|
-
if (authEnabled && canProvision) {
|
|
588
|
-
// If a database was already selected/created above, use it for auth
|
|
589
|
-
if (resourceEnvVars.DATABASE_URL) {
|
|
590
|
-
authDatabaseUrl = resourceEnvVars.DATABASE_URL;
|
|
591
|
-
// Extract database name from URL using proper URL parsing
|
|
592
|
-
try {
|
|
593
|
-
const dbUrl = new URL(authDatabaseUrl);
|
|
594
|
-
const dbName = dbUrl.pathname.replace(/^\/+/, ''); // Remove leading slashes
|
|
595
|
-
// Validate: non-empty and contains only safe characters
|
|
596
|
-
if (dbName && /^[A-Za-z0-9_-]+$/.test(dbName)) {
|
|
597
|
-
authDatabaseName = dbName;
|
|
598
|
-
}
|
|
599
|
-
} catch {
|
|
600
|
-
// Invalid URL format, authDatabaseName stays undefined
|
|
601
|
-
}
|
|
602
|
-
} else {
|
|
603
|
-
// No database selected yet, create one for auth
|
|
604
|
-
const created = await tui.spinner({
|
|
605
|
-
message: 'Provisioning database for auth',
|
|
606
|
-
clearOnSuccess: true,
|
|
607
|
-
callback: async () => {
|
|
608
|
-
return createResources(catalystClient!, orgId!, region!, [{ type: 'db' }]);
|
|
609
|
-
},
|
|
610
|
-
});
|
|
611
|
-
const createdDb = created[0];
|
|
612
|
-
if (!createdDb) {
|
|
613
|
-
logger.fatal('Failed to create database for auth', ErrorCode.RESOURCE_NOT_FOUND);
|
|
614
|
-
return undefined as never;
|
|
615
|
-
}
|
|
616
|
-
authDatabaseName = createdDb.name;
|
|
617
|
-
|
|
618
|
-
// Get env vars from created resource
|
|
619
|
-
if (createdDb.env) {
|
|
620
|
-
authDatabaseUrl = createdDb.env.DATABASE_URL;
|
|
621
|
-
// Also add to resourceEnvVars if not already set
|
|
622
|
-
if (!resourceEnvVars.DATABASE_URL) {
|
|
623
|
-
Object.assign(resourceEnvVars, createdDb.env);
|
|
624
|
-
}
|
|
534
|
+
if (created[0]?.env) Object.assign(resourceEnvVars, created[0].env);
|
|
535
|
+
} else if (s3Action && s3Action !== 'Skip') {
|
|
536
|
+
const selectedBucket = resources?.s3.find((b) => b.bucket_name === s3Action);
|
|
537
|
+
if (selectedBucket?.env) Object.assign(resourceEnvVars, selectedBucket.env);
|
|
625
538
|
}
|
|
626
539
|
}
|
|
627
540
|
|
|
628
|
-
//
|
|
629
|
-
if (!
|
|
630
|
-
await
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
await Bun.write(authFilePath, generateAuthFileContent());
|
|
640
|
-
tui.success('Created src/auth.ts');
|
|
641
|
-
}
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
// Run migrations
|
|
645
|
-
if (authDatabaseName) {
|
|
646
|
-
const sql = await tui.spinner({
|
|
647
|
-
message: 'Preparing auth database schema...',
|
|
648
|
-
clearOnSuccess: true,
|
|
649
|
-
callback: () => generateAuthSchemaSql(logger, dest),
|
|
650
|
-
});
|
|
651
|
-
|
|
652
|
-
await runAuthMigrations({
|
|
653
|
-
logger,
|
|
654
|
-
auth,
|
|
655
|
-
orgId,
|
|
656
|
-
region,
|
|
657
|
-
databaseName: authDatabaseName,
|
|
658
|
-
sql,
|
|
659
|
-
config,
|
|
541
|
+
// Custom Domain
|
|
542
|
+
if (wantDomain && !domainFlagProvided && isInteractive) {
|
|
543
|
+
const customDns = await prompt.text({
|
|
544
|
+
message: 'Custom domain',
|
|
545
|
+
hint: 'e.g. agents.example.com',
|
|
546
|
+
validate: (val: string) =>
|
|
547
|
+
val === ''
|
|
548
|
+
? 'Domain is required (or go back and uncheck Custom Domain)'
|
|
549
|
+
: DOMAIN_REGEX.test(val)
|
|
550
|
+
? true
|
|
551
|
+
: 'Invalid domain',
|
|
660
552
|
});
|
|
553
|
+
if (customDns) _domains = [customDns];
|
|
661
554
|
}
|
|
662
555
|
}
|
|
663
556
|
|
|
@@ -702,28 +595,9 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
|
|
|
702
595
|
},
|
|
703
596
|
});
|
|
704
597
|
|
|
705
|
-
// Add auth secret to resourceEnvVars if auth is enabled
|
|
706
|
-
if (authEnabled && !resourceEnvVars.AGENTUITY_AUTH_SECRET) {
|
|
707
|
-
const devSecret = `dev-${crypto.randomUUID()}`;
|
|
708
|
-
resourceEnvVars.AGENTUITY_AUTH_SECRET = devSecret;
|
|
709
|
-
}
|
|
710
|
-
|
|
711
598
|
// Write resource environment variables to .env
|
|
712
599
|
if (Object.keys(resourceEnvVars).length > 0) {
|
|
713
600
|
await addResourceEnvVars(dest, resourceEnvVars);
|
|
714
|
-
|
|
715
|
-
// Show user feedback for auth-related env vars
|
|
716
|
-
if (authEnabled) {
|
|
717
|
-
if (resourceEnvVars.DATABASE_URL) {
|
|
718
|
-
tui.success('DATABASE_URL added to .env');
|
|
719
|
-
}
|
|
720
|
-
if (resourceEnvVars.AGENTUITY_AUTH_SECRET) {
|
|
721
|
-
tui.success('AGENTUITY_AUTH_SECRET added to .env');
|
|
722
|
-
tui.info(
|
|
723
|
-
`Generate one with: ${tui.muted('npx @better-auth/cli secret')} or ${tui.muted('openssl rand -hex 32')}`
|
|
724
|
-
);
|
|
725
|
-
}
|
|
726
|
-
}
|
|
727
601
|
}
|
|
728
602
|
|
|
729
603
|
// After registration, push any existing env/secrets from .env
|
|
@@ -819,11 +693,6 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
|
|
|
819
693
|
}
|
|
820
694
|
}
|
|
821
695
|
|
|
822
|
-
// Print auth integration examples if auth was enabled (skip for auth template - already set up)
|
|
823
|
-
if (authEnabled && !templateHasAuth) {
|
|
824
|
-
printIntegrationExamples();
|
|
825
|
-
}
|
|
826
|
-
|
|
827
696
|
return {
|
|
828
697
|
projectId,
|
|
829
698
|
orgId,
|
|
@@ -838,6 +707,28 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
|
|
|
838
707
|
};
|
|
839
708
|
}
|
|
840
709
|
|
|
710
|
+
/**
|
|
711
|
+
* Normalize a CLI flag value (`--database` / `--storage`) into the same
|
|
712
|
+
* action vocabulary the interactive flow uses:
|
|
713
|
+
* - 'new' -> 'Create New'
|
|
714
|
+
* - 'skip' -> 'Skip'
|
|
715
|
+
* - any other string -> treated as an existing-resource name (returned as-is)
|
|
716
|
+
* - undefined -> undefined (no flag passed; multi-select decides)
|
|
717
|
+
*
|
|
718
|
+
* The existence check for named resources happens later, after the resource
|
|
719
|
+
* list is fetched.
|
|
720
|
+
*/
|
|
721
|
+
function resolveFlagAction(
|
|
722
|
+
flag: string | undefined,
|
|
723
|
+
_kind: 'database' | 'storage'
|
|
724
|
+
): string | undefined {
|
|
725
|
+
if (flag === undefined) return undefined;
|
|
726
|
+
const lower = flag.toLowerCase();
|
|
727
|
+
if (lower === 'new') return 'Create New';
|
|
728
|
+
if (lower === 'skip') return 'Skip';
|
|
729
|
+
return flag;
|
|
730
|
+
}
|
|
731
|
+
|
|
841
732
|
/**
|
|
842
733
|
* Sanitize a project name to create a safe directory/package name
|
|
843
734
|
* - Converts to lowercase
|
package/src/composite-logger.ts
CHANGED
|
@@ -7,6 +7,12 @@
|
|
|
7
7
|
*/
|
|
8
8
|
|
|
9
9
|
import type { Logger } from '@agentuity/core';
|
|
10
|
+
import { format } from 'node:util';
|
|
11
|
+
import { ErrorCode, getExitCode } from './errors';
|
|
12
|
+
|
|
13
|
+
function isErrorCode(value: unknown): value is ErrorCode {
|
|
14
|
+
return typeof value === 'string' && Object.values(ErrorCode).includes(value as ErrorCode);
|
|
15
|
+
}
|
|
10
16
|
|
|
11
17
|
/**
|
|
12
18
|
* A logger that delegates to multiple child loggers
|
|
@@ -45,6 +51,20 @@ export class CompositeLogger implements Logger {
|
|
|
45
51
|
}
|
|
46
52
|
|
|
47
53
|
fatal(message: unknown, ...args: unknown[]): never {
|
|
54
|
+
const maybeErrorCode = args[args.length - 1];
|
|
55
|
+
if (isErrorCode(maybeErrorCode)) {
|
|
56
|
+
const formatArgs = args.slice(0, -1);
|
|
57
|
+
const formattedMessage = format(message, ...formatArgs);
|
|
58
|
+
for (const logger of this.loggers) {
|
|
59
|
+
try {
|
|
60
|
+
logger.error(formattedMessage);
|
|
61
|
+
} catch {
|
|
62
|
+
// Keep fatal exits reliable even if one delegate cannot write.
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
process.exit(getExitCode(maybeErrorCode));
|
|
66
|
+
}
|
|
67
|
+
|
|
48
68
|
// Call fatal on all loggers, but only the first one will exit
|
|
49
69
|
for (const logger of this.loggers) {
|
|
50
70
|
try {
|