@agentuity/cli 0.0.48 → 0.0.49

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 (256) hide show
  1. package/bin/cli.ts +26 -5
  2. package/dist/banner.d.ts +1 -1
  3. package/dist/banner.d.ts.map +1 -1
  4. package/dist/cli-logger.d.ts +27 -0
  5. package/dist/cli-logger.d.ts.map +1 -0
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cmd/auth/index.d.ts.map +1 -1
  8. package/dist/cmd/auth/login.d.ts.map +1 -1
  9. package/dist/cmd/auth/logout.d.ts.map +1 -1
  10. package/dist/cmd/auth/signup.d.ts.map +1 -1
  11. package/dist/cmd/auth/ssh/add.d.ts.map +1 -1
  12. package/dist/cmd/auth/ssh/delete.d.ts.map +1 -1
  13. package/dist/cmd/auth/ssh/index.d.ts +1 -2
  14. package/dist/cmd/auth/ssh/index.d.ts.map +1 -1
  15. package/dist/cmd/auth/ssh/list.d.ts.map +1 -1
  16. package/dist/cmd/auth/whoami.d.ts.map +1 -1
  17. package/dist/cmd/bundle/ast.d.ts.map +1 -1
  18. package/dist/cmd/bundle/index.d.ts.map +1 -1
  19. package/dist/cmd/bundle/plugin.d.ts.map +1 -1
  20. package/dist/cmd/capabilities/index.d.ts +4 -0
  21. package/dist/cmd/capabilities/index.d.ts.map +1 -0
  22. package/dist/cmd/capabilities/show.d.ts +20 -0
  23. package/dist/cmd/capabilities/show.d.ts.map +1 -0
  24. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  25. package/dist/cmd/cloud/deployment/index.d.ts.map +1 -1
  26. package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
  27. package/dist/cmd/cloud/deployment/remove.d.ts.map +1 -1
  28. package/dist/cmd/cloud/deployment/rollback.d.ts.map +1 -1
  29. package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
  30. package/dist/cmd/cloud/deployment/undeploy.d.ts.map +1 -1
  31. package/dist/cmd/cloud/deployment/utils.d.ts +4 -2
  32. package/dist/cmd/cloud/deployment/utils.d.ts.map +1 -1
  33. package/dist/cmd/cloud/domain.d.ts.map +1 -1
  34. package/dist/cmd/cloud/index.d.ts.map +1 -1
  35. package/dist/cmd/cloud/resource/add.d.ts.map +1 -1
  36. package/dist/cmd/cloud/resource/delete.d.ts.map +1 -1
  37. package/dist/cmd/cloud/resource/index.d.ts +1 -2
  38. package/dist/cmd/cloud/resource/index.d.ts.map +1 -1
  39. package/dist/cmd/cloud/resource/list.d.ts.map +1 -1
  40. package/dist/cmd/cloud/scp/download.d.ts.map +1 -1
  41. package/dist/cmd/cloud/scp/index.d.ts +1 -2
  42. package/dist/cmd/cloud/scp/index.d.ts.map +1 -1
  43. package/dist/cmd/cloud/scp/upload.d.ts.map +1 -1
  44. package/dist/cmd/cloud/ssh.d.ts.map +1 -1
  45. package/dist/cmd/dev/index.d.ts.map +1 -1
  46. package/dist/cmd/env/delete.d.ts.map +1 -1
  47. package/dist/cmd/env/get.d.ts.map +1 -1
  48. package/dist/cmd/env/import.d.ts.map +1 -1
  49. package/dist/cmd/env/index.d.ts.map +1 -1
  50. package/dist/cmd/env/list.d.ts.map +1 -1
  51. package/dist/cmd/env/pull.d.ts.map +1 -1
  52. package/dist/cmd/env/push.d.ts.map +1 -1
  53. package/dist/cmd/env/set.d.ts.map +1 -1
  54. package/dist/cmd/index.d.ts.map +1 -1
  55. package/dist/cmd/kv/create-namespace.d.ts +3 -0
  56. package/dist/cmd/kv/create-namespace.d.ts.map +1 -0
  57. package/dist/cmd/kv/delete-namespace.d.ts +3 -0
  58. package/dist/cmd/kv/delete-namespace.d.ts.map +1 -0
  59. package/dist/cmd/kv/delete.d.ts +3 -0
  60. package/dist/cmd/kv/delete.d.ts.map +1 -0
  61. package/dist/cmd/kv/get.d.ts +3 -0
  62. package/dist/cmd/kv/get.d.ts.map +1 -0
  63. package/dist/cmd/kv/index.d.ts +2 -0
  64. package/dist/cmd/kv/index.d.ts.map +1 -0
  65. package/dist/cmd/kv/keys.d.ts +3 -0
  66. package/dist/cmd/kv/keys.d.ts.map +1 -0
  67. package/dist/cmd/kv/list-namespaces.d.ts +3 -0
  68. package/dist/cmd/kv/list-namespaces.d.ts.map +1 -0
  69. package/dist/cmd/kv/repl.d.ts +3 -0
  70. package/dist/cmd/kv/repl.d.ts.map +1 -0
  71. package/dist/cmd/kv/search.d.ts +3 -0
  72. package/dist/cmd/kv/search.d.ts.map +1 -0
  73. package/dist/cmd/kv/set.d.ts +3 -0
  74. package/dist/cmd/kv/set.d.ts.map +1 -0
  75. package/dist/cmd/kv/stats.d.ts +3 -0
  76. package/dist/cmd/kv/stats.d.ts.map +1 -0
  77. package/dist/cmd/kv/util.d.ts +8 -0
  78. package/dist/cmd/kv/util.d.ts.map +1 -0
  79. package/dist/cmd/objectstore/delete-bucket.d.ts +3 -0
  80. package/dist/cmd/objectstore/delete-bucket.d.ts.map +1 -0
  81. package/dist/cmd/objectstore/delete.d.ts +3 -0
  82. package/dist/cmd/objectstore/delete.d.ts.map +1 -0
  83. package/dist/cmd/objectstore/get.d.ts +3 -0
  84. package/dist/cmd/objectstore/get.d.ts.map +1 -0
  85. package/dist/cmd/objectstore/index.d.ts +2 -0
  86. package/dist/cmd/objectstore/index.d.ts.map +1 -0
  87. package/dist/cmd/objectstore/list-buckets.d.ts +3 -0
  88. package/dist/cmd/objectstore/list-buckets.d.ts.map +1 -0
  89. package/dist/cmd/objectstore/list-keys.d.ts +3 -0
  90. package/dist/cmd/objectstore/list-keys.d.ts.map +1 -0
  91. package/dist/cmd/objectstore/put.d.ts +3 -0
  92. package/dist/cmd/objectstore/put.d.ts.map +1 -0
  93. package/dist/cmd/objectstore/repl.d.ts +3 -0
  94. package/dist/cmd/objectstore/repl.d.ts.map +1 -0
  95. package/dist/cmd/objectstore/url.d.ts +3 -0
  96. package/dist/cmd/objectstore/url.d.ts.map +1 -0
  97. package/dist/cmd/objectstore/util.d.ts +8 -0
  98. package/dist/cmd/objectstore/util.d.ts.map +1 -0
  99. package/dist/cmd/profile/create.d.ts.map +1 -1
  100. package/dist/cmd/profile/delete.d.ts.map +1 -1
  101. package/dist/cmd/profile/index.d.ts.map +1 -1
  102. package/dist/cmd/profile/list.d.ts +1 -2
  103. package/dist/cmd/profile/list.d.ts.map +1 -1
  104. package/dist/cmd/profile/show.d.ts.map +1 -1
  105. package/dist/cmd/profile/use.d.ts.map +1 -1
  106. package/dist/cmd/project/create.d.ts.map +1 -1
  107. package/dist/cmd/project/delete.d.ts.map +1 -1
  108. package/dist/cmd/project/index.d.ts.map +1 -1
  109. package/dist/cmd/project/list.d.ts.map +1 -1
  110. package/dist/cmd/project/show.d.ts.map +1 -1
  111. package/dist/cmd/project/template-flow.d.ts +1 -1
  112. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  113. package/dist/cmd/prompt/index.d.ts +4 -0
  114. package/dist/cmd/prompt/index.d.ts.map +1 -0
  115. package/dist/cmd/prompt/llm.d.ts +3 -0
  116. package/dist/cmd/prompt/llm.d.ts.map +1 -0
  117. package/dist/cmd/repl/index.d.ts +3 -0
  118. package/dist/cmd/repl/index.d.ts.map +1 -0
  119. package/dist/cmd/schema/index.d.ts +4 -0
  120. package/dist/cmd/schema/index.d.ts.map +1 -0
  121. package/dist/cmd/schema/show.d.ts +3 -0
  122. package/dist/cmd/schema/show.d.ts.map +1 -0
  123. package/dist/cmd/secret/delete.d.ts.map +1 -1
  124. package/dist/cmd/secret/get.d.ts.map +1 -1
  125. package/dist/cmd/secret/import.d.ts.map +1 -1
  126. package/dist/cmd/secret/index.d.ts.map +1 -1
  127. package/dist/cmd/secret/list.d.ts.map +1 -1
  128. package/dist/cmd/secret/pull.d.ts.map +1 -1
  129. package/dist/cmd/secret/push.d.ts.map +1 -1
  130. package/dist/cmd/secret/set.d.ts.map +1 -1
  131. package/dist/cmd/version/index.d.ts.map +1 -1
  132. package/dist/config.d.ts +1 -1
  133. package/dist/config.d.ts.map +1 -1
  134. package/dist/errors.d.ts +83 -0
  135. package/dist/errors.d.ts.map +1 -0
  136. package/dist/explain.d.ts +47 -0
  137. package/dist/explain.d.ts.map +1 -0
  138. package/dist/index.d.ts +6 -0
  139. package/dist/index.d.ts.map +1 -1
  140. package/dist/json.d.ts +3 -0
  141. package/dist/json.d.ts.map +1 -0
  142. package/dist/output.d.ts +136 -0
  143. package/dist/output.d.ts.map +1 -0
  144. package/dist/repl.d.ts +124 -0
  145. package/dist/repl.d.ts.map +1 -0
  146. package/dist/schema-generator.d.ts +67 -0
  147. package/dist/schema-generator.d.ts.map +1 -0
  148. package/dist/tui.d.ts +11 -1
  149. package/dist/tui.d.ts.map +1 -1
  150. package/dist/types.d.ts +65 -6
  151. package/dist/types.d.ts.map +1 -1
  152. package/package.json +9 -4
  153. package/src/banner.ts +7 -7
  154. package/src/cli-logger.ts +80 -0
  155. package/src/cli.ts +186 -54
  156. package/src/cmd/auth/index.ts +1 -0
  157. package/src/cmd/auth/login.ts +7 -2
  158. package/src/cmd/auth/logout.ts +4 -0
  159. package/src/cmd/auth/signup.ts +7 -2
  160. package/src/cmd/auth/ssh/add.ts +20 -3
  161. package/src/cmd/auth/ssh/delete.ts +57 -4
  162. package/src/cmd/auth/ssh/index.ts +4 -3
  163. package/src/cmd/auth/ssh/list.ts +29 -12
  164. package/src/cmd/auth/whoami.ts +32 -21
  165. package/src/cmd/bundle/ast.ts +27 -5
  166. package/src/cmd/bundle/index.ts +20 -0
  167. package/src/cmd/bundle/plugin.ts +36 -12
  168. package/src/cmd/capabilities/index.ts +12 -0
  169. package/src/cmd/capabilities/show.ts +256 -0
  170. package/src/cmd/cloud/deploy.ts +54 -0
  171. package/src/cmd/cloud/deployment/index.ts +1 -0
  172. package/src/cmd/cloud/deployment/list.ts +50 -3
  173. package/src/cmd/cloud/deployment/remove.ts +26 -2
  174. package/src/cmd/cloud/deployment/rollback.ts +35 -4
  175. package/src/cmd/cloud/deployment/show.ts +37 -2
  176. package/src/cmd/cloud/deployment/undeploy.ts +12 -1
  177. package/src/cmd/cloud/deployment/utils.ts +5 -2
  178. package/src/cmd/cloud/domain.ts +3 -2
  179. package/src/cmd/cloud/index.ts +8 -1
  180. package/src/cmd/cloud/resource/add.ts +19 -0
  181. package/src/cmd/cloud/resource/delete.ts +24 -3
  182. package/src/cmd/cloud/resource/index.ts +4 -3
  183. package/src/cmd/cloud/resource/list.ts +36 -10
  184. package/src/cmd/cloud/scp/download.ts +27 -1
  185. package/src/cmd/cloud/scp/index.ts +4 -3
  186. package/src/cmd/cloud/scp/upload.ts +27 -1
  187. package/src/cmd/cloud/ssh.ts +12 -0
  188. package/src/cmd/dev/index.ts +11 -7
  189. package/src/cmd/dev/templates.ts +1 -1
  190. package/src/cmd/env/delete.ts +17 -0
  191. package/src/cmd/env/get.ts +17 -1
  192. package/src/cmd/env/import.ts +47 -3
  193. package/src/cmd/env/index.ts +1 -0
  194. package/src/cmd/env/list.ts +13 -1
  195. package/src/cmd/env/pull.ts +20 -0
  196. package/src/cmd/env/push.ts +33 -1
  197. package/src/cmd/env/set.ts +25 -1
  198. package/src/cmd/index.ts +9 -2
  199. package/src/cmd/kv/create-namespace.ts +45 -0
  200. package/src/cmd/kv/delete-namespace.ts +73 -0
  201. package/src/cmd/kv/delete.ts +51 -0
  202. package/src/cmd/kv/get.ts +65 -0
  203. package/src/cmd/kv/index.ts +31 -0
  204. package/src/cmd/kv/keys.ts +57 -0
  205. package/src/cmd/kv/list-namespaces.ts +43 -0
  206. package/src/cmd/kv/repl.ts +284 -0
  207. package/src/cmd/kv/search.ts +80 -0
  208. package/src/cmd/kv/set.ts +63 -0
  209. package/src/cmd/kv/stats.ts +96 -0
  210. package/src/cmd/kv/util.ts +32 -0
  211. package/src/cmd/objectstore/delete-bucket.ts +72 -0
  212. package/src/cmd/objectstore/delete.ts +59 -0
  213. package/src/cmd/objectstore/get.ts +64 -0
  214. package/src/cmd/objectstore/index.ts +27 -0
  215. package/src/cmd/objectstore/list-buckets.ts +45 -0
  216. package/src/cmd/objectstore/list-keys.ts +60 -0
  217. package/src/cmd/objectstore/put.ts +62 -0
  218. package/src/cmd/objectstore/repl.ts +235 -0
  219. package/src/cmd/objectstore/url.ts +59 -0
  220. package/src/cmd/objectstore/util.ts +28 -0
  221. package/src/cmd/profile/create.ts +28 -2
  222. package/src/cmd/profile/delete.ts +17 -2
  223. package/src/cmd/profile/index.ts +1 -0
  224. package/src/cmd/profile/list.ts +7 -3
  225. package/src/cmd/profile/show.ts +20 -5
  226. package/src/cmd/profile/use.ts +8 -0
  227. package/src/cmd/project/create.ts +31 -0
  228. package/src/cmd/project/delete.ts +24 -2
  229. package/src/cmd/project/index.ts +1 -0
  230. package/src/cmd/project/list.ts +23 -9
  231. package/src/cmd/project/show.ts +27 -8
  232. package/src/cmd/project/template-flow.ts +10 -6
  233. package/src/cmd/prompt/index.ts +12 -0
  234. package/src/cmd/prompt/llm.ts +368 -0
  235. package/src/cmd/repl/index.ts +477 -0
  236. package/src/cmd/schema/index.ts +12 -0
  237. package/src/cmd/schema/show.ts +27 -0
  238. package/src/cmd/secret/delete.ts +17 -0
  239. package/src/cmd/secret/get.ts +20 -1
  240. package/src/cmd/secret/import.ts +45 -2
  241. package/src/cmd/secret/index.ts +1 -0
  242. package/src/cmd/secret/list.ts +10 -1
  243. package/src/cmd/secret/pull.ts +20 -0
  244. package/src/cmd/secret/push.ts +33 -1
  245. package/src/cmd/secret/set.ts +20 -0
  246. package/src/cmd/version/index.ts +15 -2
  247. package/src/config.ts +17 -4
  248. package/src/errors.ts +222 -0
  249. package/src/explain.ts +126 -0
  250. package/src/index.ts +51 -0
  251. package/src/json.ts +28 -0
  252. package/src/output.ts +307 -0
  253. package/src/repl.ts +1517 -0
  254. package/src/schema-generator.ts +389 -0
  255. package/src/tui.ts +84 -13
  256. package/src/types.ts +62 -12
