@agentuity/cli 0.1.15 → 0.1.17

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 (255) hide show
  1. package/dist/cli.d.ts.map +1 -1
  2. package/dist/cli.js +18 -2
  3. package/dist/cli.js.map +1 -1
  4. package/dist/cmd/ai/opencode/install.js +1 -1
  5. package/dist/cmd/ai/opencode/install.js.map +1 -1
  6. package/dist/cmd/build/ast.d.ts.map +1 -1
  7. package/dist/cmd/build/ast.js +68 -2
  8. package/dist/cmd/build/ast.js.map +1 -1
  9. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
  10. package/dist/cmd/build/vite/registry-generator.js +112 -23
  11. package/dist/cmd/build/vite/registry-generator.js.map +1 -1
  12. package/dist/cmd/build/vite/route-discovery.d.ts +4 -0
  13. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
  14. package/dist/cmd/build/vite/route-discovery.js +4 -0
  15. package/dist/cmd/build/vite/route-discovery.js.map +1 -1
  16. package/dist/cmd/cloud/env/delete.d.ts.map +1 -1
  17. package/dist/cmd/cloud/env/delete.js +93 -34
  18. package/dist/cmd/cloud/env/delete.js.map +1 -1
  19. package/dist/cmd/cloud/env/get.d.ts.map +1 -1
  20. package/dist/cmd/cloud/env/get.js +53 -16
  21. package/dist/cmd/cloud/env/get.js.map +1 -1
  22. package/dist/cmd/cloud/env/import.d.ts.map +1 -1
  23. package/dist/cmd/cloud/env/import.js +80 -39
  24. package/dist/cmd/cloud/env/import.js.map +1 -1
  25. package/dist/cmd/cloud/env/index.d.ts.map +1 -1
  26. package/dist/cmd/cloud/env/index.js +6 -2
  27. package/dist/cmd/cloud/env/index.js.map +1 -1
  28. package/dist/cmd/cloud/env/list.d.ts.map +1 -1
  29. package/dist/cmd/cloud/env/list.js +99 -23
  30. package/dist/cmd/cloud/env/list.js.map +1 -1
  31. package/dist/cmd/cloud/env/org-util.d.ts +16 -0
  32. package/dist/cmd/cloud/env/org-util.d.ts.map +1 -0
  33. package/dist/cmd/cloud/env/org-util.js +28 -0
  34. package/dist/cmd/cloud/env/org-util.js.map +1 -0
  35. package/dist/cmd/cloud/env/pull.d.ts.map +1 -1
  36. package/dist/cmd/cloud/env/pull.js +61 -29
  37. package/dist/cmd/cloud/env/pull.js.map +1 -1
  38. package/dist/cmd/cloud/env/push.d.ts.map +1 -1
  39. package/dist/cmd/cloud/env/push.js +70 -30
  40. package/dist/cmd/cloud/env/push.js.map +1 -1
  41. package/dist/cmd/cloud/env/set.d.ts.map +1 -1
  42. package/dist/cmd/cloud/env/set.js +72 -26
  43. package/dist/cmd/cloud/env/set.js.map +1 -1
  44. package/dist/cmd/cloud/index.d.ts.map +1 -1
  45. package/dist/cmd/cloud/index.js +2 -0
  46. package/dist/cmd/cloud/index.js.map +1 -1
  47. package/dist/cmd/cloud/keyvalue/create-namespace.js +1 -1
  48. package/dist/cmd/cloud/keyvalue/create-namespace.js.map +1 -1
  49. package/dist/cmd/cloud/keyvalue/delete-namespace.js +2 -2
  50. package/dist/cmd/cloud/keyvalue/delete-namespace.js.map +1 -1
  51. package/dist/cmd/cloud/keyvalue/delete.js +1 -1
  52. package/dist/cmd/cloud/keyvalue/delete.js.map +1 -1
  53. package/dist/cmd/cloud/keyvalue/get.js +1 -1
  54. package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
  55. package/dist/cmd/cloud/keyvalue/index.js +1 -1
  56. package/dist/cmd/cloud/keyvalue/index.js.map +1 -1
  57. package/dist/cmd/cloud/keyvalue/keys.js +1 -1
  58. package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
  59. package/dist/cmd/cloud/keyvalue/list-namespaces.js +1 -1
  60. package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
  61. package/dist/cmd/cloud/keyvalue/repl.d.ts.map +1 -1
  62. package/dist/cmd/cloud/keyvalue/repl.js +8 -5
  63. package/dist/cmd/cloud/keyvalue/repl.js.map +1 -1
  64. package/dist/cmd/cloud/keyvalue/search.js +1 -1
  65. package/dist/cmd/cloud/keyvalue/search.js.map +1 -1
  66. package/dist/cmd/cloud/keyvalue/set.js +1 -1
  67. package/dist/cmd/cloud/keyvalue/set.js.map +1 -1
  68. package/dist/cmd/cloud/keyvalue/stats.js +1 -1
  69. package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
  70. package/dist/cmd/cloud/keyvalue/util.d.ts +4 -4
  71. package/dist/cmd/cloud/keyvalue/util.d.ts.map +1 -1
  72. package/dist/cmd/cloud/keyvalue/util.js +4 -9
  73. package/dist/cmd/cloud/keyvalue/util.js.map +1 -1
  74. package/dist/cmd/cloud/queue/ack.d.ts +3 -0
  75. package/dist/cmd/cloud/queue/ack.d.ts.map +1 -0
  76. package/dist/cmd/cloud/queue/ack.js +45 -0
  77. package/dist/cmd/cloud/queue/ack.js.map +1 -0
  78. package/dist/cmd/cloud/queue/create.d.ts +3 -0
  79. package/dist/cmd/cloud/queue/create.d.ts.map +1 -0
  80. package/dist/cmd/cloud/queue/create.js +80 -0
  81. package/dist/cmd/cloud/queue/create.js.map +1 -0
  82. package/dist/cmd/cloud/queue/delete.d.ts +3 -0
  83. package/dist/cmd/cloud/queue/delete.d.ts.map +1 -0
  84. package/dist/cmd/cloud/queue/delete.js +50 -0
  85. package/dist/cmd/cloud/queue/delete.js.map +1 -0
  86. package/dist/cmd/cloud/queue/destinations.d.ts +3 -0
  87. package/dist/cmd/cloud/queue/destinations.d.ts.map +1 -0
  88. package/dist/cmd/cloud/queue/destinations.js +232 -0
  89. package/dist/cmd/cloud/queue/destinations.js.map +1 -0
  90. package/dist/cmd/cloud/queue/dlq.d.ts +3 -0
  91. package/dist/cmd/cloud/queue/dlq.d.ts.map +1 -0
  92. package/dist/cmd/cloud/queue/dlq.js +168 -0
  93. package/dist/cmd/cloud/queue/dlq.js.map +1 -0
  94. package/dist/cmd/cloud/queue/get.d.ts +3 -0
  95. package/dist/cmd/cloud/queue/get.d.ts.map +1 -0
  96. package/dist/cmd/cloud/queue/get.js +130 -0
  97. package/dist/cmd/cloud/queue/get.js.map +1 -0
  98. package/dist/cmd/cloud/queue/index.d.ts +3 -0
  99. package/dist/cmd/cloud/queue/index.d.ts.map +1 -0
  100. package/dist/cmd/cloud/queue/index.js +65 -0
  101. package/dist/cmd/cloud/queue/index.js.map +1 -0
  102. package/dist/cmd/cloud/queue/list.d.ts +3 -0
  103. package/dist/cmd/cloud/queue/list.d.ts.map +1 -0
  104. package/dist/cmd/cloud/queue/list.js +71 -0
  105. package/dist/cmd/cloud/queue/list.js.map +1 -0
  106. package/dist/cmd/cloud/queue/messages.d.ts +3 -0
  107. package/dist/cmd/cloud/queue/messages.d.ts.map +1 -0
  108. package/dist/cmd/cloud/queue/messages.js +137 -0
  109. package/dist/cmd/cloud/queue/messages.js.map +1 -0
  110. package/dist/cmd/cloud/queue/nack.d.ts +3 -0
  111. package/dist/cmd/cloud/queue/nack.d.ts.map +1 -0
  112. package/dist/cmd/cloud/queue/nack.js +45 -0
  113. package/dist/cmd/cloud/queue/nack.js.map +1 -0
  114. package/dist/cmd/cloud/queue/pause.d.ts +3 -0
  115. package/dist/cmd/cloud/queue/pause.d.ts.map +1 -0
  116. package/dist/cmd/cloud/queue/pause.js +36 -0
  117. package/dist/cmd/cloud/queue/pause.js.map +1 -0
  118. package/dist/cmd/cloud/queue/publish.d.ts +3 -0
  119. package/dist/cmd/cloud/queue/publish.d.ts.map +1 -0
  120. package/dist/cmd/cloud/queue/publish.js +76 -0
  121. package/dist/cmd/cloud/queue/publish.js.map +1 -0
  122. package/dist/cmd/cloud/queue/receive.d.ts +3 -0
  123. package/dist/cmd/cloud/queue/receive.d.ts.map +1 -0
  124. package/dist/cmd/cloud/queue/receive.js +67 -0
  125. package/dist/cmd/cloud/queue/receive.js.map +1 -0
  126. package/dist/cmd/cloud/queue/resume.d.ts +3 -0
  127. package/dist/cmd/cloud/queue/resume.d.ts.map +1 -0
  128. package/dist/cmd/cloud/queue/resume.js +35 -0
  129. package/dist/cmd/cloud/queue/resume.js.map +1 -0
  130. package/dist/cmd/cloud/queue/sources.d.ts +3 -0
  131. package/dist/cmd/cloud/queue/sources.d.ts.map +1 -0
  132. package/dist/cmd/cloud/queue/sources.js +290 -0
  133. package/dist/cmd/cloud/queue/sources.js.map +1 -0
  134. package/dist/cmd/cloud/queue/stats.d.ts +3 -0
  135. package/dist/cmd/cloud/queue/stats.d.ts.map +1 -0
  136. package/dist/cmd/cloud/queue/stats.js +239 -0
  137. package/dist/cmd/cloud/queue/stats.js.map +1 -0
  138. package/dist/cmd/cloud/queue/util.d.ts +26 -0
  139. package/dist/cmd/cloud/queue/util.d.ts.map +1 -0
  140. package/dist/cmd/cloud/queue/util.js +19 -0
  141. package/dist/cmd/cloud/queue/util.js.map +1 -0
  142. package/dist/cmd/cloud/sandbox/snapshot/build.d.ts.map +1 -1
  143. package/dist/cmd/cloud/sandbox/snapshot/build.js +122 -28
  144. package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
  145. package/dist/cmd/cloud/sandbox/snapshot/create.d.ts.map +1 -1
  146. package/dist/cmd/cloud/sandbox/snapshot/create.js +19 -7
  147. package/dist/cmd/cloud/sandbox/snapshot/create.js.map +1 -1
  148. package/dist/cmd/cloud/sandbox/snapshot/get.d.ts.map +1 -1
  149. package/dist/cmd/cloud/sandbox/snapshot/get.js +16 -0
  150. package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
  151. package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -1
  152. package/dist/cmd/cloud/sandbox/snapshot/list.js +4 -0
  153. package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
  154. package/dist/cmd/cloud/vector/stats.d.ts.map +1 -1
  155. package/dist/cmd/cloud/vector/stats.js +8 -0
  156. package/dist/cmd/cloud/vector/stats.js.map +1 -1
  157. package/dist/cmd/project/create.d.ts.map +1 -1
  158. package/dist/cmd/project/create.js +12 -0
  159. package/dist/cmd/project/create.js.map +1 -1
  160. package/dist/cmd/project/template-flow.d.ts +3 -0
  161. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  162. package/dist/cmd/project/template-flow.js +157 -68
  163. package/dist/cmd/project/template-flow.js.map +1 -1
  164. package/dist/cmd/setup/index.d.ts.map +1 -1
  165. package/dist/cmd/setup/index.js +2 -1
  166. package/dist/cmd/setup/index.js.map +1 -1
  167. package/dist/env-util.d.ts +6 -1
  168. package/dist/env-util.d.ts.map +1 -1
  169. package/dist/env-util.js +16 -2
  170. package/dist/env-util.js.map +1 -1
  171. package/dist/errors.d.ts +4 -2
  172. package/dist/errors.d.ts.map +1 -1
  173. package/dist/errors.js +6 -0
  174. package/dist/errors.js.map +1 -1
  175. package/dist/onboarding/agentPrompt.d.ts +8 -0
  176. package/dist/onboarding/agentPrompt.d.ts.map +1 -0
  177. package/dist/onboarding/agentPrompt.js +263 -0
  178. package/dist/onboarding/agentPrompt.js.map +1 -0
  179. package/dist/schema-generator.d.ts +1 -1
  180. package/dist/schema-generator.d.ts.map +1 -1
  181. package/dist/schema-parser.d.ts +1 -1
  182. package/dist/schema-parser.d.ts.map +1 -1
  183. package/dist/schema-parser.js +36 -1
  184. package/dist/schema-parser.js.map +1 -1
  185. package/dist/tui/box.d.ts +4 -0
  186. package/dist/tui/box.d.ts.map +1 -1
  187. package/dist/tui/box.js +39 -0
  188. package/dist/tui/box.js.map +1 -1
  189. package/dist/tui.d.ts +11 -1
  190. package/dist/tui.d.ts.map +1 -1
  191. package/dist/tui.js +33 -15
  192. package/dist/tui.js.map +1 -1
  193. package/dist/types.d.ts.map +1 -1
  194. package/dist/types.js.map +1 -1
  195. package/package.json +6 -6
  196. package/src/cli.ts +19 -2
  197. package/src/cmd/ai/opencode/install.ts +1 -1
  198. package/src/cmd/build/ast.ts +88 -2
  199. package/src/cmd/build/vite/registry-generator.ts +120 -24
  200. package/src/cmd/build/vite/route-discovery.ts +16 -0
  201. package/src/cmd/cloud/env/delete.ts +113 -41
  202. package/src/cmd/cloud/env/get.ts +60 -16
  203. package/src/cmd/cloud/env/import.ts +92 -44
  204. package/src/cmd/cloud/env/index.ts +6 -2
  205. package/src/cmd/cloud/env/list.ts +112 -27
  206. package/src/cmd/cloud/env/org-util.ts +37 -0
  207. package/src/cmd/cloud/env/pull.ts +72 -31
  208. package/src/cmd/cloud/env/push.ts +84 -35
  209. package/src/cmd/cloud/env/set.ts +89 -33
  210. package/src/cmd/cloud/index.ts +2 -0
  211. package/src/cmd/cloud/keyvalue/create-namespace.ts +1 -1
  212. package/src/cmd/cloud/keyvalue/delete-namespace.ts +2 -2
  213. package/src/cmd/cloud/keyvalue/delete.ts +1 -1
  214. package/src/cmd/cloud/keyvalue/get.ts +1 -1
  215. package/src/cmd/cloud/keyvalue/index.ts +1 -1
  216. package/src/cmd/cloud/keyvalue/keys.ts +1 -1
  217. package/src/cmd/cloud/keyvalue/list-namespaces.ts +1 -1
  218. package/src/cmd/cloud/keyvalue/repl.ts +8 -5
  219. package/src/cmd/cloud/keyvalue/search.ts +1 -1
  220. package/src/cmd/cloud/keyvalue/set.ts +1 -1
  221. package/src/cmd/cloud/keyvalue/stats.ts +1 -1
  222. package/src/cmd/cloud/keyvalue/util.ts +8 -17
  223. package/src/cmd/cloud/queue/ack.ts +50 -0
  224. package/src/cmd/cloud/queue/create.ts +91 -0
  225. package/src/cmd/cloud/queue/delete.ts +57 -0
  226. package/src/cmd/cloud/queue/destinations.ts +287 -0
  227. package/src/cmd/cloud/queue/dlq.ts +203 -0
  228. package/src/cmd/cloud/queue/get.ts +158 -0
  229. package/src/cmd/cloud/queue/index.ts +66 -0
  230. package/src/cmd/cloud/queue/list.ts +81 -0
  231. package/src/cmd/cloud/queue/messages.ts +160 -0
  232. package/src/cmd/cloud/queue/nack.ts +50 -0
  233. package/src/cmd/cloud/queue/pause.ts +41 -0
  234. package/src/cmd/cloud/queue/publish.ts +88 -0
  235. package/src/cmd/cloud/queue/receive.ts +76 -0
  236. package/src/cmd/cloud/queue/resume.ts +40 -0
  237. package/src/cmd/cloud/queue/sources.ts +352 -0
  238. package/src/cmd/cloud/queue/stats.ts +297 -0
  239. package/src/cmd/cloud/queue/util.ts +34 -0
  240. package/src/cmd/cloud/sandbox/snapshot/build.ts +146 -29
  241. package/src/cmd/cloud/sandbox/snapshot/create.ts +24 -7
  242. package/src/cmd/cloud/sandbox/snapshot/get.ts +16 -0
  243. package/src/cmd/cloud/sandbox/snapshot/list.ts +4 -0
  244. package/src/cmd/cloud/vector/stats.ts +9 -0
  245. package/src/cmd/project/create.ts +12 -0
  246. package/src/cmd/project/template-flow.ts +181 -69
  247. package/src/cmd/setup/index.ts +2 -1
  248. package/src/env-util.ts +17 -2
  249. package/src/errors.ts +8 -0
  250. package/src/onboarding/agentPrompt.ts +263 -0
  251. package/src/schema-generator.ts +1 -1
  252. package/src/schema-parser.ts +45 -3
  253. package/src/tui/box.ts +52 -0
  254. package/src/tui.ts +47 -17
  255. package/src/types.ts +0 -1
