@agentuity/cli 0.1.14 → 0.1.16

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (158) hide show
  1. package/dist/auth.d.ts.map +1 -1
  2. package/dist/auth.js +7 -6
  3. package/dist/auth.js.map +1 -1
  4. package/dist/cli.d.ts.map +1 -1
  5. package/dist/cli.js +69 -11
  6. package/dist/cli.js.map +1 -1
  7. package/dist/cmd/ai/index.d.ts.map +1 -1
  8. package/dist/cmd/ai/index.js +6 -1
  9. package/dist/cmd/ai/index.js.map +1 -1
  10. package/dist/cmd/ai/opencode/index.d.ts +3 -0
  11. package/dist/cmd/ai/opencode/index.d.ts.map +1 -0
  12. package/dist/cmd/ai/opencode/index.js +27 -0
  13. package/dist/cmd/ai/opencode/index.js.map +1 -0
  14. package/dist/cmd/ai/opencode/install.d.ts +3 -0
  15. package/dist/cmd/ai/opencode/install.d.ts.map +1 -0
  16. package/dist/cmd/ai/opencode/install.js +102 -0
  17. package/dist/cmd/ai/opencode/install.js.map +1 -0
  18. package/dist/cmd/ai/opencode/run.d.ts +3 -0
  19. package/dist/cmd/ai/opencode/run.d.ts.map +1 -0
  20. package/dist/cmd/ai/opencode/run.js +88 -0
  21. package/dist/cmd/ai/opencode/run.js.map +1 -0
  22. package/dist/cmd/ai/opencode/uninstall.d.ts +3 -0
  23. package/dist/cmd/ai/opencode/uninstall.d.ts.map +1 -0
  24. package/dist/cmd/ai/opencode/uninstall.js +82 -0
  25. package/dist/cmd/ai/opencode/uninstall.js.map +1 -0
  26. package/dist/cmd/build/vite/beacon-plugin.d.ts.map +1 -1
  27. package/dist/cmd/build/vite/beacon-plugin.js.map +1 -1
  28. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  29. package/dist/cmd/build/vite/vite-builder.js +1 -1
  30. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  31. package/dist/cmd/cloud/env/delete.d.ts.map +1 -1
  32. package/dist/cmd/cloud/env/delete.js +87 -34
  33. package/dist/cmd/cloud/env/delete.js.map +1 -1
  34. package/dist/cmd/cloud/env/get.d.ts.map +1 -1
  35. package/dist/cmd/cloud/env/get.js +50 -16
  36. package/dist/cmd/cloud/env/get.js.map +1 -1
  37. package/dist/cmd/cloud/env/import.d.ts.map +1 -1
  38. package/dist/cmd/cloud/env/import.js +76 -32
  39. package/dist/cmd/cloud/env/import.js.map +1 -1
  40. package/dist/cmd/cloud/env/index.d.ts.map +1 -1
  41. package/dist/cmd/cloud/env/index.js +6 -2
  42. package/dist/cmd/cloud/env/index.js.map +1 -1
  43. package/dist/cmd/cloud/env/list.d.ts.map +1 -1
  44. package/dist/cmd/cloud/env/list.js +94 -23
  45. package/dist/cmd/cloud/env/list.js.map +1 -1
  46. package/dist/cmd/cloud/env/org-util.d.ts +16 -0
  47. package/dist/cmd/cloud/env/org-util.d.ts.map +1 -0
  48. package/dist/cmd/cloud/env/org-util.js +28 -0
  49. package/dist/cmd/cloud/env/org-util.js.map +1 -0
  50. package/dist/cmd/cloud/env/pull.d.ts.map +1 -1
  51. package/dist/cmd/cloud/env/pull.js +61 -29
  52. package/dist/cmd/cloud/env/pull.js.map +1 -1
  53. package/dist/cmd/cloud/env/push.d.ts.map +1 -1
  54. package/dist/cmd/cloud/env/push.js +69 -23
  55. package/dist/cmd/cloud/env/push.js.map +1 -1
  56. package/dist/cmd/cloud/env/set.d.ts.map +1 -1
  57. package/dist/cmd/cloud/env/set.js +69 -26
  58. package/dist/cmd/cloud/env/set.js.map +1 -1
  59. package/dist/cmd/cloud/keyvalue/create-namespace.js +1 -1
  60. package/dist/cmd/cloud/keyvalue/create-namespace.js.map +1 -1
  61. package/dist/cmd/cloud/keyvalue/delete-namespace.js +2 -2
  62. package/dist/cmd/cloud/keyvalue/delete-namespace.js.map +1 -1
  63. package/dist/cmd/cloud/keyvalue/delete.js +1 -1
  64. package/dist/cmd/cloud/keyvalue/delete.js.map +1 -1
  65. package/dist/cmd/cloud/keyvalue/get.js +1 -1
  66. package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
  67. package/dist/cmd/cloud/keyvalue/index.js +1 -1
  68. package/dist/cmd/cloud/keyvalue/index.js.map +1 -1
  69. package/dist/cmd/cloud/keyvalue/keys.js +1 -1
  70. package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
  71. package/dist/cmd/cloud/keyvalue/list-namespaces.js +1 -1
  72. package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
  73. package/dist/cmd/cloud/keyvalue/repl.d.ts.map +1 -1
  74. package/dist/cmd/cloud/keyvalue/repl.js +8 -5
  75. package/dist/cmd/cloud/keyvalue/repl.js.map +1 -1
  76. package/dist/cmd/cloud/keyvalue/search.js +1 -1
  77. package/dist/cmd/cloud/keyvalue/search.js.map +1 -1
  78. package/dist/cmd/cloud/keyvalue/set.js +1 -1
  79. package/dist/cmd/cloud/keyvalue/set.js.map +1 -1
  80. package/dist/cmd/cloud/keyvalue/stats.js +1 -1
  81. package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
  82. package/dist/cmd/cloud/keyvalue/util.d.ts +4 -4
  83. package/dist/cmd/cloud/keyvalue/util.d.ts.map +1 -1
  84. package/dist/cmd/cloud/keyvalue/util.js +4 -9
  85. package/dist/cmd/cloud/keyvalue/util.js.map +1 -1
  86. package/dist/cmd/project/create.d.ts.map +1 -1
  87. package/dist/cmd/project/create.js +20 -2
  88. package/dist/cmd/project/create.js.map +1 -1
  89. package/dist/cmd/project/download.d.ts +3 -1
  90. package/dist/cmd/project/download.d.ts.map +1 -1
  91. package/dist/cmd/project/download.js +5 -0
  92. package/dist/cmd/project/download.js.map +1 -1
  93. package/dist/cmd/project/template-flow.d.ts +5 -0
  94. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  95. package/dist/cmd/project/template-flow.js +188 -79
  96. package/dist/cmd/project/template-flow.js.map +1 -1
  97. package/dist/cmd/setup/index.d.ts.map +1 -1
  98. package/dist/cmd/setup/index.js +2 -1
  99. package/dist/cmd/setup/index.js.map +1 -1
  100. package/dist/onboarding/agentPrompt.d.ts +8 -0
  101. package/dist/onboarding/agentPrompt.d.ts.map +1 -0
  102. package/dist/onboarding/agentPrompt.js +263 -0
  103. package/dist/onboarding/agentPrompt.js.map +1 -0
  104. package/dist/schema-generator.d.ts +1 -1
  105. package/dist/schema-generator.d.ts.map +1 -1
  106. package/dist/schema-parser.d.ts +1 -1
  107. package/dist/schema-parser.d.ts.map +1 -1
  108. package/dist/schema-parser.js +36 -1
  109. package/dist/schema-parser.js.map +1 -1
  110. package/dist/tui/prompt.d.ts.map +1 -1
  111. package/dist/tui/prompt.js +7 -1
  112. package/dist/tui/prompt.js.map +1 -1
  113. package/dist/tui.d.ts.map +1 -1
  114. package/dist/tui.js +91 -28
  115. package/dist/tui.js.map +1 -1
  116. package/dist/types.d.ts.map +1 -1
  117. package/dist/types.js.map +1 -1
  118. package/package.json +7 -7
  119. package/src/auth.ts +7 -6
  120. package/src/cli.ts +84 -11
  121. package/src/cmd/ai/index.ts +6 -1
  122. package/src/cmd/ai/opencode/index.ts +28 -0
  123. package/src/cmd/ai/opencode/install.ts +120 -0
  124. package/src/cmd/ai/opencode/run.ts +103 -0
  125. package/src/cmd/ai/opencode/uninstall.ts +90 -0
  126. package/src/cmd/build/vite/beacon-plugin.ts +3 -1
  127. package/src/cmd/build/vite/vite-builder.ts +5 -1
  128. package/src/cmd/cloud/env/delete.ts +100 -41
  129. package/src/cmd/cloud/env/get.ts +53 -16
  130. package/src/cmd/cloud/env/import.ts +86 -37
  131. package/src/cmd/cloud/env/index.ts +6 -2
  132. package/src/cmd/cloud/env/list.ts +102 -27
  133. package/src/cmd/cloud/env/org-util.ts +37 -0
  134. package/src/cmd/cloud/env/pull.ts +67 -31
  135. package/src/cmd/cloud/env/push.ts +81 -28
  136. package/src/cmd/cloud/env/set.ts +82 -33
  137. package/src/cmd/cloud/keyvalue/create-namespace.ts +1 -1
  138. package/src/cmd/cloud/keyvalue/delete-namespace.ts +2 -2
  139. package/src/cmd/cloud/keyvalue/delete.ts +1 -1
  140. package/src/cmd/cloud/keyvalue/get.ts +1 -1
  141. package/src/cmd/cloud/keyvalue/index.ts +1 -1
  142. package/src/cmd/cloud/keyvalue/keys.ts +1 -1
  143. package/src/cmd/cloud/keyvalue/list-namespaces.ts +1 -1
  144. package/src/cmd/cloud/keyvalue/repl.ts +8 -5
  145. package/src/cmd/cloud/keyvalue/search.ts +1 -1
  146. package/src/cmd/cloud/keyvalue/set.ts +1 -1
  147. package/src/cmd/cloud/keyvalue/stats.ts +1 -1
  148. package/src/cmd/cloud/keyvalue/util.ts +8 -17
  149. package/src/cmd/project/create.ts +21 -2
  150. package/src/cmd/project/download.ts +7 -1
  151. package/src/cmd/project/template-flow.ts +215 -80
  152. package/src/cmd/setup/index.ts +2 -1
  153. package/src/onboarding/agentPrompt.ts +263 -0
  154. package/src/schema-generator.ts +1 -1
  155. package/src/schema-parser.ts +42 -3
  156. package/src/tui/prompt.ts +10 -3
  157. package/src/tui.ts +95 -31
  158. package/src/types.ts +1 -0
