@agentuity/cli 0.0.48 → 0.0.50

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 (282) 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/agents/index.d.ts +2 -0
  8. package/dist/cmd/agents/index.d.ts.map +1 -0
  9. package/dist/cmd/auth/index.d.ts.map +1 -1
  10. package/dist/cmd/auth/login.d.ts.map +1 -1
  11. package/dist/cmd/auth/logout.d.ts.map +1 -1
  12. package/dist/cmd/auth/signup.d.ts.map +1 -1
  13. package/dist/cmd/auth/ssh/add.d.ts.map +1 -1
  14. package/dist/cmd/auth/ssh/delete.d.ts.map +1 -1
  15. package/dist/cmd/auth/ssh/index.d.ts +1 -2
  16. package/dist/cmd/auth/ssh/index.d.ts.map +1 -1
  17. package/dist/cmd/auth/ssh/list.d.ts.map +1 -1
  18. package/dist/cmd/auth/whoami.d.ts.map +1 -1
  19. package/dist/cmd/bundle/ast.d.ts +3 -1
  20. package/dist/cmd/bundle/ast.d.ts.map +1 -1
  21. package/dist/cmd/bundle/index.d.ts.map +1 -1
  22. package/dist/cmd/bundle/plugin.d.ts.map +1 -1
  23. package/dist/cmd/capabilities/index.d.ts +4 -0
  24. package/dist/cmd/capabilities/index.d.ts.map +1 -0
  25. package/dist/cmd/capabilities/show.d.ts +20 -0
  26. package/dist/cmd/capabilities/show.d.ts.map +1 -0
  27. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  28. package/dist/cmd/cloud/deployment/index.d.ts.map +1 -1
  29. package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
  30. package/dist/cmd/cloud/deployment/remove.d.ts.map +1 -1
  31. package/dist/cmd/cloud/deployment/rollback.d.ts.map +1 -1
  32. package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
  33. package/dist/cmd/cloud/deployment/undeploy.d.ts.map +1 -1
  34. package/dist/cmd/cloud/deployment/utils.d.ts +4 -2
  35. package/dist/cmd/cloud/deployment/utils.d.ts.map +1 -1
  36. package/dist/cmd/cloud/domain.d.ts.map +1 -1
  37. package/dist/cmd/cloud/index.d.ts.map +1 -1
  38. package/dist/cmd/cloud/resource/add.d.ts.map +1 -1
  39. package/dist/cmd/cloud/resource/delete.d.ts.map +1 -1
  40. package/dist/cmd/cloud/resource/index.d.ts +1 -2
  41. package/dist/cmd/cloud/resource/index.d.ts.map +1 -1
  42. package/dist/cmd/cloud/resource/list.d.ts.map +1 -1
  43. package/dist/cmd/cloud/scp/download.d.ts.map +1 -1
  44. package/dist/cmd/cloud/scp/index.d.ts +1 -2
  45. package/dist/cmd/cloud/scp/index.d.ts.map +1 -1
  46. package/dist/cmd/cloud/scp/upload.d.ts.map +1 -1
  47. package/dist/cmd/cloud/session/get.d.ts +2 -0
  48. package/dist/cmd/cloud/session/get.d.ts.map +1 -0
  49. package/dist/cmd/cloud/session/index.d.ts +2 -0
  50. package/dist/cmd/cloud/session/index.d.ts.map +1 -0
  51. package/dist/cmd/cloud/session/list.d.ts +2 -0
  52. package/dist/cmd/cloud/session/list.d.ts.map +1 -0
  53. package/dist/cmd/cloud/session/logs.d.ts +2 -0
  54. package/dist/cmd/cloud/session/logs.d.ts.map +1 -0
  55. package/dist/cmd/cloud/ssh.d.ts.map +1 -1
  56. package/dist/cmd/dev/agents.d.ts +2 -0
  57. package/dist/cmd/dev/agents.d.ts.map +1 -0
  58. package/dist/cmd/dev/index.d.ts.map +1 -1
  59. package/dist/cmd/dev/sync.d.ts +12 -0
  60. package/dist/cmd/dev/sync.d.ts.map +1 -0
  61. package/dist/cmd/env/delete.d.ts.map +1 -1
  62. package/dist/cmd/env/get.d.ts.map +1 -1
  63. package/dist/cmd/env/import.d.ts.map +1 -1
  64. package/dist/cmd/env/index.d.ts.map +1 -1
  65. package/dist/cmd/env/list.d.ts.map +1 -1
  66. package/dist/cmd/env/pull.d.ts.map +1 -1
  67. package/dist/cmd/env/push.d.ts.map +1 -1
  68. package/dist/cmd/env/set.d.ts.map +1 -1
  69. package/dist/cmd/index.d.ts.map +1 -1
  70. package/dist/cmd/kv/create-namespace.d.ts +3 -0
  71. package/dist/cmd/kv/create-namespace.d.ts.map +1 -0
  72. package/dist/cmd/kv/delete-namespace.d.ts +3 -0
  73. package/dist/cmd/kv/delete-namespace.d.ts.map +1 -0
  74. package/dist/cmd/kv/delete.d.ts +3 -0
  75. package/dist/cmd/kv/delete.d.ts.map +1 -0
  76. package/dist/cmd/kv/get.d.ts +3 -0
  77. package/dist/cmd/kv/get.d.ts.map +1 -0
  78. package/dist/cmd/kv/index.d.ts +2 -0
  79. package/dist/cmd/kv/index.d.ts.map +1 -0
  80. package/dist/cmd/kv/keys.d.ts +3 -0
  81. package/dist/cmd/kv/keys.d.ts.map +1 -0
  82. package/dist/cmd/kv/list-namespaces.d.ts +3 -0
  83. package/dist/cmd/kv/list-namespaces.d.ts.map +1 -0
  84. package/dist/cmd/kv/repl.d.ts +3 -0
  85. package/dist/cmd/kv/repl.d.ts.map +1 -0
  86. package/dist/cmd/kv/search.d.ts +3 -0
  87. package/dist/cmd/kv/search.d.ts.map +1 -0
  88. package/dist/cmd/kv/set.d.ts +3 -0
  89. package/dist/cmd/kv/set.d.ts.map +1 -0
  90. package/dist/cmd/kv/stats.d.ts +3 -0
  91. package/dist/cmd/kv/stats.d.ts.map +1 -0
  92. package/dist/cmd/kv/util.d.ts +8 -0
  93. package/dist/cmd/kv/util.d.ts.map +1 -0
  94. package/dist/cmd/objectstore/delete-bucket.d.ts +3 -0
  95. package/dist/cmd/objectstore/delete-bucket.d.ts.map +1 -0
  96. package/dist/cmd/objectstore/delete.d.ts +3 -0
  97. package/dist/cmd/objectstore/delete.d.ts.map +1 -0
  98. package/dist/cmd/objectstore/get.d.ts +3 -0
  99. package/dist/cmd/objectstore/get.d.ts.map +1 -0
  100. package/dist/cmd/objectstore/index.d.ts +2 -0
  101. package/dist/cmd/objectstore/index.d.ts.map +1 -0
  102. package/dist/cmd/objectstore/list-buckets.d.ts +3 -0
  103. package/dist/cmd/objectstore/list-buckets.d.ts.map +1 -0
  104. package/dist/cmd/objectstore/list-keys.d.ts +3 -0
  105. package/dist/cmd/objectstore/list-keys.d.ts.map +1 -0
  106. package/dist/cmd/objectstore/put.d.ts +3 -0
  107. package/dist/cmd/objectstore/put.d.ts.map +1 -0
  108. package/dist/cmd/objectstore/repl.d.ts +3 -0
  109. package/dist/cmd/objectstore/repl.d.ts.map +1 -0
  110. package/dist/cmd/objectstore/url.d.ts +3 -0
  111. package/dist/cmd/objectstore/url.d.ts.map +1 -0
  112. package/dist/cmd/objectstore/util.d.ts +8 -0
  113. package/dist/cmd/objectstore/util.d.ts.map +1 -0
  114. package/dist/cmd/profile/create.d.ts.map +1 -1
  115. package/dist/cmd/profile/delete.d.ts.map +1 -1
  116. package/dist/cmd/profile/index.d.ts.map +1 -1
  117. package/dist/cmd/profile/list.d.ts +1 -2
  118. package/dist/cmd/profile/list.d.ts.map +1 -1
  119. package/dist/cmd/profile/show.d.ts.map +1 -1
  120. package/dist/cmd/profile/use.d.ts.map +1 -1
  121. package/dist/cmd/project/create.d.ts.map +1 -1
  122. package/dist/cmd/project/delete.d.ts.map +1 -1
  123. package/dist/cmd/project/index.d.ts.map +1 -1
  124. package/dist/cmd/project/list.d.ts.map +1 -1
  125. package/dist/cmd/project/show.d.ts.map +1 -1
  126. package/dist/cmd/project/template-flow.d.ts +1 -1
  127. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  128. package/dist/cmd/prompt/index.d.ts +4 -0
  129. package/dist/cmd/prompt/index.d.ts.map +1 -0
  130. package/dist/cmd/prompt/llm.d.ts +3 -0
  131. package/dist/cmd/prompt/llm.d.ts.map +1 -0
  132. package/dist/cmd/repl/index.d.ts +3 -0
  133. package/dist/cmd/repl/index.d.ts.map +1 -0
  134. package/dist/cmd/schema/index.d.ts +4 -0
  135. package/dist/cmd/schema/index.d.ts.map +1 -0
  136. package/dist/cmd/schema/show.d.ts +3 -0
  137. package/dist/cmd/schema/show.d.ts.map +1 -0
  138. package/dist/cmd/secret/delete.d.ts.map +1 -1
  139. package/dist/cmd/secret/get.d.ts.map +1 -1
  140. package/dist/cmd/secret/import.d.ts.map +1 -1
  141. package/dist/cmd/secret/index.d.ts.map +1 -1
  142. package/dist/cmd/secret/list.d.ts.map +1 -1
  143. package/dist/cmd/secret/pull.d.ts.map +1 -1
  144. package/dist/cmd/secret/push.d.ts.map +1 -1
  145. package/dist/cmd/secret/set.d.ts.map +1 -1
  146. package/dist/cmd/version/index.d.ts.map +1 -1
  147. package/dist/config.d.ts +1 -1
  148. package/dist/config.d.ts.map +1 -1
  149. package/dist/errors.d.ts +83 -0
  150. package/dist/errors.d.ts.map +1 -0
  151. package/dist/explain.d.ts +47 -0
  152. package/dist/explain.d.ts.map +1 -0
  153. package/dist/index.d.ts +6 -0
  154. package/dist/index.d.ts.map +1 -1
  155. package/dist/json.d.ts +3 -0
  156. package/dist/json.d.ts.map +1 -0
  157. package/dist/output.d.ts +136 -0
  158. package/dist/output.d.ts.map +1 -0
  159. package/dist/repl.d.ts +120 -0
  160. package/dist/repl.d.ts.map +1 -0
  161. package/dist/schema-generator.d.ts +67 -0
  162. package/dist/schema-generator.d.ts.map +1 -0
  163. package/dist/tui.d.ts +35 -1
  164. package/dist/tui.d.ts.map +1 -1
  165. package/dist/types.d.ts +77 -6
  166. package/dist/types.d.ts.map +1 -1
  167. package/dist/utils/format.d.ts +9 -0
  168. package/dist/utils/format.d.ts.map +1 -0
  169. package/package.json +12 -4
  170. package/src/banner.ts +7 -7
  171. package/src/cli-logger.ts +80 -0
  172. package/src/cli.ts +192 -58
  173. package/src/cmd/agents/index.ts +147 -0
  174. package/src/cmd/auth/index.ts +1 -0
  175. package/src/cmd/auth/login.ts +7 -2
  176. package/src/cmd/auth/logout.ts +4 -0
  177. package/src/cmd/auth/signup.ts +7 -2
  178. package/src/cmd/auth/ssh/add.ts +20 -3
  179. package/src/cmd/auth/ssh/delete.ts +57 -4
  180. package/src/cmd/auth/ssh/index.ts +4 -3
  181. package/src/cmd/auth/ssh/list.ts +38 -27
  182. package/src/cmd/auth/whoami.ts +32 -21
  183. package/src/cmd/bundle/ast.test.ts +2 -2
  184. package/src/cmd/bundle/ast.ts +112 -22
  185. package/src/cmd/bundle/index.ts +20 -0
  186. package/src/cmd/bundle/plugin.ts +60 -14
  187. package/src/cmd/capabilities/index.ts +12 -0
  188. package/src/cmd/capabilities/show.ts +256 -0
  189. package/src/cmd/cloud/deploy.ts +54 -0
  190. package/src/cmd/cloud/deployment/index.ts +1 -0
  191. package/src/cmd/cloud/deployment/list.ts +66 -25
  192. package/src/cmd/cloud/deployment/remove.ts +26 -2
  193. package/src/cmd/cloud/deployment/rollback.ts +35 -4
  194. package/src/cmd/cloud/deployment/show.ts +37 -2
  195. package/src/cmd/cloud/deployment/undeploy.ts +12 -1
  196. package/src/cmd/cloud/deployment/utils.ts +5 -2
  197. package/src/cmd/cloud/domain.ts +3 -2
  198. package/src/cmd/cloud/index.ts +10 -1
  199. package/src/cmd/cloud/resource/add.ts +19 -0
  200. package/src/cmd/cloud/resource/delete.ts +24 -3
  201. package/src/cmd/cloud/resource/index.ts +4 -3
  202. package/src/cmd/cloud/resource/list.ts +36 -10
  203. package/src/cmd/cloud/scp/download.ts +27 -1
  204. package/src/cmd/cloud/scp/index.ts +4 -3
  205. package/src/cmd/cloud/scp/upload.ts +27 -1
  206. package/src/cmd/cloud/session/get.ts +164 -0
  207. package/src/cmd/cloud/session/index.ts +11 -0
  208. package/src/cmd/cloud/session/list.ts +145 -0
  209. package/src/cmd/cloud/session/logs.ts +68 -0
  210. package/src/cmd/cloud/ssh.ts +12 -0
  211. package/src/cmd/dev/agents.ts +122 -0
  212. package/src/cmd/dev/index.ts +106 -8
  213. package/src/cmd/dev/sync.ts +414 -0
  214. package/src/cmd/dev/templates.ts +1 -1
  215. package/src/cmd/env/delete.ts +17 -0
  216. package/src/cmd/env/get.ts +17 -1
  217. package/src/cmd/env/import.ts +47 -3
  218. package/src/cmd/env/index.ts +1 -0
  219. package/src/cmd/env/list.ts +13 -1
  220. package/src/cmd/env/pull.ts +20 -0
  221. package/src/cmd/env/push.ts +33 -1
  222. package/src/cmd/env/set.ts +25 -1
  223. package/src/cmd/index.ts +9 -2
  224. package/src/cmd/kv/create-namespace.ts +45 -0
  225. package/src/cmd/kv/delete-namespace.ts +73 -0
  226. package/src/cmd/kv/delete.ts +51 -0
  227. package/src/cmd/kv/get.ts +65 -0
  228. package/src/cmd/kv/index.ts +31 -0
  229. package/src/cmd/kv/keys.ts +57 -0
  230. package/src/cmd/kv/list-namespaces.ts +43 -0
  231. package/src/cmd/kv/repl.ts +284 -0
  232. package/src/cmd/kv/search.ts +80 -0
  233. package/src/cmd/kv/set.ts +63 -0
  234. package/src/cmd/kv/stats.ts +96 -0
  235. package/src/cmd/kv/util.ts +32 -0
  236. package/src/cmd/objectstore/delete-bucket.ts +72 -0
  237. package/src/cmd/objectstore/delete.ts +59 -0
  238. package/src/cmd/objectstore/get.ts +64 -0
  239. package/src/cmd/objectstore/index.ts +27 -0
  240. package/src/cmd/objectstore/list-buckets.ts +45 -0
  241. package/src/cmd/objectstore/list-keys.ts +60 -0
  242. package/src/cmd/objectstore/put.ts +62 -0
  243. package/src/cmd/objectstore/repl.ts +235 -0
  244. package/src/cmd/objectstore/url.ts +59 -0
  245. package/src/cmd/objectstore/util.ts +28 -0
  246. package/src/cmd/profile/create.ts +28 -2
  247. package/src/cmd/profile/delete.ts +17 -2
  248. package/src/cmd/profile/index.ts +1 -0
  249. package/src/cmd/profile/list.ts +7 -3
  250. package/src/cmd/profile/show.ts +20 -5
  251. package/src/cmd/profile/use.ts +8 -0
  252. package/src/cmd/project/create.ts +31 -0
  253. package/src/cmd/project/delete.ts +24 -2
  254. package/src/cmd/project/index.ts +1 -0
  255. package/src/cmd/project/list.ts +24 -10
  256. package/src/cmd/project/show.ts +28 -9
  257. package/src/cmd/project/template-flow.ts +10 -6
  258. package/src/cmd/prompt/index.ts +12 -0
  259. package/src/cmd/prompt/llm.ts +368 -0
  260. package/src/cmd/repl/index.ts +477 -0
  261. package/src/cmd/schema/index.ts +12 -0
  262. package/src/cmd/schema/show.ts +27 -0
  263. package/src/cmd/secret/delete.ts +17 -0
  264. package/src/cmd/secret/get.ts +20 -1
  265. package/src/cmd/secret/import.ts +45 -2
  266. package/src/cmd/secret/index.ts +1 -0
  267. package/src/cmd/secret/list.ts +10 -1
  268. package/src/cmd/secret/pull.ts +20 -0
  269. package/src/cmd/secret/push.ts +33 -1
  270. package/src/cmd/secret/set.ts +20 -0
  271. package/src/cmd/version/index.ts +15 -2
  272. package/src/config.ts +17 -4
  273. package/src/errors.ts +222 -0
  274. package/src/explain.ts +126 -0
  275. package/src/index.ts +51 -0
  276. package/src/json.ts +28 -0
  277. package/src/output.ts +307 -0
  278. package/src/repl.ts +1507 -0
  279. package/src/schema-generator.ts +389 -0
  280. package/src/tui.ts +178 -13
  281. package/src/types.ts +75 -22
  282. package/src/utils/format.ts +17 -0
@@ -12,13 +12,22 @@ import {
12
12
  saveProfile,
13
13
  } from '../../config';
14
14
  import * as tui from '../../tui';
15
+ import { getCommand } from '../../command-prefix';
16
+ import { ErrorCode } from '../../errors';
15
17
 
16
18
  const PROFILE_NAME_REGEX = /^[\w_-]{3,}$/;
17
19
 
18
20
  export const createCommand = createSubcommand({
19
21
  name: 'create',
20
22
  description: 'Create a new configuration profile',
23
+ tags: ['mutating', 'creates-resource', 'fast'],
21
24
  aliases: ['new'],
25
+ idempotent: false,
26
+ examples: [
27
+ getCommand('profile create production'),
28
+ getCommand('profile create staging --switch'),
29
+ getCommand('profile create development'),
30
+ ],
22
31
  schema: {
23
32
  args: z
24
33
  .object({
@@ -32,6 +41,11 @@ export const createCommand = createSubcommand({
32
41
  options: z.object({
33
42
  switch: z.boolean().optional().describe('switch to this profile (if more than one)'),
34
43
  }),
44
+ response: z.object({
45
+ success: z.boolean().describe('Whether creation succeeded'),
46
+ name: z.string().describe('Profile name'),
47
+ path: z.string().describe('Profile file path'),
48
+ }),
35
49
  },
36
50
 
37
51
  async handler(ctx) {
@@ -42,7 +56,10 @@ export const createCommand = createSubcommand({
42
56
  const existing = profiles.find((p) => p.name === name);
43
57
 
44
58
  if (existing) {
45
- return logger.fatal(`Profile "${name}" already exists at ${existing.filename}`);
59
+ return logger.fatal(
60
+ `Profile "${name}" already exists at ${existing.filename}`,
61
+ ErrorCode.RESOURCE_ALREADY_EXISTS
62
+ );
46
63
  }
47
64
 
48
65
  await ensureConfigDir();
@@ -77,10 +94,19 @@ export const createCommand = createSubcommand({
77
94
  }
78
95
 
79
96
  tui.success(`Created profile "${name}" at ${filename}`);
97
+
98
+ return {
99
+ success: true,
100
+ name,
101
+ path: filename,
102
+ };
80
103
  } catch (error) {
81
104
  const message = error instanceof Error ? error.message : String(error);
82
105
  const stack = error instanceof Error ? error.stack : undefined;
83
- logger.fatal(`Failed to create profile: ${message}${stack ? `\n${stack}` : ''}`);
106
+ logger.fatal(
107
+ `Failed to create profile: ${message}${stack ? `\n${stack}` : ''}`,
108
+ ErrorCode.INTERNAL_ERROR
109
+ );
84
110
  }
85
111
  },
86
112
  });
@@ -3,11 +3,20 @@ import { z } from 'zod';
3
3
  import { fetchProfiles } from '../../config';
4
4
  import { unlink } from 'node:fs/promises';
5
5
  import * as tui from '../../tui';
6
+ import { getCommand } from '../../command-prefix';
7
+ import { ErrorCode } from '../../errors';
6
8
 
7
9
  export const deleteCommand = createSubcommand({
8
10
  name: 'delete',
9
11
  description: 'Delete a configuration profile',
12
+ tags: ['destructive', 'deletes-resource', 'fast'],
13
+ idempotent: false,
10
14
  aliases: ['remove', 'rm', 'del'],
15
+ examples: [
16
+ getCommand('profile delete staging'),
17
+ getCommand('profile delete old-dev --confirm'),
18
+ getCommand('profile delete'),
19
+ ],
11
20
  schema: {
12
21
  args: z.object({
13
22
  name: z.string().optional().describe('The name of the profile to delete'),
@@ -15,6 +24,10 @@ export const deleteCommand = createSubcommand({
15
24
  options: z.object({
16
25
  confirm: z.boolean().optional().describe('Skip confirmation prompt'),
17
26
  }),
27
+ response: z.object({
28
+ success: z.boolean().describe('Whether deletion succeeded'),
29
+ name: z.string().describe('Deleted profile name'),
30
+ }),
18
31
  },
19
32
 
20
33
  async handler(ctx) {
@@ -30,7 +43,7 @@ export const deleteCommand = createSubcommand({
30
43
  const profile = profiles.find((p) => p.name === name);
31
44
 
32
45
  if (!profile) {
33
- return logger.fatal(`Profile "${name}" not found`);
46
+ return logger.fatal(`Profile "${name}" not found`, ErrorCode.RESOURCE_NOT_FOUND);
34
47
  }
35
48
 
36
49
  // Ask for confirmation unless --confirm flag is passed
@@ -38,7 +51,7 @@ export const deleteCommand = createSubcommand({
38
51
  const confirmed = await tui.confirm(`Delete profile "${name}"?`, false);
39
52
  if (!confirmed) {
40
53
  logger.info('Cancelled');
41
- return;
54
+ return { success: false, name };
42
55
  }
43
56
  }
44
57
 
@@ -50,6 +63,8 @@ export const deleteCommand = createSubcommand({
50
63
  'The active profile was deleted. Use "profile use <name>" to select a new default.'
51
64
  );
52
65
  }
66
+
67
+ return { success: true, name };
53
68
  } catch (error) {
54
69
  logger.fatal(`Failed to delete profile: ${error}`);
55
70
  }
@@ -8,5 +8,6 @@ import { deleteCommand } from './delete';
8
8
  export const command = createCommand({
9
9
  name: 'profile',
10
10
  description: 'Manage configuration profiles',
11
+ tags: ['read-only', 'fast'],
11
12
  subcommands: [createProfileCmd, useCommand, listCommand, showCommand, deleteCommand],
12
13
  });
@@ -1,12 +1,16 @@
1
- import type { SubcommandDefinition } from '../../types';
1
+ import { createSubcommand } from '../../types';
2
2
  import { fetchProfiles } from '../../config';
3
3
  import { basename, dirname } from 'node:path';
4
4
  import * as tui from '../../tui';
5
+ import { getCommand } from '../../command-prefix';
5
6
 
6
- export const listCommand: SubcommandDefinition = {
7
+ export const listCommand = createSubcommand({
7
8
  name: 'list',
8
9
  description: 'List all available profiles',
10
+ tags: ['read-only', 'fast'],
11
+ idempotent: true,
9
12
  aliases: ['ls'],
13
+ examples: [getCommand('profile list'), getCommand('profile ls')],
10
14
 
11
15
  async handler() {
12
16
  const profiles = await fetchProfiles();
@@ -24,4 +28,4 @@ export const listCommand: SubcommandDefinition = {
24
28
  console.log(`${marker} ${name} ${tui.muted(path)}`);
25
29
  }
26
30
  },
27
- };
31
+ });
@@ -1,13 +1,23 @@
1
- import { createSubcommand } from '../../types';
1
+ import { createSubcommand, ConfigSchema } from '../../types';
2
2
  import { z } from 'zod';
3
3
  import { fetchProfiles, loadConfig } from '../../config';
4
4
  import { readFile } from 'node:fs/promises';
5
5
  import * as tui from '../../tui';
6
+ import { getCommand } from '../../command-prefix';
7
+ import { ErrorCode } from '../../errors';
8
+
9
+ const ProfileShowResponseSchema = ConfigSchema;
6
10
 
7
11
  export const showCommand = createSubcommand({
8
12
  name: 'show',
9
13
  description: 'Show the configuration of a profile',
14
+ tags: ['read-only', 'fast'],
10
15
  aliases: ['current'],
16
+ examples: [
17
+ getCommand('profile show'),
18
+ getCommand('profile show production'),
19
+ getCommand('profile show staging --json'),
20
+ ],
11
21
  schema: {
12
22
  options: z.object({
13
23
  json: z.boolean().optional().describe('Show the JSON config'),
@@ -17,7 +27,9 @@ export const showCommand = createSubcommand({
17
27
  name: z.string().optional().describe('Profile name to show (optional)'),
18
28
  })
19
29
  .describe('Profile show arguments'),
30
+ response: ProfileShowResponseSchema,
20
31
  },
32
+ idempotent: true,
21
33
 
22
34
  async handler(ctx) {
23
35
  const { logger, args, opts } = ctx;
@@ -35,7 +47,7 @@ export const showCommand = createSubcommand({
35
47
  const profile = profiles.find((p) => p.name === name);
36
48
 
37
49
  if (!profile) {
38
- return logger.fatal(`Profile "${name}" not found`);
50
+ return logger.fatal(`Profile "${name}" not found`, ErrorCode.RESOURCE_NOT_FOUND);
39
51
  }
40
52
 
41
53
  const profilePath = profile.filename;
@@ -43,14 +55,17 @@ export const showCommand = createSubcommand({
43
55
 
44
56
  tui.info(`Profile: ${profilePath}`);
45
57
 
58
+ const content = await loadConfig(current ? undefined : profilePath);
59
+
46
60
  if (opts?.json) {
47
- const content = await loadConfig(current ? undefined : profilePath);
48
61
  console.log(JSON.stringify(content, null, 2));
49
62
  } else {
50
63
  tui.newline();
51
- const content = await readFile(profilePath, 'utf-8');
52
- console.log(content);
64
+ const textContent = await readFile(profilePath, 'utf-8');
65
+ console.log(textContent);
53
66
  }
67
+
68
+ return content;
54
69
  } catch (error) {
55
70
  if (error instanceof Error) {
56
71
  logger.fatal(`Failed to show profile: ${error.message}`);
@@ -2,11 +2,19 @@ import { createSubcommand } from '../../types';
2
2
  import { z } from 'zod';
3
3
  import { fetchProfiles, saveProfile } from '../../config';
4
4
  import * as tui from '../../tui';
5
+ import { getCommand } from '../../command-prefix';
5
6
 
6
7
  export const useCommand = createSubcommand({
7
8
  name: 'use',
8
9
  description: 'Switch to a different configuration profile',
10
+ tags: ['mutating', 'updates-resource', 'fast'],
9
11
  aliases: ['switch'],
12
+ idempotent: true,
13
+ examples: [
14
+ getCommand('profile use production'),
15
+ getCommand('profile switch staging'),
16
+ getCommand('profile use'),
17
+ ],
10
18
  schema: {
11
19
  args: z.object({
12
20
  name: z.string().optional().describe('The name of the profile to use'),
@@ -1,15 +1,35 @@
1
1
  import { createSubcommand } from '../../types';
2
2
  import { z } from 'zod';
3
3
  import { runCreateFlow } from './template-flow';
4
+ import { getCommand } from '../../command-prefix';
5
+
6
+ const ProjectCreateResponseSchema = z.object({
7
+ success: z.boolean().describe('Whether the operation succeeded'),
8
+ name: z.string().describe('Project name'),
9
+ path: z.string().describe('Project directory path'),
10
+ projectId: z.string().optional().describe('Project ID if registered'),
11
+ template: z.string().describe('Template used'),
12
+ installed: z.boolean().describe('Whether dependencies were installed'),
13
+ built: z.boolean().describe('Whether the project was built'),
14
+ });
4
15
 
5
16
  export const createProjectSubcommand = createSubcommand({
6
17
  name: 'create',
7
18
  description: 'Create a new project',
19
+ tags: ['mutating', 'creates-resource', 'slow', 'api-intensive', 'requires-auth'],
8
20
  aliases: ['new'],
9
21
  banner: true,
10
22
  toplevel: true,
23
+ idempotent: false,
11
24
  optional: { auth: true, org: true, region: true },
12
25
  requires: { apiClient: true },
26
+ examples: [
27
+ getCommand('project create'),
28
+ getCommand('project create --name my-ai-agent'),
29
+ getCommand('project create --name customer-service-bot --dir ~/projects/agent'),
30
+ getCommand('project create --template basic --no-install'),
31
+ getCommand('project new --no-register'),
32
+ ],
13
33
  schema: {
14
34
  options: z.object({
15
35
  name: z.string().optional().describe('Project name'),
@@ -40,6 +60,7 @@ export const createProjectSubcommand = createSubcommand({
40
60
  .optional()
41
61
  .describe('Register the project, if authenticated (use --no-register to skip)'),
42
62
  }),
63
+ response: ProjectCreateResponseSchema,
43
64
  },
44
65
 
45
66
  async handler(ctx) {
@@ -61,5 +82,15 @@ export const createProjectSubcommand = createSubcommand({
61
82
  orgId,
62
83
  region,
63
84
  });
85
+
86
+ // Return best-effort response (runCreateFlow doesn't return values)
87
+ return {
88
+ success: true,
89
+ name: opts.name || 'project',
90
+ path: opts.dir || process.cwd(),
91
+ template: opts.template || 'default',
92
+ installed: opts.install !== false,
93
+ built: opts.build !== false,
94
+ };
64
95
  },
65
96
  });
@@ -3,12 +3,23 @@ import { createSubcommand } from '../../types';
3
3
  import * as tui from '../../tui';
4
4
  import { projectDelete, projectList } from '@agentuity/server';
5
5
  import enquirer from 'enquirer';
6
+ import { getCommand } from '../../command-prefix';
6
7
 
7
8
  export const deleteSubcommand = createSubcommand({
8
9
  name: 'delete',
9
10
  description: 'Delete a project',
11
+ tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth'],
10
12
  aliases: ['rm', 'del'],
11
13
  requires: { auth: true, apiClient: true },
14
+ idempotent: false,
15
+ examples: [
16
+ getCommand('project delete'),
17
+ getCommand('project delete proj_abc123def456'),
18
+ getCommand('project delete proj_abc123def456 --confirm'),
19
+ getCommand('project rm proj_abc123def456'),
20
+ getCommand('--explain project delete proj_abc123def456'),
21
+ getCommand('--dry-run project delete proj_abc123def456'),
22
+ ],
12
23
  schema: {
13
24
  args: z.object({
14
25
  id: z.string().optional().describe('the project id'),
@@ -16,6 +27,11 @@ export const deleteSubcommand = createSubcommand({
16
27
  options: z.object({
17
28
  confirm: z.boolean().optional().describe('Skip confirmation prompts'),
18
29
  }),
30
+ response: z.object({
31
+ success: z.boolean().describe('Whether the deletion succeeded'),
32
+ projectIds: z.array(z.string()).describe('Deleted project IDs'),
33
+ count: z.number().describe('Number of projects deleted'),
34
+ }),
19
35
  },
20
36
 
21
37
  async handler(ctx) {
@@ -67,7 +83,7 @@ export const deleteSubcommand = createSubcommand({
67
83
 
68
84
  if (projectIds.length === 0) {
69
85
  tui.info('No projects selected for deletion');
70
- return;
86
+ return { success: false, projectIds: [], count: 0 };
71
87
  }
72
88
 
73
89
  const skipConfirm = opts?.confirm === true;
@@ -90,7 +106,7 @@ export const deleteSubcommand = createSubcommand({
90
106
 
91
107
  if (!confirm.confirm) {
92
108
  tui.info('Deletion cancelled');
93
- return;
109
+ return { success: false, projectIds: [], count: 0 };
94
110
  }
95
111
  }
96
112
 
@@ -107,5 +123,11 @@ export const deleteSubcommand = createSubcommand({
107
123
  } else {
108
124
  tui.error('Failed to delete projects');
109
125
  }
126
+
127
+ return {
128
+ success: deleted.length > 0,
129
+ projectIds: deleted,
130
+ count: deleted.length,
131
+ };
110
132
  },
111
133
  });
@@ -7,5 +7,6 @@ import { showSubcommand } from './show';
7
7
  export const command = createCommand({
8
8
  name: 'project',
9
9
  description: 'Manage Agentuity projects',
10
+ tags: ['fast', 'requires-auth'],
10
11
  subcommands: [createProjectSubcommand, listSubcommand, deleteSubcommand, showSubcommand],
11
12
  });
@@ -1,24 +1,36 @@
1
- import { z } from 'zod';
2
1
  import { createSubcommand } from '../../types';
3
2
  import * as tui from '../../tui';
4
3
  import { projectList } from '@agentuity/server';
4
+ import { getCommand } from '../../command-prefix';
5
+ import { z } from 'zod';
6
+
7
+ const ProjectListResponseSchema = z.array(
8
+ z.object({
9
+ id: z.string().describe('Project ID'),
10
+ name: z.string().describe('Project name'),
11
+ orgId: z.string().describe('Organization ID'),
12
+ orgName: z.string().describe('Organization name'),
13
+ })
14
+ );
5
15
 
6
16
  export const listSubcommand = createSubcommand({
7
17
  name: 'list',
8
18
  description: 'List all projects',
19
+ tags: ['read-only', 'slow', 'requires-auth'],
9
20
  aliases: ['ls'],
10
21
  requires: { auth: true, apiClient: true },
22
+ idempotent: true,
11
23
  schema: {
12
- options: z.object({
13
- format: z
14
- .enum(['json', 'table'])
15
- .optional()
16
- .describe('the output format: json, table (default)'),
17
- }),
24
+ response: ProjectListResponseSchema,
18
25
  },
26
+ examples: [
27
+ getCommand('project list'),
28
+ getCommand('--json project list'),
29
+ getCommand('project ls'),
30
+ ],
19
31
 
20
32
  async handler(ctx) {
21
- const { apiClient, opts } = ctx;
33
+ const { apiClient, options } = ctx;
22
34
 
23
35
  const projects = await tui.spinner({
24
36
  message: 'Fetching projects',
@@ -35,10 +47,12 @@ export const listSubcommand = createSubcommand({
35
47
  });
36
48
  }
37
49
 
38
- if (opts?.format === 'json') {
50
+ if (options.json) {
39
51
  console.log(JSON.stringify(projects, null, 2));
40
52
  } else {
41
- console.table(projects, ['id', 'name', 'orgName']);
53
+ tui.table(projects, ['id', 'name', 'orgName']);
42
54
  }
55
+
56
+ return projects ?? [];
43
57
  },
44
58
  });
@@ -2,26 +2,37 @@ import { z } from 'zod';
2
2
  import { createSubcommand } from '../../types';
3
3
  import * as tui from '../../tui';
4
4
  import { projectGet } from '@agentuity/server';
5
+ import { getCommand } from '../../command-prefix';
6
+
7
+ const ProjectShowResponseSchema = z.object({
8
+ id: z.string().describe('Project ID'),
9
+ orgId: z.string().describe('Organization ID'),
10
+ name: z.string().optional().describe('Project name'),
11
+ secrets: z.record(z.string(), z.string()).optional().describe('Project secrets (masked)'),
12
+ env: z.record(z.string(), z.string()).optional().describe('Environment variables'),
13
+ });
5
14
 
6
15
  export const showSubcommand = createSubcommand({
7
16
  name: 'show',
8
17
  aliases: ['get'],
9
18
  description: 'Show project detail',
19
+ tags: ['read-only', 'fast', 'requires-auth', 'requires-project'],
10
20
  requires: { auth: true, apiClient: true },
21
+ examples: [
22
+ getCommand('project show proj_abc123def456'),
23
+ getCommand('--json project show proj_abc123def456'),
24
+ getCommand('project get proj_abc123def456'),
25
+ ],
11
26
  schema: {
12
27
  args: z.object({
13
28
  id: z.string().describe('the project id'),
14
29
  }),
15
- options: z.object({
16
- format: z
17
- .enum(['json', 'table'])
18
- .optional()
19
- .describe('the output format: json, table (default)'),
20
- }),
30
+ response: ProjectShowResponseSchema,
21
31
  },
32
+ idempotent: true,
22
33
 
23
34
  async handler(ctx) {
24
- const { opts, args, apiClient } = ctx;
35
+ const { args, apiClient, options } = ctx;
25
36
 
26
37
  const project = await tui.spinner('Fetching project', () => {
27
38
  return projectGet(apiClient, { id: args.id, mask: true });
@@ -31,10 +42,18 @@ export const showSubcommand = createSubcommand({
31
42
  tui.fatal('Project not found');
32
43
  }
33
44
 
34
- if (opts?.format === 'json') {
45
+ if (options.json) {
35
46
  console.log(JSON.stringify(project, null, 2));
36
47
  } else {
37
- console.table([project], ['id', 'orgId']);
48
+ tui.table([project], ['id', 'orgId']);
38
49
  }
50
+
51
+ return {
52
+ id: project.id,
53
+ orgId: project.orgId,
54
+ name: undefined,
55
+ secrets: project.secrets,
56
+ env: project.env,
57
+ };
39
58
  },
40
59
  });
@@ -19,7 +19,8 @@ import * as tui from '../../tui';
19
19
  import { playSound } from '../../sound';
20
20
  import { fetchTemplates, type TemplateInfo } from './templates';
21
21
  import { downloadTemplate, setupProject } from './download';
22
- import type { AuthData, Config } from '../../types';
22
+ import { type AuthData, type Config } from '../../types';
23
+ import { ErrorCode } from '../../errors';
23
24
  import type { APIClient } from '../../api';
24
25
  import { createProjectConfig } from '../../config';
25
26
  import {
@@ -78,7 +79,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<void> {
78
79
  });
79
80
 
80
81
  if (templates.length === 0) {
81
- logger.fatal('No templates available');
82
+ logger.fatal('No templates available', ErrorCode.RESOURCE_NOT_FOUND);
82
83
  }
83
84
 
84
85
  // Get project name
@@ -154,13 +155,16 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<void> {
154
155
  // Extra safety: refuse to delete root or home directories
155
156
  const home = homedir();
156
157
  if (dest === '/' || dest === home) {
157
- logger.fatal(`Refusing to delete protected path: ${dest}`);
158
+ logger.fatal(`Refusing to delete protected path: ${dest}`, ErrorCode.VALIDATION_FAILED);
158
159
  return;
159
160
  }
160
161
  rmSync(dest, { recursive: true, force: true });
161
162
  tui.success(`Deleted ${dest}`);
162
163
  } else {
163
- logger.fatal(`Directory ${dest} already exists and is not empty.`, true);
164
+ logger.fatal(
165
+ `Directory ${dest} already exists and is not empty.`,
166
+ ErrorCode.RESOURCE_ALREADY_EXISTS
167
+ );
164
168
  }
165
169
  }
166
170
 
@@ -169,7 +173,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<void> {
169
173
  if (initialTemplate) {
170
174
  const found = templates.find((t) => t.id === initialTemplate);
171
175
  if (!found) {
172
- logger.fatal(`Template "${initialTemplate}" not found`);
176
+ logger.fatal(`Template "${initialTemplate}" not found`, ErrorCode.RESOURCE_NOT_FOUND);
173
177
  return;
174
178
  }
175
179
  selectedTemplate = found;
@@ -187,7 +191,7 @@ export async function runCreateFlow(options: CreateFlowOptions): Promise<void> {
187
191
  });
188
192
  const found = templates.find((t) => t.id === response.template);
189
193
  if (!found) {
190
- logger.fatal('Template selection failed');
194
+ logger.fatal('Template selection failed', ErrorCode.USER_CANCELLED);
191
195
  return;
192
196
  }
193
197
  selectedTemplate = found;
@@ -0,0 +1,12 @@
1
+ import type { CommandDefinition } from '../../types';
2
+ import { createCommand } from '../../types';
3
+ import { llmSubcommand } from './llm';
4
+
5
+ export const promptCommand: CommandDefinition = createCommand({
6
+ name: 'prompt',
7
+ description: 'Generate prompts for LLMs and agents',
8
+ tags: ['read-only', 'fast'],
9
+ subcommands: [llmSubcommand],
10
+ });
11
+
12
+ export default promptCommand;