@@ -27,12 +27,45 @@ import {
27
27
  import { zipDir } from '../../utils/zip';
28
28
  import { encryptFIPSKEMDEMStream } from '../../crypto/box';
29
29
  import { checkCustomDomainForDNS } from './domain';
30
+ import { getCommand } from '../../command-prefix';
31
+ import { z } from 'zod';
32
+
33
+ const DeployResponseSchema = z.object({
34
+ success: z.boolean().describe('Whether deployment succeeded'),
35
+ deploymentId: z.string().describe('Deployment ID'),
36
+ projectId: z.string().describe('Project ID'),
37
+ urls: z
38
+ .object({
39
+ deployment: z.string().describe('Deployment-specific URL'),
40
+ latest: z.string().describe('Latest/active deployment URL'),
41
+ custom: z.array(z.string()).optional().describe('Custom domain URLs'),
42
+ })
43
+ .optional()
44
+ .describe('Deployment URLs'),
45
+ });
30
46
 
31
47
  export const deploySubcommand = createSubcommand({
32
48
  name: 'deploy',
33
49
  description: 'Deploy project to the Agentuity Cloud',
50
+ tags: [
51
+ 'mutating',
52
+ 'creates-resource',
53
+ 'slow',
54
+ 'api-intensive',
55
+ 'requires-auth',
56
+ 'requires-project',
57
+ ],
58
+ examples: [
59
+ `${getCommand('cloud deploy')} # Deploy current project`,
60
+ `${getCommand('cloud deploy')} --log-level=debug # Deploy with verbose output`,
61
+ ],
34
62
  toplevel: true,
63
+ idempotent: false,
35
64
  requires: { auth: true, project: true, apiClient: true },
65
+ prerequisites: ['auth login'],
66
+ schema: {
67
+ response: DeployResponseSchema,
68
+ },
36
69
 
37
70
  async handler(ctx) {
38
71
  const { project, apiClient, projectDir, config, options } = ctx;
@@ -335,6 +368,27 @@ export const deploySubcommand = createSubcommand({
335
368
  );
336
369
  }
337
370
  }
371
+
372
+ // Return deployment result (if available)
373
+ if (deployment && complete?.publicUrls) {
374
+ return {
375
+ success: true,
376
+ deploymentId: deployment.id,
377
+ projectId: project.projectId,
378
+ urls: {
379
+ deployment: complete.publicUrls.deployment,
380
+ latest: complete.publicUrls.latest,
381
+ custom: complete.publicUrls.custom,
382
+ },
383
+ };
384
+ }
385
+
386
+ // Fallback response
387
+ return {
388
+ success: false,
389
+ deploymentId: '',
390
+ projectId: project.projectId,
391
+ };
338
392
  } catch (ex) {
339
393
  tui.fatal(`unexpected error trying to deploy project. ${ex}`);
340
394
  }
@@ -8,6 +8,7 @@ import { undeploySubcommand } from './undeploy';
8
8
  export const deploymentCommand = createCommand({
9
9
  name: 'deployment',
10
10
  description: 'Manage deployments',
11
+ tags: ['read-only', 'fast', 'requires-auth'],
11
12
  aliases: ['deployments', 'dep'],
12
13
  subcommands: [
13
14
  listSubcommand,
@@ -4,18 +4,53 @@ import * as tui from '../../../tui';
4
4
  import { projectDeploymentList } from '@agentuity/server';
5
5
  import { resolveProjectId } from './utils';
6
6
  import { Table } from 'console-table-printer';
7
+ import { getCommand } from '../../../command-prefix';
8
+ import { ErrorCode } from '../../../errors';
9
+
10
+ const DeploymentListResponseSchema = z.array(
11
+ z.object({
12
+ id: z.string().describe('Deployment ID'),
13
+ state: z.string().optional().describe('Current state of the deployment'),
14
+ active: z.boolean().describe('Whether this is the active deployment'),
15
+ createdAt: z.string().describe('Creation timestamp'),
16
+ message: z.string().optional().describe('Deployment message or description'),
17
+ tags: z.array(z.string()).describe('Deployment tags'),
18
+ })
19
+ );
7
20
 
8
21
  export const listSubcommand = createSubcommand({
9
22
  name: 'list',
10
23
  description: 'List deployments',
24
+ tags: ['read-only', 'slow', 'requires-auth'],
25
+ examples: [
26
+ `${getCommand('cloud deployment list')} # List 10 most recent deployments`,
27
+ `${getCommand('cloud deployment list')} --count=25 # List 25 most recent deployments`,
28
+ `${getCommand('cloud deployment list')} --project-id=proj_abc123xyz`,
29
+ ],
11
30
  aliases: ['ls'],
12
31
  requires: { auth: true, apiClient: true },
13
32
  optional: { project: true },
33
+ idempotent: true,
34
+ pagination: {
35
+ supported: true,
36
+ defaultLimit: 10,
37
+ maxLimit: 100,
38
+ parameters: {
39
+ limit: 'count',
40
+ },
41
+ },
14
42
  schema: {
15
43
  options: z.object({
16
44
  'project-id': z.string().optional().describe('Project ID'),
17
- count: z.coerce.number().default(10).describe('Number of deployments to list'),
45
+ count: z.coerce
46
+ .number()
47
+ .int()
48
+ .min(1)
49
+ .max(100)
50
+ .default(10)
51
+ .describe('Number of deployments to list (1–100)'),
18
52
  }),
53
+ response: DeploymentListResponseSchema,
19
54
  },
20
55
  async handler(ctx) {
21
56
  const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
@@ -26,7 +61,7 @@ export const listSubcommand = createSubcommand({
26
61
 
27
62
  if (deployments.length === 0) {
28
63
  tui.info('No deployments found.');
29
- return;
64
+ return [];
30
65
  }
31
66
 
32
67
  const table = new Table({
@@ -51,8 +86,20 @@ export const listSubcommand = createSubcommand({
51
86
  });
52
87
  }
53
88
  table.printTable();
89
+
90
+ return deployments.map((d) => ({
91
+ id: d.id,
92
+ state: d.state,
93
+ active: d.active,
94
+ createdAt: d.createdAt,
95
+ message: d.message,
96
+ tags: d.tags,
97
+ }));
54
98
  } catch (ex) {
55
- tui.fatal(`Failed to list deployments: ${ex instanceof Error ? ex.message : String(ex)}`);
99
+ tui.fatal(
100
+ `Failed to list deployments: ${ex instanceof Error ? ex.message : String(ex)}`,
101
+ ErrorCode.API_ERROR
102
+ );
56
103
  }
57
104
  },
58
105
  });
@@ -3,13 +3,28 @@ import { createSubcommand } from '../../../types';
3
3
  import * as tui from '../../../tui';
4
4
  import { projectDeploymentDelete } from '@agentuity/server';
5
5
  import { resolveProjectId } from './utils';
6
+ import { getCommand } from '../../../command-prefix';
7
+
8
+ const DeploymentRemoveResponseSchema = z.object({
9
+ success: z.boolean().describe('Whether the removal succeeded'),
10
+ projectId: z.string().describe('Project ID'),
11
+ deploymentId: z.string().describe('Deployment ID that was removed'),
12
+ });
6
13
 
7
14
  export const removeSubcommand = createSubcommand({
8
15
  name: 'remove',
9
16
  description: 'Remove a specific deployment',
17
+ tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth', 'requires-deployment'],
18
+ examples: [
19
+ `${getCommand('cloud deployment remove')} dep_abc123xyz # Remove with confirmation`,
20
+ `${getCommand('cloud deployment remove')} dep_abc123xyz --force # Remove without confirmation`,
21
+ `${getCommand('cloud deployment remove')} deployment-2024-11-20 --project-id=proj_abc123xyz`,
22
+ ],
10
23
  aliases: ['rm', 'delete'],
24
+ idempotent: false,
11
25
  requires: { auth: true, apiClient: true },
12
26
  optional: { project: true },
27
+ prerequisites: ['cloud deploy'],
13
28
  schema: {
14
29
  args: z.object({
15
30
  deployment_id: z.string().describe('Deployment ID'),
@@ -18,22 +33,31 @@ export const removeSubcommand = createSubcommand({
18
33
  'project-id': z.string().optional().describe('Project ID'),
19
34
  force: z.boolean().default(false).describe('Force removal without confirmation'),
20
35
  }),
36
+ response: DeploymentRemoveResponseSchema,
21
37
  },
22
38
  async handler(ctx) {
23
39
  const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
24
40
  const { apiClient, args, opts } = ctx;
25
41
 
26
42
  if (!opts.force) {
27
- const confirmed = await tui.confirm(`Are you sure you want to remove deployment ${args.deployment_id}?`);
43
+ const confirmed = await tui.confirm(
44
+ `Are you sure you want to remove deployment ${args.deployment_id}?`
45
+ );
28
46
  if (!confirmed) {
29
47
  tui.info('Operation cancelled');
30
- return;
48
+ return { success: false, projectId, deploymentId: args.deployment_id };
31
49
  }
32
50
  }
33
51
 
34
52
  try {
35
53
  await projectDeploymentDelete(apiClient, projectId, args.deployment_id);
36
54
  tui.success(`Deployment ${args.deployment_id} removed successfully.`);
55
+
56
+ return {
57
+ success: true,
58
+ projectId,
59
+ deploymentId: args.deployment_id,
60
+ };
37
61
  } catch (ex) {
38
62
  tui.fatal(`Failed to remove deployment: ${ex instanceof Error ? ex.message : String(ex)}`);
39
63
  }
@@ -3,16 +3,39 @@ import { createSubcommand } from '../../../types';
3
3
  import * as tui from '../../../tui';
4
4
  import { projectDeploymentRollback, projectDeploymentList } from '@agentuity/server';
5
5
  import { resolveProjectId } from './utils';
6
+ import { getCommand } from '../../../command-prefix';
7
+
8
+ const DeploymentRollbackResponseSchema = z.object({
9
+ success: z.boolean().describe('Whether the rollback succeeded'),
10
+ projectId: z.string().describe('Project ID'),
11
+ targetDeploymentId: z.string().describe('Deployment ID that was rolled back to'),
12
+ });
6
13
 
7
14
  export const rollbackSubcommand = createSubcommand({
8
15
  name: 'rollback',
9
16
  description: 'Rollback the latest to the previous deployment',
17
+ tags: [
18
+ 'destructive',
19
+ 'deletes-resource',
20
+ 'updates-resource',
21
+ 'slow',
22
+ 'api-intensive',
23
+ 'requires-auth',
24
+ 'requires-deployment',
25
+ ],
26
+ examples: [
27
+ `${getCommand('cloud deployment rollback')} # Rollback to previous deployment`,
28
+ `${getCommand('cloud deployment rollback')} --project-id=proj_abc123xyz`,
29
+ ],
30
+ idempotent: false,
10
31
  requires: { auth: true, apiClient: true },
11
32
  optional: { project: true },
33
+ prerequisites: ['cloud deploy'],
12
34
  schema: {
13
35
  options: z.object({
14
36
  'project-id': z.string().optional().describe('Project ID'),
15
37
  }),
38
+ response: DeploymentRollbackResponseSchema,
16
39
  },
17
40
  async handler(ctx) {
18
41
  const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
@@ -23,17 +46,19 @@ export const rollbackSubcommand = createSubcommand({
23
46
  const deployments = await projectDeploymentList(apiClient, projectId, 5);
24
47
 
25
48
  // Find currently active
26
- const activeIndex = deployments.findIndex(d => d.active);
49
+ const activeIndex = deployments.findIndex((d) => d.active);
27
50
 
28
51
  let targetDeploymentId: string | undefined;
29
52
 
30
53
  if (activeIndex === -1) {
31
54
  // No active deployment.
32
- const candidate = deployments.find(d => d.state === 'completed');
55
+ const candidate = deployments.find((d) => d.state === 'completed');
33
56
  targetDeploymentId = candidate?.id;
34
57
  } else {
35
58
  // Has active deployment. Find the next completed one.
36
- const candidate = deployments.slice(activeIndex + 1).find(d => d.state === 'completed');
59
+ const candidate = deployments
60
+ .slice(activeIndex + 1)
61
+ .find((d) => d.state === 'completed');
37
62
  targetDeploymentId = candidate?.id;
38
63
  }
39
64
 
@@ -44,11 +69,17 @@ export const rollbackSubcommand = createSubcommand({
44
69
  const confirmed = await tui.confirm(`Rollback to deployment ${targetDeploymentId}?`);
45
70
  if (!confirmed) {
46
71
  tui.info('Operation cancelled');
47
- return;
72
+ return { success: false, projectId, targetDeploymentId };
48
73
  }
49
74
 
50
75
  await projectDeploymentRollback(apiClient, projectId, targetDeploymentId!);
51
76
  tui.success(`Rolled back to deployment ${targetDeploymentId}.`);
77
+
78
+ return {
79
+ success: true,
80
+ projectId,
81
+ targetDeploymentId,
82
+ };
52
83
  } catch (ex) {
53
84
  tui.fatal(`Failed to rollback: ${ex instanceof Error ? ex.message : String(ex)}`);
54
85
  }
@@ -3,13 +3,33 @@ import { createSubcommand } from '../../../types';
3
3
  import * as tui from '../../../tui';
4
4
  import { projectDeploymentGet } from '@agentuity/server';
5
5
  import { resolveProjectId } from './utils';
6
+ import { getCommand } from '../../../command-prefix';
7
+
8
+ const DeploymentShowResponseSchema = z.object({
9
+ id: z.string().describe('Deployment ID'),
10
+ state: z.string().optional().describe('Deployment state'),
11
+ active: z.boolean().describe('Whether deployment is active'),
12
+ createdAt: z.string().describe('Creation timestamp'),
13
+ updatedAt: z.string().optional().describe('Last update timestamp'),
14
+ message: z.string().optional().describe('Deployment message'),
15
+ tags: z.array(z.string()).describe('Deployment tags'),
16
+ customDomains: z.array(z.string()).optional().describe('Custom domains'),
17
+ cloudRegion: z.string().optional().describe('Cloud region'),
18
+ metadata: z.any().optional().describe('Deployment metadata'),
19
+ });
6
20
 
7
21
  export const showSubcommand = createSubcommand({
8
22
  name: 'show',
9
23
  description: 'Show details about a specific deployment',
24
+ tags: ['read-only', 'fast', 'requires-auth', 'requires-deployment'],
25
+ examples: [
26
+ `${getCommand('cloud deployment show')} dep_abc123xyz`,
27
+ `${getCommand('cloud deployment show')} deployment-2024-11-20 --project-id=proj_abc123xyz`,
28
+ ],
10
29
  aliases: ['get'],
11
30
  requires: { auth: true, apiClient: true },
12
31
  optional: { project: true },
32
+ prerequisites: ['cloud deploy'],
13
33
  schema: {
14
34
  args: z.object({
15
35
  deployment_id: z.string().describe('Deployment ID'),
@@ -17,7 +37,9 @@ export const showSubcommand = createSubcommand({
17
37
  options: z.object({
18
38
  'project-id': z.string().optional().describe('Project ID'),
19
39
  }),
40
+ response: DeploymentShowResponseSchema,
20
41
  },
42
+ idempotent: true,
21
43
  async handler(ctx) {
22
44
  const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
23
45
  const { apiClient, args } = ctx;
@@ -49,10 +71,10 @@ export const showSubcommand = createSubcommand({
49
71
  }
50
72
 
51
73
  // Metadata
52
- if (deployment.metadata?.origin?.commit) {
74
+ const origin = deployment.metadata?.origin;
75
+ if (origin?.commit) {
53
76
  tui.newline();
54
77
  tui.info('Origin Information');
55
- const origin = deployment.metadata.origin;
56
78
  if (origin.trigger) console.log(` Trigger: ${origin.trigger}`);
57
79
  if (origin.provider) console.log(` Provider: ${origin.provider}`);
58
80
  if (origin.event) console.log(` Event: ${origin.event}`);
@@ -65,6 +87,19 @@ export const showSubcommand = createSubcommand({
65
87
  console.log(` Author: ${origin.commit.author.name}`);
66
88
  }
67
89
  }
90
+
91
+ return {
92
+ id: deployment.id,
93
+ state: deployment.state,
94
+ active: deployment.active,
95
+ createdAt: deployment.createdAt,
96
+ updatedAt: deployment.updatedAt,
97
+ message: deployment.message,
98
+ tags: deployment.tags,
99
+ customDomains: deployment.customDomains,
100
+ cloudRegion: deployment.cloudRegion,
101
+ metadata: deployment.metadata,
102
+ };
68
103
  } catch (ex) {
69
104
  tui.fatal(`Failed to show deployment: ${ex instanceof Error ? ex.message : String(ex)}`);
70
105
  }
@@ -3,12 +3,21 @@ import { createSubcommand } from '../../../types';
3
3
  import * as tui from '../../../tui';
4
4
  import { projectDeploymentUndeploy } from '@agentuity/server';
5
5
  import { resolveProjectId } from './utils';
6
+ import { getCommand } from '../../../command-prefix';
6
7
 
7
8
  export const undeploySubcommand = createSubcommand({
8
9
  name: 'undeploy',
9
10
  description: 'Undeploy the latest deployment',
11
+ tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth', 'requires-deployment'],
12
+ examples: [
13
+ `${getCommand('cloud deployment undeploy')} # Undeploy with confirmation`,
14
+ `${getCommand('cloud deployment undeploy')} --force # Undeploy without confirmation`,
15
+ `${getCommand('cloud deployment undeploy')} --project-id=proj_abc123xyz`,
16
+ ],
17
+ idempotent: false,
10
18
  requires: { auth: true, apiClient: true },
11
19
  optional: { project: true },
20
+ prerequisites: ['cloud deploy'],
12
21
  schema: {
13
22
  options: z.object({
14
23
  'project-id': z.string().optional().describe('Project ID'),
@@ -20,7 +29,9 @@ export const undeploySubcommand = createSubcommand({
20
29
  const { apiClient, opts } = ctx;
21
30
 
22
31
  if (!opts.force) {
23
- const confirmed = await tui.confirm('Are you sure you want to undeploy? This will stop the active deployment.');
32
+ const confirmed = await tui.confirm(
33
+ 'Are you sure you want to undeploy? This will stop the active deployment.'
34
+ );
24
35
  if (!confirmed) {
25
36
  tui.info('Operation cancelled');
26
37
  return;
@@ -1,6 +1,9 @@
1
- import { CommandContext } from '../../../types';
1
+ import { ProjectConfig } from '../../../types';
2
2
 
3
- export function resolveProjectId(ctx: CommandContext<any, any>, options: { projectId?: string }): string {
3
+ export function resolveProjectId(
4
+ ctx: { project?: ProjectConfig },
5
+ options: { projectId?: string }
6
+ ): string {
4
7
  if (options.projectId) {
5
8
  return options.projectId;
6
9
  }
@@ -23,8 +23,9 @@ export async function checkCustomDomainForDNS(
23
23
  ): Promise<DNSResult[]> {
24
24
  const suffix = config?.overrides?.api_url?.includes('agentuity.io')
25
25
  ? 'agentuity.io'
26
- : 'agentuity.com';
27
- const id = Bun.hash.xxHash64(`${projectId}latest`).toString(16);
26
+ : 'agentuity.cloud';
27
+ // FIXME: update to add the region into this
28
+ const id = Bun.hash.xxHash64(projectId).toString(16);
28
29
  const proxy = `p${id}.${suffix}`;
29
30
 
30
31
  return Promise.all(
@@ -8,5 +8,12 @@ import { deploymentCommand } from './deployment';
8
8
  export const command = createCommand({
9
9
  name: 'cloud',
10
10
  description: 'Cloud related commands',
11
- subcommands: [deploySubcommand, resourceSubcommand, sshSubcommand, scpSubcommand, deploymentCommand],
11
+ tags: ['slow', 'requires-auth'],
12
+ subcommands: [
13
+ deploySubcommand,
14
+ resourceSubcommand,
15
+ sshSubcommand,
16
+ scpSubcommand,
17
+ deploymentCommand,
18
+ ],
12
19
  });
@@ -4,16 +4,30 @@ import enquirer from 'enquirer';
4
4
  import { createSubcommand } from '../../../types';
5
5
  import * as tui from '../../../tui';
6
6
  import { getCatalystAPIClient } from '../../../config';
7
+ import { getCommand } from '../../../command-prefix';
7
8
 
8
9
  export const addSubcommand = createSubcommand({
9
10
  name: 'add',
10
11
  aliases: ['create'],
11
12
  description: 'Add a cloud resource for an organization',
13
+ tags: ['mutating', 'creates-resource', 'slow', 'requires-auth', 'requires-deployment'],
14
+ idempotent: false,
12
15
  requires: { auth: true, org: true, region: true },
16
+ examples: [
17
+ getCommand('cloud resource add'),
18
+ getCommand('cloud resource add --type database'),
19
+ getCommand('cloud resource add --type storage'),
20
+ getCommand('cloud resource create --type database'),
21
+ ],
13
22
  schema: {
14
23
  options: z.object({
15
24
  type: z.enum(['database', 'storage']).optional().describe('Resource type'),
16
25
  }),
26
+ response: z.object({
27
+ success: z.boolean().describe('Whether creation succeeded'),
28
+ type: z.string().describe('Resource type (database or storage)'),
29
+ name: z.string().describe('Created resource name'),
30
+ }),
17
31
  },
18
32
 
19
33
  async handler(ctx) {
@@ -49,6 +63,11 @@ export const addSubcommand = createSubcommand({
49
63
 
50
64
  if (created.length > 0) {
51
65
  tui.success(`Created ${resourceType}: ${tui.bold(created[0].name)}`);
66
+ return {
67
+ success: true,
68
+ type: resourceType,
69
+ name: created[0].name,
70
+ };
52
71
  } else {
53
72
  tui.fatal('Failed to create resource');
54
73
  }
@@ -4,18 +4,33 @@ import enquirer from 'enquirer';
4
4
  import { createSubcommand } from '../../../types';
5
5
  import * as tui from '../../../tui';
6
6
  import { getCatalystAPIClient } from '../../../config';
7
+ import { getCommand } from '../../../command-prefix';
7
8
 
8
9
  export const deleteSubcommand = createSubcommand({
9
10
  name: 'delete',
10
11
  description: 'Delete cloud resource(s) for an organization',
12
+ tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth', 'requires-deployment'],
11
13
  aliases: ['rm', 'del', 'remove'],
14
+ idempotent: false,
12
15
  requires: { auth: true, org: true, region: true },
16
+ examples: [
17
+ getCommand('cloud resource delete'),
18
+ getCommand('cloud resource delete --type db --name my-database'),
19
+ getCommand('cloud resource delete --type s3 --name uploads'),
20
+ getCommand('--explain cloud resource delete --type db --name old-db'),
21
+ getCommand('--dry-run cloud resource rm --type s3 --name temp-bucket'),
22
+ ],
13
23
  schema: {
14
24
  options: z.object({
15
25
  type: z.enum(['db', 's3']).optional().describe('Resource type (db or s3)'),
16
26
  name: z.string().optional().describe('Resource name to delete'),
17
27
  confirm: z.boolean().optional().describe('Skip confirmation prompts'),
18
28
  }),
29
+ response: z.object({
30
+ success: z.boolean().describe('Whether deletion succeeded'),
31
+ count: z.number().describe('Number of resources deleted'),
32
+ resources: z.array(z.string()).describe('Deleted resource names'),
33
+ }),
19
34
  },
20
35
 
21
36
  async handler(ctx) {
@@ -41,7 +56,7 @@ export const deleteSubcommand = createSubcommand({
41
56
 
42
57
  if (resources.db.length === 0 && resources.s3.length === 0) {
43
58
  tui.info('No resources found to delete');
44
- return;
59
+ return { success: false, count: 0, resources: [] };
45
60
  }
46
61
 
47
62
  // Build choices for multi-select and resource map
@@ -81,7 +96,7 @@ export const deleteSubcommand = createSubcommand({
81
96
 
82
97
  if (resourcesToDelete.length === 0) {
83
98
  tui.info('No resources selected for deletion');
84
- return;
99
+ return { success: false, count: 0, resources: [] };
85
100
  }
86
101
 
87
102
  // Confirm deletion
@@ -98,7 +113,7 @@ export const deleteSubcommand = createSubcommand({
98
113
 
99
114
  if (!confirm.confirm) {
100
115
  tui.info('Deletion cancelled');
101
- return;
116
+ return { success: false, count: 0, resources: [] };
102
117
  }
103
118
  }
104
119
 
@@ -116,5 +131,11 @@ export const deleteSubcommand = createSubcommand({
116
131
  } else {
117
132
  tui.error('Failed to delete resources');
118
133
  }
134
+
135
+ return {
136
+ success: deleted.length > 0,
137
+ count: deleted.length,
138
+ resources: deleted,
139
+ };
119
140
  },
120
141
  });
@@ -1,11 +1,12 @@
1
- import type { SubcommandDefinition } from '../../../types';
1
+ import { createCommand } from '../../../types';
2
2
  import { listSubcommand } from './list';
3
3
  import { addSubcommand } from './add';
4
4
  import { deleteSubcommand } from './delete';
5
5
 
6
- export const resourceSubcommand: SubcommandDefinition = {
6
+ export const resourceSubcommand = createCommand({
7
7
  name: 'resource',
8
8
  aliases: ['resources'],
9
9
  description: 'Manage cloud resources',
10
+ tags: ['fast', 'requires-auth', 'requires-deployment'],
10
11
  subcommands: [listSubcommand, addSubcommand, deleteSubcommand],
11
- };
12
+ });
@@ -3,24 +3,48 @@ import { listResources } from '@agentuity/server';
3
3
  import { createSubcommand } from '../../../types';
4
4
  import * as tui from '../../../tui';
5
5
  import { getCatalystAPIClient } from '../../../config';
6
+ import { getCommand } from '../../../command-prefix';
7
+
8
+ const ResourceListResponseSchema = z.object({
9
+ db: z
10
+ .array(
11
+ z.object({
12
+ name: z.string().describe('Database name'),
13
+ url: z.string().optional().describe('Database connection URL'),
14
+ })
15
+ )
16
+ .describe('List of database resources'),
17
+ s3: z
18
+ .array(
19
+ z.object({
20
+ bucket_name: z.string().describe('Storage bucket name'),
21
+ access_key: z.string().optional().describe('S3 access key'),
22
+ secret_key: z.string().optional().describe('S3 secret key'),
23
+ region: z.string().optional().describe('S3 region'),
24
+ endpoint: z.string().optional().describe('S3 endpoint URL'),
25
+ })
26
+ )
27
+ .describe('List of storage resources'),
28
+ });
6
29
 
7
30
  export const listSubcommand = createSubcommand({
8
31
  name: 'list',
9
32
  description: 'List cloud resources for an organization',
33
+ tags: ['read-only', 'fast', 'requires-auth'],
10
34
  aliases: ['ls'],
11
35
  requires: { auth: true, org: true, region: true },
36
+ idempotent: true,
37
+ examples: [
38
+ getCommand('cloud resource list'),
39
+ getCommand('--json cloud resource list'),
40
+ getCommand('cloud resource ls'),
41
+ ],
12
42
  schema: {
13
- options: z.object({
14
- format: z
15
- .enum(['text', 'json'])
16
- .optional()
17
- .default('text')
18
- .describe('Output format (text or json)'),
19
- }),
43
+ response: ResourceListResponseSchema,
20
44
  },
21
45
 
22
46
  async handler(ctx) {
23
- const { logger, opts, orgId, region, config, auth } = ctx;
47
+ const { logger, options, orgId, region, config, auth } = ctx;
24
48
 
25
49
  const catalystClient = getCatalystAPIClient(config, logger, auth);
26
50
 
@@ -33,13 +57,13 @@ export const listSubcommand = createSubcommand({
33
57
  });
34
58
 
35
59
  // Output based on format
36
- if (opts.format === 'json') {
60
+ if (options.json) {
37
61
  console.log(JSON.stringify(resources, null, 2));
38
62
  } else {
39
63
  // Text table format
40
64
  if (resources.db.length === 0 && resources.s3.length === 0) {
41
65
  tui.info('No resources found');
42
- return;
66
+ return { db: [], s3: [] };
43
67
  }
44
68
 
45
69
  if (resources.db.length > 0) {
@@ -65,5 +89,7 @@ export const listSubcommand = createSubcommand({
65
89
  }
66
90
  }
67
91
  }
92
+
93
+ return resources;
68
94
  },
69
95
  });