@@ -55,6 +55,9 @@ interface CreateFlowOptions {
55
55
  orgId?: string;
56
56
  region?: string;
57
57
  apiClient?: APIClient;
58
+ database?: string;
59
+ storage?: string;
60
+ enableAuth?: boolean;
58
61
  }
59
62
 
60
63
  export interface CreateFlowResult {
@@ -66,6 +69,8 @@ export interface CreateFlowResult {
66
69
  installed: boolean;
67
70
  built: boolean;
68
71
  domains?: string[];
72
+ success: boolean;
73
+ error?: string;
69
74
  }
70
75
 
71
76
  export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateFlowResult> {
@@ -83,8 +88,14 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
83
88
  region,
84
89
  apiClient,
85
90
  domains,
91
+ database: databaseOption,
92
+ storage: storageOption,
93
+ enableAuth: enableAuthOption,
86
94
  } = options;
87
95
 
96
+ const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY;
97
+ const isInteractive = !skipPrompts && !isHeadless;
98
+
88
99
  // Fetch available templates
89
100
  if (templateDir) {
90
101
  tui.info(`📋 Loading templates from local directory: ${templateDir}...\n`);
@@ -118,11 +129,11 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
118
129
  // Create prompt flow
119
130
  const prompt = createPrompt();
120
131
 
121
- if (!skipPrompts) {
132
+ if (isInteractive) {
122
133
  prompt.intro('Create Agentuity Project');
123
134
  }
124
135
 
125
- if (!projectName && !skipPrompts) {
136
+ if (!projectName && isInteractive) {
126
137
  projectName = await prompt.text({
127
138
  message: 'What is the name of your project?',
128
139
  hint: 'The name must be unique for your organization',
@@ -162,8 +173,8 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
162
173
  const destEmpty = destIsDir ? readdirSync(dest).length === 0 : !destExists;
163
174
 
164
175
  if (destExists && !destEmpty && dirName !== '.') {
165
- // In TTY mode, ask if they want to overwrite
166
- if (process.stdin.isTTY && !skipPrompts) {
176
+ // In interactive mode, ask if they want to overwrite
177
+ if (isInteractive) {
167
178
  tui.warning(`Directory ${dest} already exists and is not empty.`, true);
168
179
  console.log(tui.tuiColors.secondary('│'));
169
180
  const overwrite = await prompt.confirm({
@@ -208,7 +219,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
208
219
  return undefined as never;
209
220
  }
210
221
  selectedTemplate = found;
211
- } else if (skipPrompts || templates.length === 1) {
222
+ } else if (!isInteractive || templates.length === 1) {
212
223
  selectedTemplate = templates[0];
213
224
  } else {
214
225
  let maxLength = 15;
@@ -249,7 +260,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
249
260
  });
250
261
 
251
262
  // Setup project (replace placeholders, install deps, build)
252
- await setupProject({
263
+ const setupResult = await setupProject({
253
264
  dest,
254
265
  projectName: projectName === '.' ? basename(dest) : projectName,
255
266
  dirName: dirName === '.' ? basename(dest) : dirName,
@@ -258,57 +269,156 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
258
269
  logger,
259
270
  });
260
271
 
261
- // Re-display template selection after spinners clear it (only if user actually selected)
262
- if (!skipPrompts && templates.length > 1) {
272
+ // If setup failed, skip resource prompts and registration - just show error and return
273
+ if (!setupResult.success) {
274
+ tui.warning('Project setup failed. Skipping resource configuration.');
275
+ return {
276
+ name: projectName,
277
+ path: dest,
278
+ template: selectedTemplate.id,
279
+ installed: !options.noInstall,
280
+ built: false,
281
+ success: false,
282
+ error: 'Project setup completed with errors',
283
+ };
284
+ }
285
+
286
+ // Add separator bar if we're going to show resource prompts
287
+ const canProvision = auth && apiClient && catalystClient && orgId && region;
288
+ // Only count as resource flags if actually requesting provisioning (not explicit skip)
289
+ const hasResourceFlags =
290
+ (databaseOption !== undefined && databaseOption.toLowerCase() !== 'skip') ||
291
+ (storageOption !== undefined && storageOption.toLowerCase() !== 'skip');
292
+
293
+ if (isInteractive && canProvision) {
263
294
  const { symbols, tuiColors } = tui;
264
- console.log(`${tuiColors.completed(symbols.completed)} Select a template:`);
265
- console.log(`${tuiColors.secondary(symbols.bar)} ${tuiColors.muted(selectedTemplate.name)}`);
266
- // Only add bar if we're going to show resource prompts
267
- if (auth && apiClient && catalystClient && orgId && region) {
268
- console.log(tuiColors.secondary(symbols.bar));
269
- }
295
+ console.log(tuiColors.secondary(symbols.bar));
270
296
  }
271
297
 
272
298
  let _domains = domains;
273
299
  const resourceEnvVars: EnvVars = {};
274
300
 
275
- if (auth && apiClient && catalystClient && orgId && region && !skipPrompts) {
276
- // Fetch resources for selected org and region using Catalyst API
277
- const resources = await tui.spinner({
278
- message: 'Fetching resources',
279
- clearOnSuccess: true,
280
- callback: async () => {
281
- return listResources(catalystClient, orgId, region);
282
- },
283
- });
301
+ // Validate that resource flags require authentication and registration
302
+ if (hasResourceFlags && !canProvision) {
303
+ logger.fatal(
304
+ 'Cannot provision database/storage without being authenticated and registering the project.\n' +
305
+ 'Remove --no-register or omit --database/--storage flags.',
306
+ ErrorCode.VALIDATION_FAILED
307
+ );
308
+ }
284
309
 
285
- logger.debug(`Resources for org ${orgId} in region ${region}:`, resources);
310
+ // Validate that --enable-auth requires authentication and registration
311
+ if (enableAuthOption && !canProvision) {
312
+ logger.fatal(
313
+ 'Cannot enable Agentuity Auth without being authenticated and registering the project.\n' +
314
+ 'Remove --no-register or omit --enable-auth flag.',
315
+ ErrorCode.VALIDATION_FAILED
316
+ );
317
+ }
286
318
 
287
- const db_action = await prompt.select({
288
- message: 'Create SQL Database?',
289
- options: [
290
- { value: 'Skip', label: 'Skip or Setup later' },
291
- { value: 'Create New', label: 'Create a new database' },
292
- ...resources.db.map((db) => ({
293
- value: db.name,
294
- label: `Use database: ${tui.tuiColors.primary(db.name)}`,
295
- })),
296
- ],
297
- });
319
+ if (canProvision) {
320
+ // Fetch resources for selected org and region using Catalyst API (needed for both interactive and CLI flags)
321
+ let resources: Awaited<ReturnType<typeof listResources>> | undefined;
298
322
 
299
- const s3_action = await prompt.select({
300
- message: 'Create Storage Bucket?',
301
- options: [
302
- { value: 'Skip', label: 'Skip or Setup later' },
303
- { value: 'Create New', label: 'Create a new bucket' },
304
- ...resources.s3.map((bucket) => ({
305
- value: bucket.bucket_name,
306
- label: `Use bucket: ${tui.tuiColors.primary(bucket.bucket_name)}`,
307
- })),
308
- ],
309
- });
323
+ const needResources =
324
+ isInteractive ||
325
+ (databaseOption && databaseOption !== 'skip' && databaseOption !== 'new') ||
326
+ (storageOption && storageOption !== 'skip' && storageOption !== 'new');
310
327
 
311
- if (!domains?.length) {
328
+ if (needResources) {
329
+ resources = await tui.spinner({
330
+ message: 'Fetching resources',
331
+ clearOnSuccess: true,
332
+ callback: async () => {
333
+ return listResources(catalystClient!, orgId!, region!);
334
+ },
335
+ });
336
+ // Log sanitized summary (avoid exposing DATABASE_URL, tokens, secrets)
337
+ logger.debug(
338
+ `Resources for org ${orgId} in region ${region}: ${resources.db.length} databases, ${resources.s3.length} storage buckets`
339
+ );
340
+ logger.debug(
341
+ `Database names: ${resources.db.map((d) => d.name).join(', ') || '(none)'}`
342
+ );
343
+ logger.debug(
344
+ `Storage buckets: ${resources.s3.map((b) => b.bucket_name).join(', ') || '(none)'}`
345
+ );
346
+ }
347
+
348
+ // Determine database action: CLI flag > interactive prompt > skip (headless)
349
+ let db_action: string;
350
+ if (databaseOption !== undefined) {
351
+ // CLI flag provided - normalize to expected values
352
+ if (databaseOption.toLowerCase() === 'new') {
353
+ db_action = 'Create New';
354
+ } else if (databaseOption.toLowerCase() === 'skip') {
355
+ db_action = 'Skip';
356
+ } else {
357
+ // Existing database name - validate it exists
358
+ const existingDb = resources?.db.find((d) => d.name === databaseOption);
359
+ if (!existingDb) {
360
+ logger.fatal(
361
+ `Database '${databaseOption}' not found. Use 'new' to create a new database or 'skip' to skip.`,
362
+ ErrorCode.RESOURCE_NOT_FOUND
363
+ );
364
+ }
365
+ db_action = databaseOption;
366
+ }
367
+ } else if (isInteractive) {
368
+ db_action = await prompt.select({
369
+ message: 'Create SQL Database?',
370
+ options: [
371
+ { value: 'Skip', label: 'Skip or Setup later' },
372
+ { value: 'Create New', label: 'Create a new database' },
373
+ ...resources!.db.map((db) => ({
374
+ value: db.name,
375
+ label: `Use database: ${tui.tuiColors.primary(db.name)}`,
376
+ })),
377
+ ],
378
+ });
379
+ } else {
380
+ // Headless without flag - skip
381
+ db_action = 'Skip';
382
+ }
383
+
384
+ // Determine storage action: CLI flag > interactive prompt > skip (headless)
385
+ let s3_action: string;
386
+ if (storageOption !== undefined) {
387
+ // CLI flag provided - normalize to expected values
388
+ if (storageOption.toLowerCase() === 'new') {
389
+ s3_action = 'Create New';
390
+ } else if (storageOption.toLowerCase() === 'skip') {
391
+ s3_action = 'Skip';
392
+ } else {
393
+ // Existing bucket name - validate it exists
394
+ const existingBucket = resources?.s3.find((b) => b.bucket_name === storageOption);
395
+ if (!existingBucket) {
396
+ logger.fatal(
397
+ `Storage bucket '${storageOption}' not found. Use 'new' to create a new bucket or 'skip' to skip.`,
398
+ ErrorCode.RESOURCE_NOT_FOUND
399
+ );
400
+ }
401
+ s3_action = storageOption;
402
+ }
403
+ } else if (isInteractive) {
404
+ s3_action = await prompt.select({
405
+ message: 'Create Storage Bucket?',
406
+ options: [
407
+ { value: 'Skip', label: 'Skip or Setup later' },
408
+ { value: 'Create New', label: 'Create a new bucket' },
409
+ ...resources!.s3.map((bucket) => ({
410
+ value: bucket.bucket_name,
411
+ label: `Use bucket: ${tui.tuiColors.primary(bucket.bucket_name)}`,
412
+ })),
413
+ ],
414
+ });
415
+ } else {
416
+ // Headless without flag - skip
417
+ s3_action = 'Skip';
418
+ }
419
+
420
+ // Custom DNS: only prompt in interactive mode if not already provided
421
+ if (!domains?.length && isInteractive) {
312
422
  const customDns = await prompt.text({
313
423
  message: 'Setup custom DNS?',
314
424
  hint: 'Enter a domain name or press Enter to skip',
@@ -324,14 +434,14 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
324
434
  }
325
435
  }
326
436
 
327
- const choices = { db_action, s3_action };
328
- switch (choices.s3_action) {
437
+ // Process storage action
438
+ switch (s3_action) {
329
439
  case 'Create New': {
330
440
  const created = await tui.spinner({
331
441
  message: 'Provisioning New Bucket',
332
442
  clearOnSuccess: true,
333
443
  callback: async () => {
334
- return createResources(catalystClient, orgId, region!, [{ type: 's3' }]);
444
+ return createResources(catalystClient!, orgId!, region!, [{ type: 's3' }]);
335
445
  },
336
446
  });
337
447
  // Collect env vars from newly created resource
@@ -345,39 +455,49 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
345
455
  }
346
456
  default: {
347
457
  // User selected an existing bucket - get env vars from the resources list
348
- const selectedBucket = resources.s3.find((b) => b.bucket_name === choices.s3_action);
458
+ const selectedBucket = resources?.s3.find((b) => b.bucket_name === s3_action);
349
459
  if (selectedBucket?.env) {
350
460
  Object.assign(resourceEnvVars, selectedBucket.env);
351
461
  }
352
462
  break;
353
463
  }
354
464
  }
355
- switch (choices.db_action) {
465
+
466
+ // Process database action
467
+ switch (db_action) {
356
468
  case 'Create New': {
357
- const dbNameInput = await prompt.text({
358
- message: 'Database name',
359
- hint: 'Optional - lowercase letters, digits, underscores only',
360
- validate: (value: string) => {
361
- const trimmed = value.trim();
362
- if (trimmed === '') return true;
363
- const result = validateDatabaseName(trimmed);
364
- return result.valid ? true : result.error!;
365
- },
366
- });
367
- const dbName = dbNameInput.trim() || undefined;
368
- const dbDescription = await prompt.text({
369
- message: 'Database description',
370
- hint: 'Optional - press Enter to skip',
371
- });
469
+ let dbName: string | undefined;
470
+ let dbDescription: string | undefined;
471
+
472
+ // Only prompt for name/description in interactive mode
473
+ if (isInteractive) {
474
+ const dbNameInput = await prompt.text({
475
+ message: 'Database name',
476
+ hint: 'Optional - lowercase letters, digits, underscores only',
477
+ validate: (value: string) => {
478
+ const trimmed = value.trim();
479
+ if (trimmed === '') return true;
480
+ const result = validateDatabaseName(trimmed);
481
+ return result.valid ? true : result.error!;
482
+ },
483
+ });
484
+ dbName = dbNameInput.trim() || undefined;
485
+ dbDescription =
486
+ (await prompt.text({
487
+ message: 'Database description',
488
+ hint: 'Optional - press Enter to skip',
489
+ })) || undefined;
490
+ }
491
+
372
492
  const created = await tui.spinner({
373
493
  message: 'Provisioning New SQL Database',
374
494
  clearOnSuccess: true,
375
495
  callback: async () => {
376
- return createResources(catalystClient, orgId, region!, [
496
+ return createResources(catalystClient!, orgId!, region!, [
377
497
  {
378
498
  type: 'db',
379
499
  name: dbName,
380
- description: dbDescription || undefined,
500
+ description: dbDescription,
381
501
  },
382
502
  ]);
383
503
  },
@@ -393,7 +513,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
393
513
  }
394
514
  default: {
395
515
  // User selected an existing database - get env vars from the resources list
396
- const selectedDb = resources.db.find((d) => d.name === choices.db_action);
516
+ const selectedDb = resources?.db.find((d) => d.name === db_action);
397
517
  if (selectedDb?.env) {
398
518
  Object.assign(resourceEnvVars, selectedDb.env);
399
519
  }
@@ -402,15 +522,19 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
402
522
  }
403
523
  }
404
524
 
405
- // Auth setup - either from template or user choice
525
+ // Auth setup - either from template, CLI flag, or user choice
406
526
  const templateHasAuth = selectedTemplate.id === 'agentuity-auth';
407
527
 
408
528
  let authEnabled = templateHasAuth; // Auth templates have auth enabled by default
409
529
  let authDatabaseName: string | undefined;
410
530
  let authDatabaseUrl: string | undefined;
411
531
 
412
- // For non-auth templates, ask if they want to enable auth
413
- if (auth && catalystClient && orgId && region && !skipPrompts && !templateHasAuth) {
532
+ // Handle auth enablement: CLI flag > interactive prompt > disabled (headless)
533
+ if (enableAuthOption !== undefined) {
534
+ // CLI flag provided
535
+ authEnabled = enableAuthOption;
536
+ } else if (canProvision && isInteractive && !templateHasAuth) {
537
+ // For non-auth templates in interactive mode, ask if they want to enable auth
414
538
  const enableAuth = await prompt.select({
415
539
  message: 'Enable Agentuity Authentication?',
416
540
  options: [
@@ -423,9 +547,10 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
423
547
  authEnabled = true;
424
548
  }
425
549
  }
550
+ // In headless mode without --enable-auth flag, authEnabled stays false (unless template has auth)
426
551
 
427
552
  // Set up database and secret for any auth-enabled project
428
- if (authEnabled && auth && catalystClient && orgId && region && !skipPrompts) {
553
+ if (authEnabled && canProvision) {
429
554
  // If a database was already selected/created above, use it for auth
430
555
  if (resourceEnvVars.DATABASE_URL) {
431
556
  authDatabaseUrl = resourceEnvVars.DATABASE_URL;
@@ -446,7 +571,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
446
571
  message: 'Provisioning database for auth',
447
572
  clearOnSuccess: true,
448
573
  callback: async () => {
449
- return createResources(catalystClient, orgId, region!, [{ type: 'db' }]);
574
+ return createResources(catalystClient!, orgId!, region!, [{ type: 'db' }]);
450
575
  },
451
576
  });
452
577
  authDatabaseName = created[0].name;
@@ -596,8 +721,12 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
596
721
  await initGitRepo(dest);
597
722
 
598
723
  // Show completion message
599
- if (!skipPrompts) {
600
- tui.success('✨ Project created successfully!\n');
724
+ if (isInteractive) {
725
+ if (setupResult.success) {
726
+ tui.success('✨ Project created successfully!\n');
727
+ } else {
728
+ tui.warning('Project created with errors (see above)\n');
729
+ }
601
730
 
602
731
  // Show next steps in a box with primary color for commands
603
732
  if (dirName !== '.') {
@@ -617,12 +746,16 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
617
746
  `${tui.tuiColors.muted('⭐️ Follow us:')} ${tui.link('https://github.com/agentuity/sdk')}`
618
747
  );
619
748
  } else {
620
- tui.success('✨ Project created successfully!');
749
+ if (setupResult.success) {
750
+ tui.success('✨ Project created successfully!');
751
+ } else {
752
+ tui.warning('Project created with errors');
753
+ }
621
754
  }
622
755
 
623
756
  playSound();
624
757
 
625
- if (process.stdin.isTTY && !skipPrompts && _domains?.length && projectId) {
758
+ if (isInteractive && _domains?.length && projectId) {
626
759
  tui.newline();
627
760
  const ok = await tui.confirm('Would you like to configure DNS now?', true);
628
761
  if (ok) {
@@ -643,8 +776,10 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
643
776
  path: dest,
644
777
  template: selectedTemplate.id,
645
778
  installed: !options.noInstall,
646
- built: !options.noBuild,
779
+ built: !options.noBuild && setupResult.success,
647
780
  domains: _domains,
781
+ success: setupResult.success,
782
+ error: setupResult.success ? undefined : 'Project setup completed with errors',
648
783
  };
649
784
  }
650
785
 
@@ -4,6 +4,7 @@ import { hasLoggedInBefore } from '../../auth';
4
4
  import { showBanner } from '../../banner';
5
5
  import * as tui from '../../tui';
6
6
  import { getCommand } from '../../command-prefix';
7
+ import { getAgentPromptMarkdown } from '../../onboarding/agentPrompt';
7
8
 
8
9
  const validateToken = /[\d]{7,}\.[\w-_.]{22}/;
9
10
 
@@ -53,7 +54,7 @@ export const command = createCommand({
53
54
  },
54
55
  });
55
56
  if (ok) {
56
- /* TODO */
57
+ process.stdout.write(getAgentPromptMarkdown());
57
58
  return;
58
59
  }
59
60
  }