@@ -8,11 +8,15 @@ import { getGlobalCatalystAPIClient } from '../../../../config';
8
8
  const SnapshotInfoSchema = z.object({
9
9
  snapshotId: z.string(),
10
10
  name: z.string().nullable().optional(),
11
+ fullName: z.string().nullable().optional(),
11
12
  description: z.string().nullable().optional(),
12
13
  tag: z.string().nullable().optional(),
13
14
  sizeBytes: z.number(),
14
15
  fileCount: z.number(),
15
16
  parentSnapshotId: z.string().nullable().optional(),
17
+ public: z.boolean().optional(),
18
+ orgName: z.string().optional(),
19
+ orgSlug: z.string().optional(),
16
20
  createdAt: z.string(),
17
21
  });
18
22
 
@@ -21,12 +21,21 @@ const VectorNamespaceStatsSchema = z.object({
21
21
  lastUsed: z.number().optional().describe('Last used timestamp (ms)'),
22
22
  });
23
23
 
24
+ const VectorStatsPaginatedSchema = z.object({
25
+ namespaces: z.record(z.string(), VectorNamespaceStatsSchema).describe('Map of namespace names to their statistics'),
26
+ total: z.number().describe('Total number of namespaces across all pages'),
27
+ limit: z.number().describe('Number of namespaces requested per page'),
28
+ offset: z.number().describe('Number of namespaces skipped'),
29
+ hasMore: z.boolean().describe('Whether there are more namespaces available'),
30
+ });
31
+
24
32
  const VectorStatsResponseSchema = z.union([
25
33
  VectorNamespaceStatsSchema.extend({
26
34
  namespace: z.string().describe('Namespace name'),
27
35
  sampledResults: z.record(z.string(), VectorItemStatsSchema).optional(),
28
36
  }),
29
37
  z.record(z.string(), VectorNamespaceStatsSchema),
38
+ VectorStatsPaginatedSchema,
30
39
  ]);
