@agentuity/cli 0.0.47 → 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 (262) 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 +2 -0
  26. package/dist/cmd/cloud/deployment/index.d.ts.map +1 -0
  27. package/dist/cmd/cloud/deployment/list.d.ts +2 -0
  28. package/dist/cmd/cloud/deployment/list.d.ts.map +1 -0
  29. package/dist/cmd/cloud/deployment/remove.d.ts +2 -0
  30. package/dist/cmd/cloud/deployment/remove.d.ts.map +1 -0
  31. package/dist/cmd/cloud/deployment/rollback.d.ts +2 -0
  32. package/dist/cmd/cloud/deployment/rollback.d.ts.map +1 -0
  33. package/dist/cmd/cloud/deployment/show.d.ts +2 -0
  34. package/dist/cmd/cloud/deployment/show.d.ts.map +1 -0
  35. package/dist/cmd/cloud/deployment/undeploy.d.ts +2 -0
  36. package/dist/cmd/cloud/deployment/undeploy.d.ts.map +1 -0
  37. package/dist/cmd/cloud/deployment/utils.d.ts +7 -0
  38. package/dist/cmd/cloud/deployment/utils.d.ts.map +1 -0
  39. package/dist/cmd/cloud/domain.d.ts.map +1 -1
  40. package/dist/cmd/cloud/index.d.ts.map +1 -1
  41. package/dist/cmd/cloud/resource/add.d.ts.map +1 -1
  42. package/dist/cmd/cloud/resource/delete.d.ts.map +1 -1
  43. package/dist/cmd/cloud/resource/index.d.ts +1 -2
  44. package/dist/cmd/cloud/resource/index.d.ts.map +1 -1
  45. package/dist/cmd/cloud/resource/list.d.ts.map +1 -1
  46. package/dist/cmd/cloud/scp/download.d.ts.map +1 -1
  47. package/dist/cmd/cloud/scp/index.d.ts +1 -2
  48. package/dist/cmd/cloud/scp/index.d.ts.map +1 -1
  49. package/dist/cmd/cloud/scp/upload.d.ts.map +1 -1
  50. package/dist/cmd/cloud/ssh.d.ts.map +1 -1
  51. package/dist/cmd/dev/index.d.ts.map +1 -1
  52. package/dist/cmd/env/delete.d.ts.map +1 -1
  53. package/dist/cmd/env/get.d.ts.map +1 -1
  54. package/dist/cmd/env/import.d.ts.map +1 -1
  55. package/dist/cmd/env/index.d.ts.map +1 -1
  56. package/dist/cmd/env/list.d.ts.map +1 -1
  57. package/dist/cmd/env/pull.d.ts.map +1 -1
  58. package/dist/cmd/env/push.d.ts.map +1 -1
  59. package/dist/cmd/env/set.d.ts.map +1 -1
  60. package/dist/cmd/index.d.ts.map +1 -1
  61. package/dist/cmd/kv/create-namespace.d.ts +3 -0
  62. package/dist/cmd/kv/create-namespace.d.ts.map +1 -0
  63. package/dist/cmd/kv/delete-namespace.d.ts +3 -0
  64. package/dist/cmd/kv/delete-namespace.d.ts.map +1 -0
  65. package/dist/cmd/kv/delete.d.ts +3 -0
  66. package/dist/cmd/kv/delete.d.ts.map +1 -0
  67. package/dist/cmd/kv/get.d.ts +3 -0
  68. package/dist/cmd/kv/get.d.ts.map +1 -0
  69. package/dist/cmd/kv/index.d.ts +2 -0
  70. package/dist/cmd/kv/index.d.ts.map +1 -0
  71. package/dist/cmd/kv/keys.d.ts +3 -0
  72. package/dist/cmd/kv/keys.d.ts.map +1 -0
  73. package/dist/cmd/kv/list-namespaces.d.ts +3 -0
  74. package/dist/cmd/kv/list-namespaces.d.ts.map +1 -0
  75. package/dist/cmd/kv/repl.d.ts +3 -0
  76. package/dist/cmd/kv/repl.d.ts.map +1 -0
  77. package/dist/cmd/kv/search.d.ts +3 -0
  78. package/dist/cmd/kv/search.d.ts.map +1 -0
  79. package/dist/cmd/kv/set.d.ts +3 -0
  80. package/dist/cmd/kv/set.d.ts.map +1 -0
  81. package/dist/cmd/kv/stats.d.ts +3 -0
  82. package/dist/cmd/kv/stats.d.ts.map +1 -0
  83. package/dist/cmd/kv/util.d.ts +8 -0
  84. package/dist/cmd/kv/util.d.ts.map +1 -0
  85. package/dist/cmd/objectstore/delete-bucket.d.ts +3 -0
  86. package/dist/cmd/objectstore/delete-bucket.d.ts.map +1 -0
  87. package/dist/cmd/objectstore/delete.d.ts +3 -0
  88. package/dist/cmd/objectstore/delete.d.ts.map +1 -0
  89. package/dist/cmd/objectstore/get.d.ts +3 -0
  90. package/dist/cmd/objectstore/get.d.ts.map +1 -0
  91. package/dist/cmd/objectstore/index.d.ts +2 -0
  92. package/dist/cmd/objectstore/index.d.ts.map +1 -0
  93. package/dist/cmd/objectstore/list-buckets.d.ts +3 -0
  94. package/dist/cmd/objectstore/list-buckets.d.ts.map +1 -0
  95. package/dist/cmd/objectstore/list-keys.d.ts +3 -0
  96. package/dist/cmd/objectstore/list-keys.d.ts.map +1 -0
  97. package/dist/cmd/objectstore/put.d.ts +3 -0
  98. package/dist/cmd/objectstore/put.d.ts.map +1 -0
  99. package/dist/cmd/objectstore/repl.d.ts +3 -0
  100. package/dist/cmd/objectstore/repl.d.ts.map +1 -0
  101. package/dist/cmd/objectstore/url.d.ts +3 -0
  102. package/dist/cmd/objectstore/url.d.ts.map +1 -0
  103. package/dist/cmd/objectstore/util.d.ts +8 -0
  104. package/dist/cmd/objectstore/util.d.ts.map +1 -0
  105. package/dist/cmd/profile/create.d.ts.map +1 -1
  106. package/dist/cmd/profile/delete.d.ts.map +1 -1
  107. package/dist/cmd/profile/index.d.ts.map +1 -1
  108. package/dist/cmd/profile/list.d.ts +1 -2
  109. package/dist/cmd/profile/list.d.ts.map +1 -1
  110. package/dist/cmd/profile/show.d.ts.map +1 -1
  111. package/dist/cmd/profile/use.d.ts.map +1 -1
  112. package/dist/cmd/project/create.d.ts.map +1 -1
  113. package/dist/cmd/project/delete.d.ts.map +1 -1
  114. package/dist/cmd/project/index.d.ts.map +1 -1
  115. package/dist/cmd/project/list.d.ts.map +1 -1
  116. package/dist/cmd/project/show.d.ts.map +1 -1
  117. package/dist/cmd/project/template-flow.d.ts +1 -1
  118. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  119. package/dist/cmd/prompt/index.d.ts +4 -0
  120. package/dist/cmd/prompt/index.d.ts.map +1 -0
  121. package/dist/cmd/prompt/llm.d.ts +3 -0
  122. package/dist/cmd/prompt/llm.d.ts.map +1 -0
  123. package/dist/cmd/repl/index.d.ts +3 -0
  124. package/dist/cmd/repl/index.d.ts.map +1 -0
  125. package/dist/cmd/schema/index.d.ts +4 -0
  126. package/dist/cmd/schema/index.d.ts.map +1 -0
  127. package/dist/cmd/schema/show.d.ts +3 -0
  128. package/dist/cmd/schema/show.d.ts.map +1 -0
  129. package/dist/cmd/secret/delete.d.ts.map +1 -1
  130. package/dist/cmd/secret/get.d.ts.map +1 -1
  131. package/dist/cmd/secret/import.d.ts.map +1 -1
  132. package/dist/cmd/secret/index.d.ts.map +1 -1
  133. package/dist/cmd/secret/list.d.ts.map +1 -1
  134. package/dist/cmd/secret/pull.d.ts.map +1 -1
  135. package/dist/cmd/secret/push.d.ts.map +1 -1
  136. package/dist/cmd/secret/set.d.ts.map +1 -1
  137. package/dist/cmd/version/index.d.ts.map +1 -1
  138. package/dist/config.d.ts +1 -1
  139. package/dist/config.d.ts.map +1 -1
  140. package/dist/errors.d.ts +83 -0
  141. package/dist/errors.d.ts.map +1 -0
  142. package/dist/explain.d.ts +47 -0
  143. package/dist/explain.d.ts.map +1 -0
  144. package/dist/index.d.ts +6 -0
  145. package/dist/index.d.ts.map +1 -1
  146. package/dist/json.d.ts +3 -0
  147. package/dist/json.d.ts.map +1 -0
  148. package/dist/output.d.ts +136 -0
  149. package/dist/output.d.ts.map +1 -0
  150. package/dist/repl.d.ts +124 -0
  151. package/dist/repl.d.ts.map +1 -0
  152. package/dist/schema-generator.d.ts +67 -0
  153. package/dist/schema-generator.d.ts.map +1 -0
  154. package/dist/tui.d.ts +20 -1
  155. package/dist/tui.d.ts.map +1 -1
  156. package/dist/types.d.ts +65 -6
  157. package/dist/types.d.ts.map +1 -1
  158. package/package.json +10 -4
  159. package/src/banner.ts +7 -7
  160. package/src/cli-logger.ts +80 -0
  161. package/src/cli.ts +186 -54
  162. package/src/cmd/auth/index.ts +1 -0
  163. package/src/cmd/auth/login.ts +7 -2
  164. package/src/cmd/auth/logout.ts +4 -0
  165. package/src/cmd/auth/signup.ts +7 -2
  166. package/src/cmd/auth/ssh/add.ts +20 -3
  167. package/src/cmd/auth/ssh/delete.ts +57 -4
  168. package/src/cmd/auth/ssh/index.ts +4 -3
  169. package/src/cmd/auth/ssh/list.ts +44 -32
  170. package/src/cmd/auth/whoami.ts +32 -21
  171. package/src/cmd/bundle/ast.ts +27 -5
  172. package/src/cmd/bundle/index.ts +20 -0
  173. package/src/cmd/bundle/plugin.ts +36 -12
  174. package/src/cmd/capabilities/index.ts +12 -0
  175. package/src/cmd/capabilities/show.ts +256 -0
  176. package/src/cmd/cloud/deploy.ts +60 -0
  177. package/src/cmd/cloud/deployment/index.ts +20 -0
  178. package/src/cmd/cloud/deployment/list.ts +105 -0
  179. package/src/cmd/cloud/deployment/remove.ts +65 -0
  180. package/src/cmd/cloud/deployment/rollback.ts +87 -0
  181. package/src/cmd/cloud/deployment/show.ts +107 -0
  182. package/src/cmd/cloud/deployment/undeploy.ts +48 -0
  183. package/src/cmd/cloud/deployment/utils.ts +14 -0
  184. package/src/cmd/cloud/domain.ts +3 -2
  185. package/src/cmd/cloud/index.ts +9 -1
  186. package/src/cmd/cloud/resource/add.ts +19 -0
  187. package/src/cmd/cloud/resource/delete.ts +24 -3
  188. package/src/cmd/cloud/resource/index.ts +4 -3
  189. package/src/cmd/cloud/resource/list.ts +36 -10
  190. package/src/cmd/cloud/scp/download.ts +27 -1
  191. package/src/cmd/cloud/scp/index.ts +4 -3
  192. package/src/cmd/cloud/scp/upload.ts +27 -1
  193. package/src/cmd/cloud/ssh.ts +12 -0
  194. package/src/cmd/dev/index.ts +11 -7
  195. package/src/cmd/dev/templates.ts +1 -1
  196. package/src/cmd/env/delete.ts +17 -0
  197. package/src/cmd/env/get.ts +17 -1
  198. package/src/cmd/env/import.ts +47 -3
  199. package/src/cmd/env/index.ts +1 -0
  200. package/src/cmd/env/list.ts +13 -1
  201. package/src/cmd/env/pull.ts +20 -0
  202. package/src/cmd/env/push.ts +33 -1
  203. package/src/cmd/env/set.ts +25 -1
  204. package/src/cmd/index.ts +9 -2
  205. package/src/cmd/kv/create-namespace.ts +45 -0
  206. package/src/cmd/kv/delete-namespace.ts +73 -0
  207. package/src/cmd/kv/delete.ts +51 -0
  208. package/src/cmd/kv/get.ts +65 -0
  209. package/src/cmd/kv/index.ts +31 -0
  210. package/src/cmd/kv/keys.ts +57 -0
  211. package/src/cmd/kv/list-namespaces.ts +43 -0
  212. package/src/cmd/kv/repl.ts +284 -0
  213. package/src/cmd/kv/search.ts +80 -0
  214. package/src/cmd/kv/set.ts +63 -0
  215. package/src/cmd/kv/stats.ts +96 -0
  216. package/src/cmd/kv/util.ts +32 -0
  217. package/src/cmd/objectstore/delete-bucket.ts +72 -0
  218. package/src/cmd/objectstore/delete.ts +59 -0
  219. package/src/cmd/objectstore/get.ts +64 -0
  220. package/src/cmd/objectstore/index.ts +27 -0
  221. package/src/cmd/objectstore/list-buckets.ts +45 -0
  222. package/src/cmd/objectstore/list-keys.ts +60 -0
  223. package/src/cmd/objectstore/put.ts +62 -0
  224. package/src/cmd/objectstore/repl.ts +235 -0
  225. package/src/cmd/objectstore/url.ts +59 -0
  226. package/src/cmd/objectstore/util.ts +28 -0
  227. package/src/cmd/profile/create.ts +61 -6
  228. package/src/cmd/profile/delete.ts +25 -5
  229. package/src/cmd/profile/index.ts +1 -0
  230. package/src/cmd/profile/list.ts +7 -3
  231. package/src/cmd/profile/show.ts +33 -19
  232. package/src/cmd/profile/use.ts +17 -4
  233. package/src/cmd/project/create.ts +31 -0
  234. package/src/cmd/project/delete.ts +24 -2
  235. package/src/cmd/project/index.ts +1 -0
  236. package/src/cmd/project/list.ts +23 -9
  237. package/src/cmd/project/show.ts +27 -8
  238. package/src/cmd/project/template-flow.ts +10 -6
  239. package/src/cmd/prompt/index.ts +12 -0
  240. package/src/cmd/prompt/llm.ts +368 -0
  241. package/src/cmd/repl/index.ts +477 -0
  242. package/src/cmd/schema/index.ts +12 -0
  243. package/src/cmd/schema/show.ts +27 -0
  244. package/src/cmd/secret/delete.ts +17 -0
  245. package/src/cmd/secret/get.ts +20 -1
  246. package/src/cmd/secret/import.ts +45 -2
  247. package/src/cmd/secret/index.ts +1 -0
  248. package/src/cmd/secret/list.ts +10 -1
  249. package/src/cmd/secret/pull.ts +20 -0
  250. package/src/cmd/secret/push.ts +33 -1
  251. package/src/cmd/secret/set.ts +20 -0
  252. package/src/cmd/version/index.ts +15 -2
  253. package/src/config.ts +18 -5
  254. package/src/errors.ts +222 -0
  255. package/src/explain.ts +126 -0
  256. package/src/index.ts +51 -0
  257. package/src/json.ts +28 -0
  258. package/src/output.ts +307 -0
  259. package/src/repl.ts +1517 -0
  260. package/src/schema-generator.ts +389 -0
  261. package/src/tui.ts +136 -13
  262. package/src/types.ts +62 -12
@@ -3,12 +3,18 @@ import { createSubcommand } from '../../types';
3
3
  import * as tui from '../../tui';
4
4
  import { projectGet } from '@agentuity/server';
5
5
  import { maskSecret } from '../../env-util';
6
+ import { getCommand } from '../../command-prefix';
7
+
8
+ const SecretListResponseSchema = z.record(z.string(), z.string().describe('Secret value'));
6
9
 
7
10
  export const listSubcommand = createSubcommand({
8
11
  name: 'list',
9
12
  aliases: ['ls'],
10
13
  description: 'List all secrets',
14
+ tags: ['read-only', 'fast', 'requires-auth', 'requires-project'],
15
+ examples: [getCommand('secret list'), getCommand('secret list --no-mask')],
11
16
  requires: { auth: true, project: true, apiClient: true },
17
+ idempotent: true,
12
18
  schema: {
13
19
  options: z.object({
14
20
  mask: z
@@ -16,6 +22,7 @@ export const listSubcommand = createSubcommand({
16
22
  .default(!!process.stdout.isTTY)
17
23
  .describe('mask the values in output (default: true in TTY for secrets)'),
18
24
  }),
25
+ response: SecretListResponseSchema,
19
26
  },
20
27
 
21
28
  async handler(ctx) {
@@ -30,7 +37,7 @@ export const listSubcommand = createSubcommand({
30
37
 
31
38
  if (Object.keys(secrets).length === 0) {
32
39
  tui.info('No secrets found');
33
- return;
40
+ return {};
34
41
  }
35
42
 
36
43
  // Display the secrets
@@ -52,5 +59,7 @@ export const listSubcommand = createSubcommand({
52
59
  console.log(`${key}=${displayValue}`);
53
60
  }
54
61
  }
62
+
63
+ return secrets;
55
64
  },
56
65
  });
@@ -10,15 +10,28 @@ import {
10
10
  writeEnvFile,
11
11
  mergeEnvVars,
12
12
  } from '../../env-util';
13
+ import { getCommand } from '../../command-prefix';
14
+
15
+ const SecretPullResponseSchema = z.object({
16
+ success: z.boolean().describe('Whether pull succeeded'),
17
+ pulled: z.number().describe('Number of items pulled'),
18
+ path: z.string().describe('Local file path where secrets were saved'),
19
+ force: z.boolean().describe('Whether force mode was used'),
20
+ });
13
21
 
14
22
  export const pullSubcommand = createSubcommand({
15
23
  name: 'pull',
16
24
  description: 'Pull secrets from cloud to local .env.production file',
25
+ tags: ['slow', 'requires-auth', 'requires-project'],
26
+ idempotent: true,
27
+ examples: [getCommand('secret pull'), getCommand('secret pull --force')],
17
28
  requires: { auth: true, project: true, apiClient: true },
29
+ prerequisites: ['cloud deploy'],
18
30
  schema: {
19
31
  options: z.object({
20
32
  force: z.boolean().default(false).describe('overwrite local values with cloud values'),
21
33
  }),
34
+ response: SecretPullResponseSchema,
22
35
  },
23
36
 
24
37
  async handler(ctx) {
@@ -74,5 +87,12 @@ export const pullSubcommand = createSubcommand({
74
87
 
75
88
  const count = Object.keys(cloudSecrets).length;
76
89
  tui.success(`Pulled ${count} secret${count !== 1 ? 's' : ''} to ${targetEnvPath}`);
90
+
91
+ return {
92
+ success: true,
93
+ pulled: count,
94
+ path: targetEnvPath,
95
+ force: opts?.force ?? false,
96
+ };
77
97
  },
78
98
  });
@@ -1,12 +1,34 @@
1
+ import { z } from 'zod';
1
2
  import { createSubcommand } from '../../types';
2
3
  import * as tui from '../../tui';
3
4
  import { projectEnvUpdate } from '@agentuity/server';
4
5
  import { findEnvFile, readEnvFile, filterAgentuitySdkKeys } from '../../env-util';
6
+ import { getCommand } from '../../command-prefix';
7
+
8
+ const SecretPushResponseSchema = z.object({
9
+ success: z.boolean().describe('Whether push succeeded'),
10
+ pushed: z.number().describe('Number of items pushed'),
11
+ source: z.string().describe('Source file path'),
12
+ });
5
13
 
6
14
  export const pushSubcommand = createSubcommand({
7
15
  name: 'push',
8
16
  description: 'Push secrets from local .env.production file to cloud',
17
+ tags: [
18
+ 'mutating',
19
+ 'updates-resource',
20
+ 'slow',
21
+ 'api-intensive',
22
+ 'requires-auth',
23
+ 'requires-project',
24
+ ],
25
+ idempotent: true,
26
+ examples: [getCommand('secret push')],
9
27
  requires: { auth: true, project: true, apiClient: true },
28
+ prerequisites: ['secret set'],
29
+ schema: {
30
+ response: SecretPushResponseSchema,
31
+ },
10
32
 
11
33
  async handler(ctx) {
12
34
  const { apiClient, project, projectDir } = ctx;
@@ -20,7 +42,11 @@ export const pushSubcommand = createSubcommand({
20
42
 
21
43
  if (Object.keys(filteredSecrets).length === 0) {
22
44
  tui.warning('No secrets to push');
23
- return;
45
+ return {
46
+ success: false,
47
+ pushed: 0,
48
+ source: envFilePath,
49
+ };
24
50
  }
25
51
 
26
52
  // Push to cloud (using secrets field)
@@ -33,5 +59,11 @@ export const pushSubcommand = createSubcommand({
33
59
 
34
60
  const count = Object.keys(filteredSecrets).length;
35
61
  tui.success(`Pushed ${count} secret${count !== 1 ? 's' : ''} to cloud`);
62
+
63
+ return {
64
+ success: true,
65
+ pushed: count,
66
+ source: envFilePath,
67
+ };
36
68
  },
37
69
  });
@@ -3,16 +3,30 @@ import { createSubcommand } from '../../types';
3
3
  import * as tui from '../../tui';
4
4
  import { projectEnvUpdate } from '@agentuity/server';
5
5
  import { findEnvFile, readEnvFile, writeEnvFile, filterAgentuitySdkKeys } from '../../env-util';
6
+ import { getCommand } from '../../command-prefix';
7
+
8
+ const SecretSetResponseSchema = z.object({
9
+ success: z.boolean().describe('Whether the operation succeeded'),
10
+ key: z.string().describe('Secret key name'),
11
+ path: z.string().describe('Local file path where secret was saved'),
12
+ });
6
13
 
7
14
  export const setSubcommand = createSubcommand({
8
15
  name: 'set',
9
16
  description: 'Set a secret',
17
+ tags: ['mutating', 'updates-resource', 'slow', 'requires-auth', 'requires-project'],
18
+ idempotent: true,
19
+ examples: [
20
+ getCommand('secret set DATABASE_URL "postgres://user:pass@host:5432/db"'),
21
+ getCommand('secret set STRIPE_SECRET_KEY "sk_live_..."'),
22
+ ],
10
23
  requires: { auth: true, project: true, apiClient: true },
11
24
  schema: {
12
25
  args: z.object({
13
26
  key: z.string().min(1, 'key must not be empty').describe('the secret key'),
14
27
  value: z.string().min(1, 'value must not be empty').describe('the secret value'),
15
28
  }),
29
+ response: SecretSetResponseSchema,
16
30
  },
17
31
 
18
32
  async handler(ctx) {
@@ -41,5 +55,11 @@ export const setSubcommand = createSubcommand({
41
55
  await writeEnvFile(envFilePath, filteredEnv);
42
56
 
43
57
  tui.success(`Secret '${args.key}' set successfully (cloud + ${envFilePath})`);
58
+
59
+ return {
60
+ success: true,
61
+ key: args.key,
62
+ path: envFilePath,
63
+ };
44
64
  },
45
65
  });
@@ -1,17 +1,30 @@
1
1
  import { createCommand } from '../../types';
2
2
  import { getVersion } from '../../version';
3
3
  import { createLogger } from '@agentuity/server';
4
+ import { getCommand } from '../../command-prefix';
5
+ import { z } from 'zod';
6
+ import { ErrorCode } from '../../errors';
7
+
8
+ const VersionResponseSchema = z.string().describe('CLI version number');
4
9
 
5
10
  export const command = createCommand({
6
11
  name: 'version',
7
12
  description: 'Display version information',
13
+ tags: ['read-only', 'fast'],
14
+ examples: [getCommand('version'), getCommand('--version')],
15
+ schema: {
16
+ response: VersionResponseSchema,
17
+ },
18
+ idempotent: true,
8
19
 
9
20
  async handler() {
10
21
  try {
11
- console.log(getVersion());
22
+ const version = getVersion();
23
+ console.log(version);
24
+ return version;
12
25
  } catch (error) {
13
26
  const logger = createLogger();
14
- logger.fatal('Failed to retrieve version: %s', error);
27
+ logger.fatal('Failed to retrieve version: %s', error, ErrorCode.INTERNAL_ERROR);
15
28
  }
16
29
  },
17
30
  });
package/src/config.ts CHANGED
@@ -41,7 +41,7 @@ export async function ensureConfigDir(): Promise<void> {
41
41
 
42
42
  export async function saveProfile(path: string): Promise<void> {
43
43
  await ensureConfigDir();
44
- await writeFile(getProfilePath(), path, { mode: 0o644 });
44
+ await writeFile(getProfilePath(), path, { mode: 0o600 });
45
45
  }
46
46
 
47
47
  export async function getProfile(): Promise<string> {
@@ -108,7 +108,12 @@ function expandTilde(path: string): string {
108
108
  return path;
109
109
  }
110
110
 
111
+ let cachedConfig: Config | null | undefined;
112
+
111
113
  export async function loadConfig(customPath?: string): Promise<Config | null> {
114
+ if (cachedConfig !== undefined) {
115
+ return cachedConfig;
116
+ }
112
117
  const configPath = customPath ? expandTilde(customPath) : await getProfile();
113
118
 
114
119
  try {
@@ -171,11 +176,13 @@ export async function loadConfig(customPath?: string): Promise<Config | null> {
171
176
  result.data.overrides = overrides;
172
177
  }
173
178
 
179
+ cachedConfig = result.data;
174
180
  return result.data;
175
181
  } catch (error) {
176
182
  if (error instanceof Error) {
177
183
  console.error(`Error loading config from ${configPath}:`, error.message);
178
184
  }
185
+ cachedConfig = null;
179
186
  return null;
180
187
  }
181
188
  }
@@ -230,6 +237,7 @@ export async function saveConfig(config: Config, customPath?: string): Promise<v
230
237
  await writeFile(configPath, content + '\n', { mode: 0o600 });
231
238
  // Ensure existing files get correct permissions on upgrade
232
239
  await chmod(configPath, 0o600);
240
+ cachedConfig = config;
233
241
  }
234
242
 
235
243
  async function getOrInitConfig(): Promise<Config> {
@@ -582,10 +590,15 @@ export async function loadBuildMetadata(dir: string): Promise<BuildMetadata> {
582
590
  return result.data;
583
591
  }
584
592
 
585
- export async function loadDevelopmentProjectSDKKey(
586
- projectDir: string
587
- ): Promise<string | undefined> {
588
- const files: string[] = ['.env.development', '.env.local', '.env'];
593
+ export async function loadProjectSDKKey(projectDir: string): Promise<string | undefined> {
594
+ const files: string[] =
595
+ process.env.NODE_ENV === 'production'
596
+ ? ['.env', '.env.production']
597
+ : ['.env.development', '.env.local', '.env'];
598
+ const c = await getOrInitConfig();
599
+ if (c) {
600
+ files.unshift(`.env.${c.name}`);
601
+ }
589
602
  for (const filename of files) {
590
603
  const fn = join(projectDir, filename);
591
604
  if (existsSync(fn)) {
package/src/errors.ts ADDED
@@ -0,0 +1,222 @@
1
+ import type { Logger } from './types';
2
+
3
+ /**
4
+ * Standard exit codes for the CLI
5
+ */
6
+ export enum ExitCode {
7
+ SUCCESS = 0,
8
+ GENERAL_ERROR = 1,
9
+ VALIDATION_ERROR = 2,
10
+ AUTH_ERROR = 3,
11
+ NOT_FOUND = 4,
12
+ PERMISSION_ERROR = 5,
13
+ NETWORK_ERROR = 6,
14
+ FILE_ERROR = 7,
15
+ USER_CANCELLED = 8,
16
+ }
17
+
18
+ /**
19
+ * Standard error codes for the CLI
20
+ */
21
+ export enum ErrorCode {
22
+ // Validation errors
23
+ VALIDATION_FAILED = 'VALIDATION_FAILED',
24
+ MISSING_ARGUMENT = 'MISSING_ARGUMENT',
25
+ INVALID_ARGUMENT = 'INVALID_ARGUMENT',
26
+ INVALID_OPTION = 'INVALID_OPTION',
27
+ UNKNOWN_COMMAND = 'UNKNOWN_COMMAND',
28
+
29
+ // Authentication errors
30
+ AUTH_REQUIRED = 'AUTH_REQUIRED',
31
+ AUTH_FAILED = 'AUTH_FAILED',
32
+ AUTH_EXPIRED = 'AUTH_EXPIRED',
33
+ PERMISSION_DENIED = 'PERMISSION_DENIED',
34
+
35
+ // Project/Configuration errors
36
+ PROJECT_NOT_FOUND = 'PROJECT_NOT_FOUND',
37
+ PROJECT_INVALID = 'PROJECT_INVALID',
38
+ CONFIG_NOT_FOUND = 'CONFIG_NOT_FOUND',
39
+ CONFIG_INVALID = 'CONFIG_INVALID',
40
+
41
+ // Resource errors
42
+ RESOURCE_NOT_FOUND = 'RESOURCE_NOT_FOUND',
43
+ RESOURCE_ALREADY_EXISTS = 'RESOURCE_ALREADY_EXISTS',
44
+ RESOURCE_CONFLICT = 'RESOURCE_CONFLICT',
45
+
46
+ // Organization/Region errors
47
+ ORG_REQUIRED = 'ORG_REQUIRED',
48
+ ORG_NOT_FOUND = 'ORG_NOT_FOUND',
49
+ REGION_REQUIRED = 'REGION_REQUIRED',
50
+ REGION_NOT_FOUND = 'REGION_NOT_FOUND',
51
+ NO_REGIONS_AVAILABLE = 'NO_REGIONS_AVAILABLE',
52
+
53
+ // Network/API errors
54
+ NETWORK_ERROR = 'NETWORK_ERROR',
55
+ API_ERROR = 'API_ERROR',
56
+ TIMEOUT = 'TIMEOUT',
57
+
58
+ // File system errors
59
+ FILE_NOT_FOUND = 'FILE_NOT_FOUND',
60
+ FILE_READ_ERROR = 'FILE_READ_ERROR',
61
+ FILE_WRITE_ERROR = 'FILE_WRITE_ERROR',
62
+ DIRECTORY_NOT_FOUND = 'DIRECTORY_NOT_FOUND',
63
+
64
+ // Runtime errors
65
+ RUNTIME_ERROR = 'RUNTIME_ERROR',
66
+ INTERNAL_ERROR = 'INTERNAL_ERROR',
67
+ NOT_IMPLEMENTED = 'NOT_IMPLEMENTED',
68
+
69
+ // User cancellation
70
+ USER_CANCELLED = 'USER_CANCELLED',
71
+ }
72
+
73
+ /**
74
+ * Map error codes to exit codes
75
+ */
76
+ export function getExitCode(errorCode: ErrorCode): ExitCode {
77
+ switch (errorCode) {
78
+ // Validation errors
79
+ case ErrorCode.VALIDATION_FAILED:
80
+ case ErrorCode.MISSING_ARGUMENT:
81
+ case ErrorCode.INVALID_ARGUMENT:
82
+ case ErrorCode.INVALID_OPTION:
83
+ case ErrorCode.UNKNOWN_COMMAND:
84
+ case ErrorCode.PROJECT_INVALID:
85
+ case ErrorCode.CONFIG_INVALID:
86
+ return ExitCode.VALIDATION_ERROR;
87
+
88
+ // Authentication errors
89
+ case ErrorCode.AUTH_REQUIRED:
90
+ case ErrorCode.AUTH_FAILED:
91
+ case ErrorCode.AUTH_EXPIRED:
92
+ return ExitCode.AUTH_ERROR;
93
+
94
+ // Permission errors
95
+ case ErrorCode.PERMISSION_DENIED:
96
+ return ExitCode.PERMISSION_ERROR;
97
+
98
+ // Not found errors
99
+ case ErrorCode.PROJECT_NOT_FOUND:
100
+ case ErrorCode.CONFIG_NOT_FOUND:
101
+ case ErrorCode.RESOURCE_NOT_FOUND:
102
+ case ErrorCode.ORG_NOT_FOUND:
103
+ case ErrorCode.REGION_NOT_FOUND:
104
+ case ErrorCode.FILE_NOT_FOUND:
105
+ case ErrorCode.DIRECTORY_NOT_FOUND:
106
+ case ErrorCode.NO_REGIONS_AVAILABLE:
107
+ return ExitCode.NOT_FOUND;
108
+
109
+ // Network/API errors
110
+ case ErrorCode.NETWORK_ERROR:
111
+ case ErrorCode.API_ERROR:
112
+ case ErrorCode.TIMEOUT:
113
+ return ExitCode.NETWORK_ERROR;
114
+
115
+ // File system errors
116
+ case ErrorCode.FILE_READ_ERROR:
117
+ case ErrorCode.FILE_WRITE_ERROR:
118
+ return ExitCode.FILE_ERROR;
119
+
120
+ // User cancellation
121
+ case ErrorCode.USER_CANCELLED:
122
+ return ExitCode.USER_CANCELLED;
123
+
124
+ // Resource conflicts and other errors
125
+ case ErrorCode.RESOURCE_ALREADY_EXISTS:
126
+ case ErrorCode.RESOURCE_CONFLICT:
127
+ case ErrorCode.ORG_REQUIRED:
128
+ case ErrorCode.REGION_REQUIRED:
129
+ case ErrorCode.RUNTIME_ERROR:
130
+ case ErrorCode.INTERNAL_ERROR:
131
+ case ErrorCode.NOT_IMPLEMENTED:
132
+ default:
133
+ return ExitCode.GENERAL_ERROR;
134
+ }
135
+ }
136
+
137
+ /**
138
+ * Structured error information
139
+ */
140
+ export interface StructuredError {
141
+ code: ErrorCode;
142
+ message: string;
143
+ details?: Record<string, unknown>;
144
+ suggestions?: string[];
145
+ exitCode?: ExitCode;
146
+ }
147
+
148
+ /**
149
+ * Format error in JSON structure
150
+ */
151
+ export function formatErrorJSON(error: StructuredError): string {
152
+ const exitCode = error.exitCode ?? getExitCode(error.code);
153
+ const output: Record<string, unknown> = {
154
+ error: {
155
+ code: error.code,
156
+ message: error.message,
157
+ exitCode,
158
+ },
159
+ };
160
+
161
+ if (error.details) {
162
+ (output.error as Record<string, unknown>).details = error.details;
163
+ }
164
+
165
+ if (error.suggestions && error.suggestions.length > 0) {
166
+ (output.error as Record<string, unknown>).suggestions = error.suggestions;
167
+ }
168
+
169
+ return JSON.stringify(output, null, 2);
170
+ }
171
+
172
+ /**
173
+ * Format error for human-readable output
174
+ */
175
+ export function formatErrorHuman(error: StructuredError): string {
176
+ let output = `error: ${error.message}`;
177
+
178
+ if (error.details && Object.keys(error.details).length > 0) {
179
+ output += '\n\nDetails:';
180
+ for (const [key, value] of Object.entries(error.details)) {
181
+ output += `\n ${key}: ${JSON.stringify(value)}`;
182
+ }
183
+ }
184
+
185
+ if (error.suggestions && error.suggestions.length > 0) {
186
+ output += '\n\nSuggestions:';
187
+ for (const suggestion of error.suggestions) {
188
+ output += `\n - ${suggestion}`;
189
+ }
190
+ }
191
+
192
+ return output;
193
+ }
194
+
195
+ /**
196
+ * Exit the process with a structured error
197
+ */
198
+ export function exitWithError(
199
+ error: StructuredError,
200
+ logger: Logger,
201
+ errorFormat: 'json' | 'text' = 'text'
202
+ ): never {
203
+ if (errorFormat === 'json') {
204
+ console.error(formatErrorJSON(error));
205
+ } else {
206
+ console.error(formatErrorHuman(error));
207
+ }
208
+ const exitCode = error.exitCode ?? getExitCode(error.code);
209
+ process.exit(exitCode);
210
+ }
211
+
212
+ /**
213
+ * Create a structured error from a simple message and code
214
+ */
215
+ export function createError(
216
+ code: ErrorCode,
217
+ message: string,
218
+ details?: Record<string, unknown>,
219
+ suggestions?: string[]
220
+ ): StructuredError {
221
+ return { code, message, details, suggestions };
222
+ }
package/src/explain.ts ADDED
@@ -0,0 +1,126 @@
1
+ import type { GlobalOptions } from './types';
2
+ import * as tui from './tui';
3
+
4
+ /**
5
+ * Utilities for explain mode and dry-run mode
6
+ */
7
+
8
+ /**
9
+ * Check if explain mode is enabled
10
+ */
11
+ export function isExplainMode(options: GlobalOptions): boolean {
12
+ return options.explain === true;
13
+ }
14
+
15
+ /**
16
+ * Check if dry-run mode is enabled
17
+ */
18
+ export function isDryRunMode(options: GlobalOptions): boolean {
19
+ return options.dryRun === true;
20
+ }
21
+
22
+ /**
23
+ * Check if the command should execute (not explain, not dry-run unless specifically handling dry-run)
24
+ */
25
+ export function shouldExecute(options: GlobalOptions): boolean {
26
+ return !options.explain && !options.dryRun;
27
+ }
28
+
29
+ /**
30
+ * Explanation step for a command action
31
+ */
32
+ export interface ExplainStep {
33
+ action: string;
34
+ details?: Record<string, unknown>;
35
+ }
36
+
37
+ /**
38
+ * Explanation plan for a command
39
+ */
40
+ export interface ExplainPlan {
41
+ command: string;
42
+ description: string;
43
+ prerequisites?: string[];
44
+ steps: ExplainStep[];
45
+ warnings?: string[];
46
+ estimatedDuration?: string;
47
+ }
48
+
49
+ /**
50
+ * Output an explanation plan
51
+ */
52
+ export function outputExplain(plan: ExplainPlan, options: GlobalOptions): void {
53
+ if (options.json) {
54
+ console.log(JSON.stringify({ explain: plan }, null, 2));
55
+ return;
56
+ }
57
+
58
+ // Human-readable output
59
+ console.log(tui.bold('Command Explanation:'));
60
+ console.log(` ${plan.command}`);
61
+ tui.newline();
62
+
63
+ if (plan.description) {
64
+ console.log(tui.bold('Description:'));
65
+ console.log(` ${plan.description}`);
66
+ tui.newline();
67
+ }
68
+
69
+ if (plan.prerequisites && plan.prerequisites.length > 0) {
70
+ console.log(tui.bold('Prerequisites:'));
71
+ for (const prereq of plan.prerequisites) {
72
+ console.log(` ${tui.bullet} ${prereq}`);
73
+ }
74
+ tui.newline();
75
+ }
76
+
77
+ console.log(tui.bold('This command will:'));
78
+ for (const step of plan.steps) {
79
+ console.log(` • ${step.action}`);
80
+ if (step.details && Object.keys(step.details).length > 0) {
81
+ for (const [key, value] of Object.entries(step.details)) {
82
+ console.log(` ${tui.muted(`${key}: ${JSON.stringify(value)}`)}`);
83
+ }
84
+ }
85
+ }
86
+ tui.newline();
87
+
88
+ if (plan.warnings && plan.warnings.length > 0) {
89
+ console.log(tui.bold('Warnings:'));
90
+ for (const warn of plan.warnings) {
91
+ console.log(` ⚠ ${warn}`);
92
+ }
93
+ tui.newline();
94
+ }
95
+
96
+ if (plan.estimatedDuration) {
97
+ console.log(tui.muted(`Estimated duration: ${plan.estimatedDuration}`));
98
+ tui.newline();
99
+ }
100
+ }
101
+
102
+ /**
103
+ * Create a simple explain plan
104
+ */
105
+ export function createExplainPlan(
106
+ command: string,
107
+ description: string,
108
+ steps: string[]
109
+ ): ExplainPlan {
110
+ return {
111
+ command,
112
+ description,
113
+ steps: steps.map((action) => ({ action })),
114
+ };
115
+ }
116
+
117
+ /**
118
+ * Output dry-run result
119
+ */
120
+ export function outputDryRun(message: string, options: GlobalOptions): void {
121
+ if (options.json) {
122
+ console.log(JSON.stringify({ dryRun: true, message }, null, 2));
123
+ } else {
124
+ console.log(tui.muted('[DRY RUN] ') + message);
125
+ }
126
+ }
package/src/index.ts CHANGED
@@ -1,5 +1,47 @@
1
1
  export { createCLI, registerCommands } from './cli';
2
2
  export { validateRuntime, isBun } from './runtime';
3
+ export { generateCLISchema, type CLISchema, type SchemaCommand } from './schema-generator';
4
+ export {
5
+ ErrorCode,
6
+ createError,
7
+ exitWithError,
8
+ formatErrorJSON,
9
+ formatErrorHuman,
10
+ type StructuredError,
11
+ } from './errors';
12
+ export { wrapLogger, CLILogger } from './cli-logger';
13
+ export {
14
+ isJSONMode,
15
+ isQuietMode,
16
+ shouldDisableProgress,
17
+ shouldDisableColors,
18
+ outputJSON,
19
+ outputSuccess,
20
+ outputInfo,
21
+ outputWarning,
22
+ canPrompt,
23
+ createSuccessResponse,
24
+ createErrorResponse,
25
+ createMetadata,
26
+ setOutputOptions,
27
+ getOutputOptions,
28
+ createBatchResult,
29
+ outputBatchResult,
30
+ type JSONResponse,
31
+ type ResponseMetadata,
32
+ type BatchItemResult,
33
+ type BatchOperationResult,
34
+ } from './output';
35
+ export {
36
+ isExplainMode,
37
+ isDryRunMode,
38
+ shouldExecute,
39
+ outputExplain,
40
+ createExplainPlan,
41
+ outputDryRun,
42
+ type ExplainPlan,
43
+ type ExplainStep,
44
+ } from './explain';
3
45
  export { getVersion, getRevision, getPackageName, getPackage } from './version';
4
46
  export { requireAuth, optionalAuth } from './auth';
5
47
  export {
@@ -27,6 +69,15 @@ export { discoverCommands } from './cmd';
27
69
  export { detectColorScheme } from './terminal';
28
70
  export { getCommandPrefix, getCommand } from './command-prefix';
29
71
  export * as tui from './tui';
72
+ export {
73
+ createRepl,
74
+ type ReplConfig,
75
+ type ReplCommand,
76
+ type ReplContext,
77
+ type ParsedCommand,
78
+ type CommandHandler,
79
+ type TableColumn,
80
+ } from './repl';
30
81
  export { runSteps, setStepsColorScheme, stepSuccess, stepSkipped, stepError } from './steps';
31
82
  export { playSound } from './sound';
32
83
  export {