31
40
 
32
41
  export const statsSubcommand = createCommand({
@@ -69,6 +69,15 @@ export const createProjectSubcommand = createSubcommand({
69
69
  .default(true)
70
70
  .optional()
71
71
  .describe('Register the project, if authenticated (use --no-register to skip)'),
72
+ database: z
73
+ .string()
74
+ .optional()
75
+ .describe('Database action: "skip", "new", or existing database name'),
76
+ storage: z
77
+ .string()
78
+ .optional()
79
+ .describe('Storage action: "skip", "new", or existing bucket name'),
80
+ enableAuth: z.boolean().optional().describe('Enable Agentuity Auth'),
72
81
  }),
73
82
  response: ProjectCreateResponseSchema,
74
83
  },
@@ -101,6 +110,9 @@ export const createProjectSubcommand = createSubcommand({
101
110
  apiClient,
102
111
  orgId: opts.register === true ? orgId : undefined,
103
112
  region,
113
+ database: opts.database,
114
+ storage: opts.storage,
115
+ enableAuth: opts.enableAuth,
104
116
  });
105
117
 
106
118
  // Exit with error code if setup failed and not in JSON mode
@@ -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 {
@@ -85,8 +88,14 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
85
88
  region,
86
89
  apiClient,
87
90
  domains,
91
+ database: databaseOption,
92
+ storage: storageOption,
93
+ enableAuth: enableAuthOption,
88
94
  } = options;
89
95
 
96
+ const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY;
97
+ const isInteractive = !skipPrompts && !isHeadless;
98
+
90
99
  // Fetch available templates
91
100
  if (templateDir) {
92
101
  tui.info(`📋 Loading templates from local directory: ${templateDir}...\n`);
@@ -120,11 +129,11 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
120
129
  // Create prompt flow
121
130
  const prompt = createPrompt();
122
131
 
123
- if (!skipPrompts) {
132
+ if (isInteractive) {
124
133
  prompt.intro('Create Agentuity Project');
125
134
  }
126
135
 
127
- if (!projectName && !skipPrompts) {
136
+ if (!projectName && isInteractive) {
128
137
  projectName = await prompt.text({
129
138
  message: 'What is the name of your project?',
130
139
  hint: 'The name must be unique for your organization',
@@ -164,8 +173,8 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
164
173
  const destEmpty = destIsDir ? readdirSync(dest).length === 0 : !destExists;
165
174
 
166
175
  if (destExists && !destEmpty && dirName !== '.') {
167
- // In TTY mode, ask if they want to overwrite
168
- if (process.stdin.isTTY && !skipPrompts) {
176
+ // In interactive mode, ask if they want to overwrite
177
+ if (isInteractive) {
169
178
  tui.warning(`Directory ${dest} already exists and is not empty.`, true);
170
179
  console.log(tui.tuiColors.secondary('│'));
171
180
  const overwrite = await prompt.confirm({
@@ -210,7 +219,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
210
219
  return undefined as never;
211
220
  }
212
221
  selectedTemplate = found;
213
- } else if (skipPrompts || templates.length === 1) {
222
+ } else if (!isInteractive || templates.length === 1) {
214
223
  selectedTemplate = templates[0];
215
224
  } else {
216
225
  let maxLength = 15;
@@ -275,7 +284,13 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
275
284
  }
276
285
 
277
286
  // Add separator bar if we're going to show resource prompts
278
- if (!skipPrompts && auth && apiClient && catalystClient && orgId && region) {
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) {
279
294
  const { symbols, tuiColors } = tui;
280
295
  console.log(tuiColors.secondary(symbols.bar));
281
296
  }
@@ -283,43 +298,125 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
283
298
  let _domains = domains;
284
299
  const resourceEnvVars: EnvVars = {};
285
300
 
286
- if (auth && apiClient && catalystClient && orgId && region && !skipPrompts) {
287
- // Fetch resources for selected org and region using Catalyst API
288
- const resources = await tui.spinner({
289
- message: 'Fetching resources',
290
- clearOnSuccess: true,
291
- callback: async () => {
292
- return listResources(catalystClient, orgId, region);
293
- },
294
- });
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
+ }
295
309
 
296
- 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
+ }
297
318
 
298
- const db_action = await prompt.select({
299
- message: 'Create SQL Database?',
300
- options: [
301
- { value: 'Skip', label: 'Skip or Setup later' },
302
- { value: 'Create New', label: 'Create a new database' },
303
- ...resources.db.map((db) => ({
304
- value: db.name,
305
- label: `Use database: ${tui.tuiColors.primary(db.name)}`,
306
- })),
307
- ],
308
- });
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;
309
322
 
310
- const s3_action = await prompt.select({
311
- message: 'Create Storage Bucket?',
312
- options: [
313
- { value: 'Skip', label: 'Skip or Setup later' },
314
- { value: 'Create New', label: 'Create a new bucket' },
315
- ...resources.s3.map((bucket) => ({
316
- value: bucket.bucket_name,
317
- label: `Use bucket: ${tui.tuiColors.primary(bucket.bucket_name)}`,
318
- })),
319
- ],
320
- });
323
+ const needResources =
324
+ isInteractive ||
325
+ (databaseOption && databaseOption !== 'skip' && databaseOption !== 'new') ||
326
+ (storageOption && storageOption !== 'skip' && storageOption !== 'new');
321
327
 
322
- 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(`Database names: ${resources.db.map((d) => d.name).join(', ') || '(none)'}`);
341
+ logger.debug(
342
+ `Storage buckets: ${resources.s3.map((b) => b.bucket_name).join(', ') || '(none)'}`
343
+ );
344
+ }
345
+
346
+ // Determine database action: CLI flag > interactive prompt > skip (headless)
347
+ let db_action: string;
348
+ if (databaseOption !== undefined) {
349
+ // CLI flag provided - normalize to expected values
350
+ if (databaseOption.toLowerCase() === 'new') {
351
+ db_action = 'Create New';
352
+ } else if (databaseOption.toLowerCase() === 'skip') {
353
+ db_action = 'Skip';
354
+ } else {
355
+ // Existing database name - validate it exists
356
+ const existingDb = resources?.db.find((d) => d.name === databaseOption);
357
+ if (!existingDb) {
358
+ logger.fatal(
359
+ `Database '${databaseOption}' not found. Use 'new' to create a new database or 'skip' to skip.`,
360
+ ErrorCode.RESOURCE_NOT_FOUND
361
+ );
362
+ }
363
+ db_action = databaseOption;
364
+ }
365
+ } else if (isInteractive) {
366
+ db_action = await prompt.select({
367
+ message: 'Create SQL Database?',
368
+ options: [
369
+ { value: 'Skip', label: 'Skip or Setup later' },
370
+ { value: 'Create New', label: 'Create a new database' },
371
+ ...resources!.db.map((db) => ({
372
+ value: db.name,
373
+ label: `Use database: ${tui.tuiColors.primary(db.name)}`,
374
+ })),
375
+ ],
376
+ });
377
+ } else {
378
+ // Headless without flag - skip
379
+ db_action = 'Skip';
380
+ }
381
+
382
+ // Determine storage action: CLI flag > interactive prompt > skip (headless)
383
+ let s3_action: string;
384
+ if (storageOption !== undefined) {
385
+ // CLI flag provided - normalize to expected values
386
+ if (storageOption.toLowerCase() === 'new') {
387
+ s3_action = 'Create New';
388
+ } else if (storageOption.toLowerCase() === 'skip') {
389
+ s3_action = 'Skip';
390
+ } else {
391
+ // Existing bucket name - validate it exists
392
+ const existingBucket = resources?.s3.find((b) => b.bucket_name === storageOption);
393
+ if (!existingBucket) {
394
+ logger.fatal(
395
+ `Storage bucket '${storageOption}' not found. Use 'new' to create a new bucket or 'skip' to skip.`,
396
+ ErrorCode.RESOURCE_NOT_FOUND
397
+ );
398
+ }
399
+ s3_action = storageOption;
400
+ }
401
+ } else if (isInteractive) {
402
+ s3_action = await prompt.select({
403
+ message: 'Create Storage Bucket?',
404
+ options: [
405
+ { value: 'Skip', label: 'Skip or Setup later' },
406
+ { value: 'Create New', label: 'Create a new bucket' },
407
+ ...resources!.s3.map((bucket) => ({
408
+ value: bucket.bucket_name,
409
+ label: `Use bucket: ${tui.tuiColors.primary(bucket.bucket_name)}`,
410
+ })),
411
+ ],
412
+ });
413
+ } else {
414
+ // Headless without flag - skip
415
+ s3_action = 'Skip';
416
+ }
417
+
418
+ // Custom DNS: only prompt in interactive mode if not already provided
419
+ if (!domains?.length && isInteractive) {
323
420
  const customDns = await prompt.text({
324
421
  message: 'Setup custom DNS?',
325
422
  hint: 'Enter a domain name or press Enter to skip',
@@ -335,14 +432,14 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
335
432
  }
336
433
  }
337
434
 
338
- const choices = { db_action, s3_action };
339
- switch (choices.s3_action) {
435
+ // Process storage action
436
+ switch (s3_action) {
340
437
  case 'Create New': {
341
438
  const created = await tui.spinner({
342
439
  message: 'Provisioning New Bucket',
343
440
  clearOnSuccess: true,
344
441
  callback: async () => {
345
- return createResources(catalystClient, orgId, region!, [{ type: 's3' }]);
442
+ return createResources(catalystClient!, orgId!, region!, [{ type: 's3' }]);
346
443
  },
347
444
  });
348
445
  // Collect env vars from newly created resource
@@ -356,39 +453,49 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
356
453
  }
357
454
  default: {
358
455
  // User selected an existing bucket - get env vars from the resources list
359
- const selectedBucket = resources.s3.find((b) => b.bucket_name === choices.s3_action);
456
+ const selectedBucket = resources?.s3.find((b) => b.bucket_name === s3_action);
360
457
  if (selectedBucket?.env) {
361
458
  Object.assign(resourceEnvVars, selectedBucket.env);
362
459
  }
363
460
  break;
364
461
  }
365
462
  }
366
- switch (choices.db_action) {
463
+
464
+ // Process database action
465
+ switch (db_action) {
367
466
  case 'Create New': {
368
- const dbNameInput = await prompt.text({
369
- message: 'Database name',
370
- hint: 'Optional - lowercase letters, digits, underscores only',
371
- validate: (value: string) => {
372
- const trimmed = value.trim();
373
- if (trimmed === '') return true;
374
- const result = validateDatabaseName(trimmed);
375
- return result.valid ? true : result.error!;
376
- },
377
- });
378
- const dbName = dbNameInput.trim() || undefined;
379
- const dbDescription = await prompt.text({
380
- message: 'Database description',
381
- hint: 'Optional - press Enter to skip',
382
- });
467
+ let dbName: string | undefined;
468
+ let dbDescription: string | undefined;
469
+
470
+ // Only prompt for name/description in interactive mode
471
+ if (isInteractive) {
472
+ const dbNameInput = await prompt.text({
473
+ message: 'Database name',
474
+ hint: 'Optional - lowercase letters, digits, underscores only',
475
+ validate: (value: string) => {
476
+ const trimmed = value.trim();
477
+ if (trimmed === '') return true;
478
+ const result = validateDatabaseName(trimmed);
479
+ return result.valid ? true : result.error!;
480
+ },
481
+ });
482
+ dbName = dbNameInput.trim() || undefined;
483
+ dbDescription =
484
+ (await prompt.text({
485
+ message: 'Database description',
486
+ hint: 'Optional - press Enter to skip',
487
+ })) || undefined;
488
+ }
489
+
383
490
  const created = await tui.spinner({
384
491
  message: 'Provisioning New SQL Database',
385
492
  clearOnSuccess: true,
386
493
  callback: async () => {
387
- return createResources(catalystClient, orgId, region!, [
494
+ return createResources(catalystClient!, orgId!, region!, [
388
495
  {
389
496
  type: 'db',
390
497
  name: dbName,
391
- description: dbDescription || undefined,
498
+ description: dbDescription,
392
499
  },
393
500
  ]);
394
501
  },
@@ -404,7 +511,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
404
511
  }
405
512
  default: {
406
513
  // User selected an existing database - get env vars from the resources list
407
- const selectedDb = resources.db.find((d) => d.name === choices.db_action);
514
+ const selectedDb = resources?.db.find((d) => d.name === db_action);
408
515
  if (selectedDb?.env) {
409
516
  Object.assign(resourceEnvVars, selectedDb.env);
410
517
  }
@@ -413,15 +520,19 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
413
520
  }
414
521
  }
415
522
 
416
- // Auth setup - either from template or user choice
523
+ // Auth setup - either from template, CLI flag, or user choice
417
524
  const templateHasAuth = selectedTemplate.id === 'agentuity-auth';
418
525
 
419
526
  let authEnabled = templateHasAuth; // Auth templates have auth enabled by default
420
527
  let authDatabaseName: string | undefined;
421
528
  let authDatabaseUrl: string | undefined;
422
529
 
423
- // For non-auth templates, ask if they want to enable auth
424
- if (auth && catalystClient && orgId && region && !skipPrompts && !templateHasAuth) {
530
+ // Handle auth enablement: CLI flag > interactive prompt > disabled (headless)
531
+ if (enableAuthOption !== undefined) {
532
+ // CLI flag provided
533
+ authEnabled = enableAuthOption;
534
+ } else if (canProvision && isInteractive && !templateHasAuth) {
535
+ // For non-auth templates in interactive mode, ask if they want to enable auth
425
536
  const enableAuth = await prompt.select({
426
537
  message: 'Enable Agentuity Authentication?',
427
538
  options: [
@@ -434,9 +545,10 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
434
545
  authEnabled = true;
435
546
  }
436
547
  }
548
+ // In headless mode without --enable-auth flag, authEnabled stays false (unless template has auth)
437
549
 
438
550
  // Set up database and secret for any auth-enabled project
439
- if (authEnabled && auth && catalystClient && orgId && region && !skipPrompts) {
551
+ if (authEnabled && canProvision) {
440
552
  // If a database was already selected/created above, use it for auth
441
553
  if (resourceEnvVars.DATABASE_URL) {
442
554
  authDatabaseUrl = resourceEnvVars.DATABASE_URL;
@@ -457,7 +569,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
457
569
  message: 'Provisioning database for auth',
458
570
  clearOnSuccess: true,
459
571
  callback: async () => {
460
- return createResources(catalystClient, orgId, region!, [{ type: 'db' }]);
572
+ return createResources(catalystClient!, orgId!, region!, [{ type: 'db' }]);
461
573
  },
462
574
  });
463
575
  authDatabaseName = created[0].name;
@@ -607,7 +719,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
607
719
  await initGitRepo(dest);
608
720
 
609
721
  // Show completion message
610
- if (!skipPrompts) {
722
+ if (isInteractive) {
611
723
  if (setupResult.success) {
612
724
  tui.success('✨ Project created successfully!\n');
613
725
  } else {
@@ -641,7 +753,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<CreateF
641
753
 
642
754
  playSound();
643
755
 
644
- if (process.stdin.isTTY && !skipPrompts && _domains?.length && projectId) {
756
+ if (isInteractive && _domains?.length && projectId) {
645
757
  tui.newline();
646
758
  const ok = await tui.confirm('Would you like to configure DNS now?', true);
647
759
  if (ok) {
@@ -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
  }
package/src/env-util.ts CHANGED
@@ -13,6 +13,12 @@ export interface EnvVars {
13
13
  */
14
14
  export const PUBLIC_VAR_PREFIXES = ['VITE_', 'AGENTUITY_PUBLIC_', 'PUBLIC_'] as const;
15
15
 
16
+ /**
17
+ * Specific AGENTUITY_ keys that are allowed to be set by users.
18
+ * Note: There is also a whitelist in the API that must be kept in sync.
19
+ */
20
+ export const AGENTUITY_ALLOWED_KEYS = ['AGENTUITY_AUTH_SECRET'] as const;
21
+
16
22
  /**
17
23
  * Check if a key is a public variable (exposed to frontend)
18
24
  */
@@ -22,11 +28,20 @@ export function isPublicVarKey(key: string): boolean {
22
28
  }
23
29
 
24
30
  /**
25
- * Check if a key is a reserved AGENTUITY key (except AGENTUITY_PUBLIC_)
31
+ * Check if a key is a reserved AGENTUITY key (except AGENTUITY_PUBLIC_ and allowed keys)
26
32
  */
27
33
  export function isReservedAgentuityKey(key: string): boolean {
28
34
  const upperKey = key.toUpperCase();
29
- return upperKey.startsWith('AGENTUITY_') && !upperKey.startsWith('AGENTUITY_PUBLIC_');
35
+ if (!upperKey.startsWith('AGENTUITY_')) {
36
+ return false;
37
+ }
38
+ if (upperKey.startsWith('AGENTUITY_PUBLIC_')) {
39
+ return false;
40
+ }
41
+ if (AGENTUITY_ALLOWED_KEYS.includes(key as (typeof AGENTUITY_ALLOWED_KEYS)[number])) {
42
+ return false;
43
+ }
44
+ return true;
30
45
  }
31
46
 
32
47
  /**
package/src/errors.ts CHANGED
@@ -14,6 +14,7 @@ export enum ExitCode {
14
14
  FILE_ERROR = 7,
15
15
  USER_CANCELLED = 8,
16
16
  BUILD_FAILED = 9,
17
+ SECURITY_ERROR = 10,
17
18
  }
18
19
 
19
20
  /**
@@ -75,6 +76,9 @@ export enum ErrorCode {
75
76
 
76
77
  // Integration errors
77
78
  INTEGRATION_FAILED = 'INTEGRATION_FAILED',
79
+
80
+ // Security errors
81
+ MALWARE_DETECTED = 'MALWARE_DETECTED',
78
82
  }
79
83
 
80
84
  /**
@@ -136,6 +140,10 @@ export function getExitCode(errorCode: ErrorCode): ExitCode {
136
140
  case ErrorCode.INTEGRATION_FAILED:
137
141
  return ExitCode.NETWORK_ERROR;
138
142
 
143
+ // Security errors
144
+ case ErrorCode.MALWARE_DETECTED:
145
+ return ExitCode.SECURITY_ERROR;
146
+
139
147
  // Resource conflicts and other errors
140
148
  case ErrorCode.RESOURCE_ALREADY_EXISTS:
141
149
  case ErrorCode.RESOURCE_CONFLICT: