@agentuity/cli 0.0.51 → 0.0.52

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 (299) hide show
  1. package/dist/api.js +68 -0
  2. package/dist/api.js.map +1 -0
  3. package/dist/auth.js +225 -0
  4. package/dist/auth.js.map +1 -0
  5. package/dist/banner.js +35 -0
  6. package/dist/banner.js.map +1 -0
  7. package/dist/cli-logger.js +72 -0
  8. package/dist/cli-logger.js.map +1 -0
  9. package/dist/cli.js +822 -0
  10. package/dist/cli.js.map +1 -0
  11. package/dist/cmd/ai/capabilities/index.js +10 -0
  12. package/dist/cmd/ai/capabilities/index.js.map +1 -0
  13. package/dist/cmd/ai/capabilities/show.js +221 -0
  14. package/dist/cmd/ai/capabilities/show.js.map +1 -0
  15. package/dist/cmd/ai/index.js +11 -0
  16. package/dist/cmd/ai/index.js.map +1 -0
  17. package/dist/cmd/ai/prompt/index.js +10 -0
  18. package/dist/cmd/ai/prompt/index.js.map +1 -0
  19. package/dist/cmd/ai/prompt/llm.js +365 -0
  20. package/dist/cmd/ai/prompt/llm.js.map +1 -0
  21. package/dist/cmd/ai/schema/index.js +10 -0
  22. package/dist/cmd/ai/schema/index.js.map +1 -0
  23. package/dist/cmd/ai/schema/show.js +23 -0
  24. package/dist/cmd/ai/schema/show.js.map +1 -0
  25. package/dist/cmd/auth/api.js +85 -0
  26. package/dist/cmd/auth/api.js.map +1 -0
  27. package/dist/cmd/auth/index.js +13 -0
  28. package/dist/cmd/auth/index.js.map +1 -0
  29. package/dist/cmd/auth/login.js +84 -0
  30. package/dist/cmd/auth/login.js.map +1 -0
  31. package/dist/cmd/auth/logout.js +17 -0
  32. package/dist/cmd/auth/logout.js.map +1 -0
  33. package/dist/cmd/auth/signup.js +55 -0
  34. package/dist/cmd/auth/signup.js.map +1 -0
  35. package/dist/cmd/auth/ssh/add.js +239 -0
  36. package/dist/cmd/auth/ssh/add.js.map +1 -0
  37. package/dist/cmd/auth/ssh/api.js +53 -0
  38. package/dist/cmd/auth/ssh/api.js.map +1 -0
  39. package/dist/cmd/auth/ssh/delete.js +126 -0
  40. package/dist/cmd/auth/ssh/delete.js.map +1 -0
  41. package/dist/cmd/auth/ssh/index.js +11 -0
  42. package/dist/cmd/auth/ssh/index.js.map +1 -0
  43. package/dist/cmd/auth/ssh/list.js +70 -0
  44. package/dist/cmd/auth/ssh/list.js.map +1 -0
  45. package/dist/cmd/auth/whoami.js +68 -0
  46. package/dist/cmd/auth/whoami.js.map +1 -0
  47. package/dist/cmd/build/ast.js +608 -0
  48. package/dist/cmd/build/ast.js.map +1 -0
  49. package/dist/cmd/build/ast.test.js +389 -0
  50. package/dist/cmd/build/ast.test.js.map +1 -0
  51. package/dist/cmd/build/bundler.js +304 -0
  52. package/dist/cmd/build/bundler.js.map +1 -0
  53. package/dist/cmd/build/file.js +10 -0
  54. package/dist/cmd/build/file.js.map +1 -0
  55. package/dist/cmd/build/fix-duplicate-exports.js +167 -0
  56. package/dist/cmd/build/fix-duplicate-exports.js.map +1 -0
  57. package/dist/cmd/build/fix-duplicate-exports.test.js +300 -0
  58. package/dist/cmd/build/fix-duplicate-exports.test.js.map +1 -0
  59. package/dist/cmd/build/index.d.ts.map +1 -1
  60. package/dist/cmd/build/index.js +79 -0
  61. package/dist/cmd/build/index.js.map +1 -0
  62. package/dist/cmd/build/patch/_util.js +42 -0
  63. package/dist/cmd/build/patch/_util.js.map +1 -0
  64. package/dist/cmd/build/patch/aisdk.js +65 -0
  65. package/dist/cmd/build/patch/aisdk.js.map +1 -0
  66. package/dist/cmd/build/patch/index.js +97 -0
  67. package/dist/cmd/build/patch/index.js.map +1 -0
  68. package/dist/cmd/build/patch/llm.js +18 -0
  69. package/dist/cmd/build/patch/llm.js.map +1 -0
  70. package/dist/cmd/build/plugin.d.ts.map +1 -1
  71. package/dist/cmd/build/plugin.js +556 -0
  72. package/dist/cmd/build/plugin.js.map +1 -0
  73. package/dist/cmd/cloud/agents/index.js +133 -0
  74. package/dist/cmd/cloud/agents/index.js.map +1 -0
  75. package/dist/cmd/cloud/deploy.js +341 -0
  76. package/dist/cmd/cloud/deploy.js.map +1 -0
  77. package/dist/cmd/cloud/deployment/index.js +20 -0
  78. package/dist/cmd/cloud/deployment/index.js.map +1 -0
  79. package/dist/cmd/cloud/deployment/list.js +89 -0
  80. package/dist/cmd/cloud/deployment/list.js.map +1 -0
  81. package/dist/cmd/cloud/deployment/remove.js +60 -0
  82. package/dist/cmd/cloud/deployment/remove.js.map +1 -0
  83. package/dist/cmd/cloud/deployment/rollback.js +80 -0
  84. package/dist/cmd/cloud/deployment/rollback.js.map +1 -0
  85. package/dist/cmd/cloud/deployment/show.js +106 -0
  86. package/dist/cmd/cloud/deployment/show.js.map +1 -0
  87. package/dist/cmd/cloud/deployment/undeploy.js +45 -0
  88. package/dist/cmd/cloud/deployment/undeploy.js.map +1 -0
  89. package/dist/cmd/cloud/deployment/utils.js +10 -0
  90. package/dist/cmd/cloud/deployment/utils.js.map +1 -0
  91. package/dist/cmd/cloud/domain.js +77 -0
  92. package/dist/cmd/cloud/domain.js.map +1 -0
  93. package/dist/cmd/cloud/env/delete.js +50 -0
  94. package/dist/cmd/cloud/env/delete.js.map +1 -0
  95. package/dist/cmd/cloud/env/get.js +65 -0
  96. package/dist/cmd/cloud/env/get.js.map +1 -0
  97. package/dist/cmd/cloud/env/import.js +113 -0
  98. package/dist/cmd/cloud/env/import.js.map +1 -0
  99. package/dist/cmd/cloud/env/index.js +24 -0
  100. package/dist/cmd/cloud/env/index.js.map +1 -0
  101. package/dist/cmd/cloud/env/list.js +58 -0
  102. package/dist/cmd/cloud/env/list.js.map +1 -0
  103. package/dist/cmd/cloud/env/pull.js +81 -0
  104. package/dist/cmd/cloud/env/pull.js.map +1 -0
  105. package/dist/cmd/cloud/env/push.js +61 -0
  106. package/dist/cmd/cloud/env/push.js.map +1 -0
  107. package/dist/cmd/cloud/env/set.js +73 -0
  108. package/dist/cmd/cloud/env/set.js.map +1 -0
  109. package/dist/cmd/cloud/index.js +31 -0
  110. package/dist/cmd/cloud/index.js.map +1 -0
  111. package/dist/cmd/cloud/keyvalue/create-namespace.js +41 -0
  112. package/dist/cmd/cloud/keyvalue/create-namespace.js.map +1 -0
  113. package/dist/cmd/cloud/keyvalue/delete-namespace.js +64 -0
  114. package/dist/cmd/cloud/keyvalue/delete-namespace.js.map +1 -0
  115. package/dist/cmd/cloud/keyvalue/delete.js +47 -0
  116. package/dist/cmd/cloud/keyvalue/delete.js.map +1 -0
  117. package/dist/cmd/cloud/keyvalue/get.js +65 -0
  118. package/dist/cmd/cloud/keyvalue/get.js.map +1 -0
  119. package/dist/cmd/cloud/keyvalue/index.js +32 -0
  120. package/dist/cmd/cloud/keyvalue/index.js.map +1 -0
  121. package/dist/cmd/cloud/keyvalue/keys.js +50 -0
  122. package/dist/cmd/cloud/keyvalue/keys.js.map +1 -0
  123. package/dist/cmd/cloud/keyvalue/list-namespaces.js +37 -0
  124. package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -0
  125. package/dist/cmd/cloud/keyvalue/repl.js +277 -0
  126. package/dist/cmd/cloud/keyvalue/repl.js.map +1 -0
  127. package/dist/cmd/cloud/keyvalue/search.js +72 -0
  128. package/dist/cmd/cloud/keyvalue/search.js.map +1 -0
  129. package/dist/cmd/cloud/keyvalue/set.js +59 -0
  130. package/dist/cmd/cloud/keyvalue/set.js.map +1 -0
  131. package/dist/cmd/cloud/keyvalue/stats.js +82 -0
  132. package/dist/cmd/cloud/keyvalue/stats.js.map +1 -0
  133. package/dist/cmd/cloud/keyvalue/util.js +19 -0
  134. package/dist/cmd/cloud/keyvalue/util.js.map +1 -0
  135. package/dist/cmd/cloud/objectstore/delete-bucket.js +66 -0
  136. package/dist/cmd/cloud/objectstore/delete-bucket.js.map +1 -0
  137. package/dist/cmd/cloud/objectstore/delete.js +56 -0
  138. package/dist/cmd/cloud/objectstore/delete.js.map +1 -0
  139. package/dist/cmd/cloud/objectstore/get.js +64 -0
  140. package/dist/cmd/cloud/objectstore/get.js.map +1 -0
  141. package/dist/cmd/cloud/objectstore/index.js +28 -0
  142. package/dist/cmd/cloud/objectstore/index.js.map +1 -0
  143. package/dist/cmd/cloud/objectstore/list-buckets.js +37 -0
  144. package/dist/cmd/cloud/objectstore/list-buckets.js.map +1 -0
  145. package/dist/cmd/cloud/objectstore/list-keys.js +52 -0
  146. package/dist/cmd/cloud/objectstore/list-keys.js.map +1 -0
  147. package/dist/cmd/cloud/objectstore/put.js +57 -0
  148. package/dist/cmd/cloud/objectstore/put.js.map +1 -0
  149. package/dist/cmd/cloud/objectstore/repl.js +219 -0
  150. package/dist/cmd/cloud/objectstore/repl.js.map +1 -0
  151. package/dist/cmd/cloud/objectstore/url.js +55 -0
  152. package/dist/cmd/cloud/objectstore/url.js.map +1 -0
  153. package/dist/cmd/cloud/objectstore/util.js +18 -0
  154. package/dist/cmd/cloud/objectstore/util.js.map +1 -0
  155. package/dist/cmd/cloud/resource/add.js +70 -0
  156. package/dist/cmd/cloud/resource/add.js.map +1 -0
  157. package/dist/cmd/cloud/resource/delete.js +126 -0
  158. package/dist/cmd/cloud/resource/delete.js.map +1 -0
  159. package/dist/cmd/cloud/resource/index.js +12 -0
  160. package/dist/cmd/cloud/resource/index.js.map +1 -0
  161. package/dist/cmd/cloud/resource/list.js +89 -0
  162. package/dist/cmd/cloud/resource/list.js.map +1 -0
  163. package/dist/cmd/cloud/scp/download.js +72 -0
  164. package/dist/cmd/cloud/scp/download.js.map +1 -0
  165. package/dist/cmd/cloud/scp/index.js +10 -0
  166. package/dist/cmd/cloud/scp/index.js.map +1 -0
  167. package/dist/cmd/cloud/scp/upload.js +75 -0
  168. package/dist/cmd/cloud/scp/upload.js.map +1 -0
  169. package/dist/cmd/cloud/secret/delete.js +50 -0
  170. package/dist/cmd/cloud/secret/delete.js.map +1 -0
  171. package/dist/cmd/cloud/secret/get.js +69 -0
  172. package/dist/cmd/cloud/secret/get.js.map +1 -0
  173. package/dist/cmd/cloud/secret/import.js +88 -0
  174. package/dist/cmd/cloud/secret/import.js.map +1 -0
  175. package/dist/cmd/cloud/secret/index.js +24 -0
  176. package/dist/cmd/cloud/secret/index.js.map +1 -0
  177. package/dist/cmd/cloud/secret/list.js +58 -0
  178. package/dist/cmd/cloud/secret/list.js.map +1 -0
  179. package/dist/cmd/cloud/secret/pull.js +81 -0
  180. package/dist/cmd/cloud/secret/pull.js.map +1 -0
  181. package/dist/cmd/cloud/secret/push.js +61 -0
  182. package/dist/cmd/cloud/secret/push.js.map +1 -0
  183. package/dist/cmd/cloud/secret/set.js +57 -0
  184. package/dist/cmd/cloud/secret/set.js.map +1 -0
  185. package/dist/cmd/cloud/session/get.d.ts.map +1 -1
  186. package/dist/cmd/cloud/session/get.js +155 -0
  187. package/dist/cmd/cloud/session/get.js.map +1 -0
  188. package/dist/cmd/cloud/session/index.js +11 -0
  189. package/dist/cmd/cloud/session/index.js.map +1 -0
  190. package/dist/cmd/cloud/session/list.js +132 -0
  191. package/dist/cmd/cloud/session/list.js.map +1 -0
  192. package/dist/cmd/cloud/session/logs.js +56 -0
  193. package/dist/cmd/cloud/session/logs.js.map +1 -0
  194. package/dist/cmd/cloud/ssh.js +67 -0
  195. package/dist/cmd/cloud/ssh.js.map +1 -0
  196. package/dist/cmd/dev/agents.js +103 -0
  197. package/dist/cmd/dev/agents.js.map +1 -0
  198. package/dist/cmd/dev/api.js +26 -0
  199. package/dist/cmd/dev/api.js.map +1 -0
  200. package/dist/cmd/dev/download.js +77 -0
  201. package/dist/cmd/dev/download.js.map +1 -0
  202. package/dist/cmd/dev/index.js +745 -0
  203. package/dist/cmd/dev/index.js.map +1 -0
  204. package/dist/cmd/dev/sync.js +229 -0
  205. package/dist/cmd/dev/sync.js.map +1 -0
  206. package/dist/cmd/dev/templates.js +75 -0
  207. package/dist/cmd/dev/templates.js.map +1 -0
  208. package/dist/cmd/index.js +49 -0
  209. package/dist/cmd/index.js.map +1 -0
  210. package/dist/cmd/profile/create.js +89 -0
  211. package/dist/cmd/profile/create.js.map +1 -0
  212. package/dist/cmd/profile/delete.js +63 -0
  213. package/dist/cmd/profile/delete.js.map +1 -0
  214. package/dist/cmd/profile/index.js +14 -0
  215. package/dist/cmd/profile/index.js.map +1 -0
  216. package/dist/cmd/profile/list.js +28 -0
  217. package/dist/cmd/profile/list.js.map +1 -0
  218. package/dist/cmd/profile/show.js +68 -0
  219. package/dist/cmd/profile/show.js.map +1 -0
  220. package/dist/cmd/profile/use.js +37 -0
  221. package/dist/cmd/profile/use.js.map +1 -0
  222. package/dist/cmd/project/create.js +92 -0
  223. package/dist/cmd/project/create.js.map +1 -0
  224. package/dist/cmd/project/delete.js +117 -0
  225. package/dist/cmd/project/delete.js.map +1 -0
  226. package/dist/cmd/project/download.js +217 -0
  227. package/dist/cmd/project/download.js.map +1 -0
  228. package/dist/cmd/project/index.js +12 -0
  229. package/dist/cmd/project/index.js.map +1 -0
  230. package/dist/cmd/project/list.js +51 -0
  231. package/dist/cmd/project/list.js.map +1 -0
  232. package/dist/cmd/project/show.js +54 -0
  233. package/dist/cmd/project/show.js.map +1 -0
  234. package/dist/cmd/project/template-flow.js +315 -0
  235. package/dist/cmd/project/template-flow.js.map +1 -0
  236. package/dist/cmd/project/templates.js +31 -0
  237. package/dist/cmd/project/templates.js.map +1 -0
  238. package/dist/cmd/repl/index.js +444 -0
  239. package/dist/cmd/repl/index.js.map +1 -0
  240. package/dist/cmd/version/index.js +29 -0
  241. package/dist/cmd/version/index.js.map +1 -0
  242. package/dist/command-prefix.js +37 -0
  243. package/dist/command-prefix.js.map +1 -0
  244. package/dist/config.js +536 -0
  245. package/dist/config.js.map +1 -0
  246. package/dist/crypto/box.js +382 -0
  247. package/dist/crypto/box.js.map +1 -0
  248. package/dist/crypto/box.test.js +317 -0
  249. package/dist/crypto/box.test.js.map +1 -0
  250. package/dist/download.js +64 -0
  251. package/dist/download.js.map +1 -0
  252. package/dist/env-util.js +219 -0
  253. package/dist/env-util.js.map +1 -0
  254. package/dist/env-util.test.js +146 -0
  255. package/dist/env-util.test.js.map +1 -0
  256. package/dist/errors.js +177 -0
  257. package/dist/errors.js.map +1 -0
  258. package/dist/explain.js +90 -0
  259. package/dist/explain.js.map +1 -0
  260. package/dist/index.js +23 -0
  261. package/dist/index.js.map +1 -0
  262. package/dist/json.js +29 -0
  263. package/dist/json.js.map +1 -0
  264. package/dist/legacy-check.js +104 -0
  265. package/dist/legacy-check.js.map +1 -0
  266. package/dist/output.js +207 -0
  267. package/dist/output.js.map +1 -0
  268. package/dist/repl.js +1176 -0
  269. package/dist/repl.js.map +1 -0
  270. package/dist/runtime.js +19 -0
  271. package/dist/runtime.js.map +1 -0
  272. package/dist/schema-generator.js +289 -0
  273. package/dist/schema-generator.js.map +1 -0
  274. package/dist/schema-parser.js +145 -0
  275. package/dist/schema-parser.js.map +1 -0
  276. package/dist/sound.js +44 -0
  277. package/dist/sound.js.map +1 -0
  278. package/dist/steps.js +293 -0
  279. package/dist/steps.js.map +1 -0
  280. package/dist/terminal.js +130 -0
  281. package/dist/terminal.js.map +1 -0
  282. package/dist/tui.js +1124 -0
  283. package/dist/tui.js.map +1 -0
  284. package/dist/types.js +163 -0
  285. package/dist/types.js.map +1 -0
  286. package/dist/utils/detectSubagent.js +25 -0
  287. package/dist/utils/detectSubagent.js.map +1 -0
  288. package/dist/utils/format.js +21 -0
  289. package/dist/utils/format.js.map +1 -0
  290. package/dist/utils/zip.js +33 -0
  291. package/dist/utils/zip.js.map +1 -0
  292. package/dist/version.js +24 -0
  293. package/dist/version.js.map +1 -0
  294. package/package.json +6 -6
  295. package/src/banner.ts +1 -1
  296. package/src/cmd/build/index.ts +15 -21
  297. package/src/cmd/build/plugin.ts +2 -1
  298. package/src/cmd/cloud/session/get.ts +20 -14
  299. package/src/cmd/cloud/session/list.ts +1 -1
package/dist/cli.js ADDED
@@ -0,0 +1,822 @@
1
+ import { Command } from 'commander';
2
+ import { showBanner } from './banner';
3
+ import { requireAuth, optionalAuth, requireOrg, optionalOrg as selectOptionalOrg } from './auth';
4
+ import { listRegions } from '@agentuity/server';
5
+ import enquirer from 'enquirer';
6
+ import * as tui from './tui';
7
+ import { parseArgsSchema, parseOptionsSchema, buildValidationInput } from './schema-parser';
8
+ import { defaultProfileName, loadProjectConfig } from './config';
9
+ import { APIClient, getAPIBaseURL } from './api';
10
+ import { ErrorCode, ExitCode, createError, exitWithError } from './errors';
11
+ import { getCommand } from './command-prefix';
12
+ import { isValidateMode, outputValidation } from './output';
13
+ function createAPIClient(baseCtx, config) {
14
+ try {
15
+ const apiUrl = getAPIBaseURL(config);
16
+ const apiClient = new APIClient(apiUrl, baseCtx.logger, config);
17
+ if (!apiClient) {
18
+ throw new Error('APIClient constructor returned null/undefined');
19
+ }
20
+ if (typeof apiClient.request !== 'function') {
21
+ throw new Error('APIClient instance is missing request method');
22
+ }
23
+ return apiClient;
24
+ }
25
+ catch (error) {
26
+ baseCtx.logger.error('Failed to create API client:', error);
27
+ throw new Error(`API client initialization failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
28
+ }
29
+ }
30
+ /**
31
+ * Execute handler or output validation result based on mode
32
+ */
33
+ async function executeOrValidate(ctx, commandName, handler) {
34
+ if (isValidateMode(ctx.options)) {
35
+ // In validate mode, just output success (validation already passed via Zod)
36
+ const result = {
37
+ valid: true,
38
+ command: commandName,
39
+ };
40
+ outputValidation(result, ctx.options);
41
+ }
42
+ else if (handler) {
43
+ // Normal execution
44
+ await handler(ctx);
45
+ }
46
+ }
47
+ /**
48
+ * Handle validation error - output structured result in validate mode, otherwise log and exit
49
+ */
50
+ function handleValidationError(error, commandName, baseCtx) {
51
+ if (error && typeof error === 'object' && 'issues' in error) {
52
+ const issues = error.issues;
53
+ if (isValidateMode(baseCtx.options)) {
54
+ // In validate mode, output structured validation result
55
+ const result = {
56
+ valid: false,
57
+ command: commandName,
58
+ errors: issues.map((issue) => ({
59
+ field: issue.path?.length ? issue.path.join('.') : 'unknown',
60
+ message: issue.message,
61
+ })),
62
+ };
63
+ outputValidation(result, baseCtx.options);
64
+ process.exit(ExitCode.VALIDATION_ERROR);
65
+ }
66
+ else {
67
+ // Use centralized error handling
68
+ exitWithError({
69
+ code: ErrorCode.VALIDATION_FAILED,
70
+ message: 'Validation error',
71
+ details: {
72
+ issues: issues.map((issue) => ({
73
+ field: issue.path?.length ? issue.path.join('.') : 'unknown',
74
+ message: issue.message,
75
+ })),
76
+ },
77
+ }, baseCtx.logger, baseCtx.options.errorFormat ?? 'text');
78
+ }
79
+ }
80
+ throw error;
81
+ }
82
+ function normalizeReqs(def) {
83
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
84
+ const d = def;
85
+ const requires = d.requires;
86
+ const optional = d.optional;
87
+ const requiresAuth = requires?.auth === true;
88
+ const optionalAuthValue = optional?.auth;
89
+ const optionalAuth = optionalAuthValue === true ? 'Continue without authentication' : optionalAuthValue || false;
90
+ const requiresProject = requires?.project === true;
91
+ const optionalProject = optional?.project === true;
92
+ const requiresOrg = requires?.org === true;
93
+ const optionalOrg = optional?.org === true;
94
+ const requiresRegions = requires?.regions === true;
95
+ const requiresRegion = requires?.region === true;
96
+ const optionalRegion = optional?.region === true;
97
+ // Implicitly require apiClient if org or region is required or optional
98
+ const requiresAPIClient = requires?.apiClient === true ||
99
+ requiresOrg ||
100
+ optionalOrg ||
101
+ requiresRegion ||
102
+ optionalRegion ||
103
+ requiresRegions;
104
+ return {
105
+ requiresAuth,
106
+ optionalAuth,
107
+ requiresProject,
108
+ optionalProject,
109
+ requiresAPIClient,
110
+ requiresOrg,
111
+ optionalOrg,
112
+ requiresRegions,
113
+ requiresRegion,
114
+ optionalRegion,
115
+ };
116
+ }
117
+ function handleProjectConfigError(error, requiresProject, logger, errorFormat) {
118
+ if (requiresProject &&
119
+ error &&
120
+ typeof error === 'object' &&
121
+ 'name' in error &&
122
+ error.name === 'ProjectConfigNotFoundExpection') {
123
+ exitWithError(createError(ErrorCode.PROJECT_NOT_FOUND, 'Invalid project folder', undefined, [
124
+ 'Use --dir to specify a different directory',
125
+ 'Change to a directory containing agentuity.json',
126
+ `Run "${getCommand('project create')}" to create a new project`,
127
+ ]), logger, errorFormat ?? 'text');
128
+ }
129
+ throw error;
130
+ }
131
+ export async function createCLI(version) {
132
+ const program = new Command();
133
+ program
134
+ .name('agentuity')
135
+ .version(version, '-V, --version', 'Display version')
136
+ .helpOption('-h, --help=[json]', 'Display help (with optional JSON output)')
137
+ .allowUnknownOption(false)
138
+ .allowExcessArguments(false)
139
+ .showHelpAfterError(true);
140
+ program
141
+ .option('--config <path>', 'Config file path')
142
+ .option('--log-level <level>', 'Log level', process.env.AGENTUITY_LOG_LEVEL ?? 'info')
143
+ .option('--log-timestamp', 'Show timestamps in log output', false)
144
+ .option('--no-log-prefix', 'Hide log level prefixes', true)
145
+ .option('--org-id <id>', 'Use a specific organization when performing operations', process.env.AGENTUITY_CLOUD_ORG_ID)
146
+ .option('--color-scheme <scheme>', 'Color scheme: light or dark')
147
+ .option('--color <mode>', 'Color output: auto, always, never', 'auto')
148
+ .option('--error-format <format>', 'Error output format: json or text', 'text')
149
+ .option('--json', 'Output in JSON format (machine-readable)', false)
150
+ .option('--quiet', 'Suppress non-essential output', false)
151
+ .option('--no-progress', 'Disable progress indicators', false)
152
+ .option('--explain', 'Show what the command would do without executing', false)
153
+ .option('--dry-run', 'Execute command without making changes', false)
154
+ .option('--validate', 'Validate arguments and options without executing', false);
155
+ const skipVersionCheckOption = program.createOption('--skip-version-check', 'Skip version compatibility check (dev only)');
156
+ skipVersionCheckOption.hideHelp();
157
+ program.addOption(skipVersionCheckOption);
158
+ program.action(() => {
159
+ showBanner(version);
160
+ program.help();
161
+ });
162
+ // Handle unknown commands
163
+ program.on('command:*', (operands) => {
164
+ const unknownCommand = operands[0];
165
+ console.error(`error: unknown command '${unknownCommand}'`);
166
+ console.error();
167
+ const availableCommands = program.commands.map((cmd) => cmd.name());
168
+ if (availableCommands.length > 0) {
169
+ console.error('Available commands:');
170
+ availableCommands.forEach((name) => {
171
+ console.error(` ${name}`);
172
+ });
173
+ }
174
+ console.error();
175
+ console.error(`Run '${getCommand('--help')}' for usage information.`);
176
+ process.exit(1);
177
+ });
178
+ // Custom error handling for argument/command parsing errors
179
+ program.configureOutput({
180
+ outputError: (str, write) => {
181
+ // Intercept commander.js error messages
182
+ if (str.includes('too many arguments') || str.includes('unknown command')) {
183
+ // Extract potential command name from error context
184
+ const match = str.match(/got (\d+)/);
185
+ if (match) {
186
+ write(`error: unknown command or subcommand\n`);
187
+ write(`\nRun '${getCommand('--help')}' for available commands.\n`);
188
+ }
189
+ else {
190
+ write(str);
191
+ }
192
+ }
193
+ else {
194
+ write(str);
195
+ }
196
+ },
197
+ });
198
+ // Configure help to show only main command names, not aliases
199
+ program.configureHelp({
200
+ subcommandTerm: (cmd) => cmd.name(),
201
+ });
202
+ return program;
203
+ }
204
+ async function getRegion(regions) {
205
+ if (regions.length === 1) {
206
+ return regions[0].region;
207
+ }
208
+ else {
209
+ const response = await enquirer.prompt({
210
+ type: 'select',
211
+ name: 'region',
212
+ message: 'Select a cloud region:',
213
+ choices: regions.map((r) => ({
214
+ name: r.region,
215
+ message: `${r.description.padEnd(15, ' ')} ${tui.muted(r.region)}`,
216
+ })),
217
+ });
218
+ return response.region;
219
+ }
220
+ }
221
+ async function resolveRegion(opts) {
222
+ const { options, apiClient, logger, required } = opts;
223
+ // Fetch regions
224
+ const regions = await listRegions(apiClient);
225
+ // No regions available
226
+ if (regions.length === 0) {
227
+ if (required) {
228
+ const errorFormat = options.errorFormat;
229
+ exitWithError(createError(ErrorCode.NO_REGIONS_AVAILABLE, 'No cloud regions available', undefined, [
230
+ 'Contact support if you need access to cloud regions',
231
+ ]), logger, errorFormat ?? 'text');
232
+ }
233
+ return undefined;
234
+ }
235
+ // Check if region was provided via flag
236
+ let region = options.region;
237
+ // Validate --region flag if provided
238
+ if (region) {
239
+ const found = regions.find((r) => r.region === region);
240
+ if (!found) {
241
+ const errorFormat = options.errorFormat;
242
+ exitWithError(createError(ErrorCode.REGION_NOT_FOUND, `Invalid region '${region}'`, { region, availableRegions: regions.map((r) => r.region) }, [`Use one of: ${regions.map((r) => r.region).join(', ')}`]), logger, errorFormat ?? 'text');
243
+ }
244
+ return region;
245
+ }
246
+ // Auto-select if only one region available
247
+ if (regions.length === 1) {
248
+ region = regions[0].region;
249
+ if (!process.stdin.isTTY) {
250
+ logger.trace('auto-selected region (non-TTY): %s', region);
251
+ }
252
+ return region;
253
+ }
254
+ // No flag provided - handle TTY vs non-TTY
255
+ if (required && !process.stdin.isTTY) {
256
+ const errorFormat = options.errorFormat;
257
+ exitWithError(createError(ErrorCode.REGION_REQUIRED, '--region flag is required in non-interactive mode', { availableRegions: regions.map((r) => r.region) }, [`Use --region with one of: ${regions.map((r) => r.region).join(', ')}`]), logger, errorFormat ?? 'text');
258
+ }
259
+ if (process.stdin.isTTY) {
260
+ // Interactive mode - prompt user
261
+ region = await getRegion(regions);
262
+ return region;
263
+ }
264
+ // Non-interactive, optional region - return undefined
265
+ return undefined;
266
+ }
267
+ async function registerSubcommand(parent, subcommand, baseCtx, hidden) {
268
+ const cmd = parent.command(subcommand.name, { hidden }).description(subcommand.description);
269
+ if (subcommand.aliases) {
270
+ cmd.aliases(subcommand.aliases);
271
+ }
272
+ // Add examples to help text
273
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
274
+ const examples = subcommand.examples;
275
+ if (examples && examples.length > 0) {
276
+ cmd.addHelpText('after', '\nExamples:\n' + examples.map((ex) => ` ${ex}`).join('\n'));
277
+ }
278
+ // Check if this subcommand has its own subcommands (nested subcommands)
279
+ const subDef = subcommand;
280
+ if (subDef.subcommands && subDef.subcommands.length > 0) {
281
+ // Register nested subcommands recursively
282
+ for (const nestedSub of subDef.subcommands) {
283
+ await registerSubcommand(cmd, nestedSub, baseCtx);
284
+ }
285
+ return;
286
+ }
287
+ const { requiresProject, optionalProject, requiresOrg, optionalOrg, requiresRegion, optionalRegion, } = normalizeReqs(subcommand);
288
+ if (requiresProject || optionalProject) {
289
+ cmd.option('--dir <path>', 'project directory (default: current directory)');
290
+ }
291
+ if (requiresOrg || optionalOrg) {
292
+ cmd.option('--org-id <id>', 'organization ID');
293
+ }
294
+ if (requiresRegion || optionalRegion) {
295
+ cmd.option('--region <region>', 'cloud region');
296
+ }
297
+ if (subcommand.schema?.args) {
298
+ const parsed = parseArgsSchema(subcommand.schema.args);
299
+ for (const argMeta of parsed.metadata) {
300
+ let argSyntax;
301
+ if (argMeta.variadic) {
302
+ argSyntax = argMeta.optional ? `[${argMeta.name}...]` : `<${argMeta.name}...>`;
303
+ }
304
+ else {
305
+ argSyntax = argMeta.optional ? `[${argMeta.name}]` : `<${argMeta.name}>`;
306
+ }
307
+ cmd.argument(argSyntax);
308
+ }
309
+ }
310
+ if (subcommand.schema?.options) {
311
+ const parsed = parseOptionsSchema(subcommand.schema.options);
312
+ for (const opt of parsed) {
313
+ const flag = opt.name.replace(/([A-Z])/g, '-$1').toLowerCase();
314
+ const desc = opt.description || '';
315
+ // Add short flag alias for verbose
316
+ const flagSpec = flag === 'verbose' ? `-v, --${flag}` : `--${flag}`;
317
+ if (opt.type === 'boolean') {
318
+ if (opt.hasDefault) {
319
+ const defaultValue = typeof opt.defaultValue === 'function' ? opt.defaultValue() : opt.defaultValue;
320
+ cmd.option(`--no-${flag}`, desc);
321
+ cmd.option(flagSpec, desc, defaultValue);
322
+ }
323
+ else {
324
+ cmd.option(flagSpec, desc);
325
+ }
326
+ }
327
+ else if (opt.type === 'number') {
328
+ cmd.option(`${flagSpec} <${opt.name}>`, desc, parseFloat);
329
+ }
330
+ else {
331
+ cmd.option(`${flagSpec} <${opt.name}>`, desc);
332
+ }
333
+ }
334
+ }
335
+ cmd.action(async (...rawArgs) => {
336
+ const cmdObj = rawArgs[rawArgs.length - 1];
337
+ const options = cmdObj.opts();
338
+ const args = rawArgs.slice(0, -1);
339
+ if (subcommand.banner) {
340
+ showBanner();
341
+ }
342
+ const normalized = normalizeReqs(subcommand);
343
+ let project;
344
+ let projectDir;
345
+ const dirNeeded = normalized.requiresProject || normalized.optionalProject;
346
+ if (dirNeeded) {
347
+ const dir = options.dir ?? process.cwd();
348
+ projectDir = dir;
349
+ try {
350
+ project = await loadProjectConfig(dir, baseCtx.config);
351
+ }
352
+ catch (error) {
353
+ if (normalized.requiresProject) {
354
+ if (error &&
355
+ typeof error === 'object' &&
356
+ 'name' in error &&
357
+ error.name === 'ProjectConfigNotFoundExpection') {
358
+ exitWithError(createError(ErrorCode.PROJECT_NOT_FOUND, 'Invalid project folder', undefined, [
359
+ 'Use --dir to specify a different directory',
360
+ 'Change to a directory containing agentuity.json',
361
+ `Run "${getCommand('project create')}" to create a new project`,
362
+ ]), baseCtx.logger, baseCtx.options.errorFormat);
363
+ }
364
+ throw error;
365
+ }
366
+ // For optional projects, silently continue without project config
367
+ }
368
+ }
369
+ if (normalized.requiresAuth) {
370
+ // Create apiClient before requireAuth since login command needs it
371
+ if (normalized.requiresAPIClient) {
372
+ baseCtx.apiClient = createAPIClient(baseCtx, baseCtx.config ?? null);
373
+ }
374
+ const auth = await requireAuth(baseCtx);
375
+ if (subcommand.schema) {
376
+ try {
377
+ const input = buildValidationInput(subcommand.schema, args, options);
378
+ const ctx = {
379
+ ...baseCtx,
380
+ config: {
381
+ ...(baseCtx.config ?? {}),
382
+ auth: {
383
+ api_key: auth.apiKey,
384
+ user_id: auth.userId,
385
+ expires: auth.expires.getTime(),
386
+ },
387
+ },
388
+ auth,
389
+ };
390
+ if (project || projectDir) {
391
+ if (project) {
392
+ ctx.project = project;
393
+ }
394
+ ctx.projectDir = projectDir;
395
+ }
396
+ if (subcommand.schema.args) {
397
+ ctx.args = subcommand.schema.args.parse(input.args);
398
+ }
399
+ if (subcommand.schema.options) {
400
+ ctx.opts = subcommand.schema.options.parse(input.options);
401
+ }
402
+ if (normalized.requiresAPIClient) {
403
+ // Recreate apiClient with auth credentials
404
+ ctx.apiClient = createAPIClient(baseCtx, ctx.config);
405
+ }
406
+ if (normalized.requiresOrg) {
407
+ ctx.orgId = await requireOrg(ctx);
408
+ }
409
+ if (normalized.optionalOrg && ctx.auth) {
410
+ ctx.orgId = await requireOrg(ctx);
411
+ }
412
+ if ((normalized.requiresRegion || normalized.optionalRegion) && ctx.apiClient) {
413
+ const apiClient = ctx.apiClient;
414
+ const region = await tui.spinner({
415
+ message: 'Fetching cloud regions',
416
+ clearOnSuccess: true,
417
+ callback: async () => {
418
+ return resolveRegion({
419
+ options: options,
420
+ apiClient,
421
+ logger: baseCtx.logger,
422
+ required: !!normalized.requiresRegion,
423
+ });
424
+ },
425
+ });
426
+ if (region) {
427
+ ctx.region = region;
428
+ }
429
+ }
430
+ await executeOrValidate(ctx, `${parent.name()} ${subcommand.name}`, subcommand.handler);
431
+ }
432
+ catch (error) {
433
+ if (error && typeof error === 'object' && 'issues' in error) {
434
+ handleValidationError(error, `${parent.name()} ${subcommand.name}`, baseCtx);
435
+ }
436
+ handleProjectConfigError(error, normalized.requiresProject, baseCtx.logger, baseCtx.options.errorFormat);
437
+ }
438
+ }
439
+ else {
440
+ const ctx = {
441
+ ...baseCtx,
442
+ config: baseCtx.config
443
+ ? {
444
+ ...baseCtx.config,
445
+ name: baseCtx.config.name ?? defaultProfileName,
446
+ auth: {
447
+ api_key: auth.apiKey,
448
+ user_id: auth.userId,
449
+ expires: auth.expires.getTime(),
450
+ },
451
+ }
452
+ : null,
453
+ auth,
454
+ };
455
+ if (project || projectDir) {
456
+ if (project) {
457
+ ctx.project = project;
458
+ }
459
+ ctx.projectDir = projectDir;
460
+ }
461
+ if (normalized.requiresAPIClient) {
462
+ // Recreate apiClient with auth credentials
463
+ ctx.apiClient = createAPIClient(baseCtx, ctx.config);
464
+ }
465
+ if (normalized.requiresOrg) {
466
+ ctx.orgId = await requireOrg(ctx);
467
+ }
468
+ if (normalized.optionalOrg && ctx.auth) {
469
+ ctx.orgId = await requireOrg(ctx);
470
+ }
471
+ if ((normalized.requiresRegion || normalized.optionalRegion) && ctx.apiClient) {
472
+ const apiClient = ctx.apiClient;
473
+ const region = await tui.spinner('Fetching cloud regions', async () => {
474
+ return resolveRegion({
475
+ options: options,
476
+ apiClient,
477
+ logger: baseCtx.logger,
478
+ required: !!normalized.requiresRegion,
479
+ });
480
+ });
481
+ if (region) {
482
+ ctx.region = region;
483
+ }
484
+ }
485
+ if (subcommand.handler) {
486
+ await subcommand.handler(ctx);
487
+ }
488
+ }
489
+ }
490
+ else if (normalized.optionalAuth) {
491
+ const continueText = typeof normalized.optionalAuth === 'string' ? normalized.optionalAuth : undefined;
492
+ // Create apiClient before optionalAuth since login command needs it
493
+ if (normalized.requiresAPIClient) {
494
+ baseCtx.apiClient = createAPIClient(baseCtx, baseCtx.config ?? null);
495
+ }
496
+ const auth = await optionalAuth(baseCtx, continueText);
497
+ if (subcommand.schema) {
498
+ try {
499
+ const input = buildValidationInput(subcommand.schema, args, options);
500
+ const ctx = {
501
+ ...baseCtx,
502
+ config: auth
503
+ ? {
504
+ ...(baseCtx.config ?? {}),
505
+ auth: {
506
+ api_key: auth.apiKey,
507
+ user_id: auth.userId,
508
+ expires: auth.expires.getTime(),
509
+ },
510
+ }
511
+ : baseCtx.config,
512
+ auth,
513
+ };
514
+ if (project || projectDir) {
515
+ if (project) {
516
+ ctx.project = project;
517
+ }
518
+ ctx.projectDir = projectDir;
519
+ }
520
+ if (subcommand.schema.args) {
521
+ ctx.args = subcommand.schema.args.parse(input.args);
522
+ }
523
+ if (subcommand.schema.options) {
524
+ ctx.opts = subcommand.schema.options.parse(input.options);
525
+ }
526
+ if (normalized.requiresAPIClient) {
527
+ // Recreate apiClient with auth credentials
528
+ ctx.apiClient = createAPIClient(baseCtx, ctx.config);
529
+ }
530
+ baseCtx.logger.trace('optionalAuth path: org=%s, region=%s, hasApiClient=%s, hasAuth=%s', normalized.optionalOrg, normalized.optionalRegion, !!ctx.apiClient, !!auth);
531
+ if (normalized.requiresOrg && ctx.apiClient) {
532
+ ctx.orgId = await requireOrg(ctx);
533
+ }
534
+ if (normalized.optionalOrg && ctx.apiClient && auth) {
535
+ ctx.orgId = await selectOptionalOrg(ctx);
536
+ baseCtx.logger.trace('selected orgId: %s', ctx.orgId);
537
+ }
538
+ if ((normalized.requiresRegion || normalized.optionalRegion) &&
539
+ ctx.apiClient &&
540
+ auth) {
541
+ const apiClient = ctx.apiClient;
542
+ const region = await resolveRegion({
543
+ options: options,
544
+ apiClient,
545
+ logger: baseCtx.logger,
546
+ required: !!normalized.requiresRegion,
547
+ });
548
+ if (region) {
549
+ ctx.region = region;
550
+ }
551
+ }
552
+ await executeOrValidate(ctx, `${parent.name()} ${subcommand.name}`, subcommand.handler);
553
+ }
554
+ catch (error) {
555
+ if (error && typeof error === 'object' && 'issues' in error) {
556
+ handleValidationError(error, `${parent.name()} ${subcommand.name}`, baseCtx);
557
+ }
558
+ handleProjectConfigError(error, normalized.requiresProject, baseCtx.logger, baseCtx.options.errorFormat);
559
+ }
560
+ }
561
+ else {
562
+ const ctx = {
563
+ ...baseCtx,
564
+ config: auth
565
+ ? {
566
+ ...(baseCtx.config ?? {}),
567
+ auth: {
568
+ api_key: auth.apiKey,
569
+ user_id: auth.userId,
570
+ expires: auth.expires.getTime(),
571
+ },
572
+ }
573
+ : baseCtx.config,
574
+ auth,
575
+ };
576
+ if (project || projectDir) {
577
+ if (project) {
578
+ ctx.project = project;
579
+ }
580
+ ctx.projectDir = projectDir;
581
+ }
582
+ if (normalized.requiresAPIClient) {
583
+ // Recreate apiClient with auth credentials if auth was provided
584
+ ctx.apiClient = createAPIClient(baseCtx, ctx.config);
585
+ }
586
+ if (normalized.requiresOrg && ctx.apiClient) {
587
+ ctx.orgId = await requireOrg(ctx);
588
+ }
589
+ if (normalized.optionalOrg && ctx.apiClient) {
590
+ ctx.orgId = await selectOptionalOrg(ctx);
591
+ }
592
+ if ((normalized.requiresRegion || normalized.optionalRegion) && ctx.apiClient) {
593
+ const apiClient = ctx.apiClient;
594
+ const region = await resolveRegion({
595
+ options: options,
596
+ apiClient,
597
+ logger: baseCtx.logger,
598
+ required: !!normalized.requiresRegion,
599
+ });
600
+ if (region) {
601
+ ctx.region = region;
602
+ }
603
+ }
604
+ if (subcommand.handler) {
605
+ await subcommand.handler(ctx);
606
+ }
607
+ }
608
+ }
609
+ else {
610
+ if (subcommand.schema) {
611
+ try {
612
+ const input = buildValidationInput(subcommand.schema, args, options);
613
+ const ctx = {
614
+ ...baseCtx,
615
+ };
616
+ if (project || projectDir) {
617
+ if (project) {
618
+ ctx.project = project;
619
+ }
620
+ ctx.projectDir = projectDir;
621
+ }
622
+ if (subcommand.schema.args) {
623
+ ctx.args = subcommand.schema.args.parse(input.args);
624
+ }
625
+ if (subcommand.schema.options) {
626
+ ctx.opts = subcommand.schema.options.parse(input.options);
627
+ }
628
+ if (normalized.requiresAPIClient && !ctx.apiClient) {
629
+ ctx.apiClient = createAPIClient(baseCtx, ctx.config);
630
+ }
631
+ if (normalized.requiresOrg && ctx.apiClient) {
632
+ ctx.orgId = await requireOrg(ctx);
633
+ }
634
+ if (normalized.optionalOrg && ctx.apiClient && ctx.auth) {
635
+ ctx.orgId = await requireOrg(ctx);
636
+ }
637
+ await executeOrValidate(ctx, `${parent.name()} ${subcommand.name}`, subcommand.handler);
638
+ }
639
+ catch (error) {
640
+ if (error && typeof error === 'object' && 'issues' in error) {
641
+ handleValidationError(error, `${parent.name()} ${subcommand.name}`, baseCtx);
642
+ }
643
+ handleProjectConfigError(error, normalized.requiresProject, baseCtx.logger, baseCtx.options.errorFormat);
644
+ }
645
+ }
646
+ else {
647
+ const ctx = {
648
+ ...baseCtx,
649
+ };
650
+ if (project || projectDir) {
651
+ if (project) {
652
+ ctx.project = project;
653
+ }
654
+ ctx.projectDir = projectDir;
655
+ }
656
+ if (normalized.requiresAPIClient && !ctx.apiClient) {
657
+ ctx.apiClient = createAPIClient(baseCtx, ctx.config);
658
+ }
659
+ if (normalized.requiresOrg && ctx.apiClient) {
660
+ ctx.orgId = await requireOrg(ctx);
661
+ }
662
+ if (normalized.optionalOrg && ctx.apiClient && ctx.auth) {
663
+ ctx.orgId = await requireOrg(ctx);
664
+ }
665
+ if ((normalized.requiresRegion || normalized.optionalRegion) && ctx.apiClient) {
666
+ const apiClient = ctx.apiClient;
667
+ const region = await resolveRegion({
668
+ options: options,
669
+ apiClient,
670
+ logger: baseCtx.logger,
671
+ required: !!normalized.requiresRegion,
672
+ });
673
+ if (region) {
674
+ ctx.region = region;
675
+ }
676
+ }
677
+ if (subcommand.handler) {
678
+ await subcommand.handler(ctx);
679
+ }
680
+ }
681
+ }
682
+ });
683
+ }
684
+ export async function registerCommands(program, commands, baseCtx) {
685
+ for (const cmdDef of commands) {
686
+ if (cmdDef.subcommands) {
687
+ const cmd = program
688
+ .command(cmdDef.name, { hidden: cmdDef.hidden })
689
+ .description(cmdDef.description);
690
+ if (cmdDef.aliases) {
691
+ cmd.aliases(cmdDef.aliases);
692
+ }
693
+ if (cmdDef.handler) {
694
+ cmd.action(async () => {
695
+ if (cmdDef.banner) {
696
+ showBanner();
697
+ }
698
+ const normalized = normalizeReqs(cmdDef);
699
+ if (normalized.requiresAuth) {
700
+ // Create apiClient before requireAuth since login command needs it
701
+ if (normalized.requiresAPIClient) {
702
+ baseCtx.apiClient = createAPIClient(baseCtx, baseCtx.config ?? null);
703
+ }
704
+ const auth = await requireAuth(baseCtx);
705
+ const ctx = {
706
+ ...baseCtx,
707
+ config: baseCtx.config
708
+ ? {
709
+ ...baseCtx.config,
710
+ name: baseCtx.config.name ?? defaultProfileName,
711
+ auth: {
712
+ api_key: auth.apiKey,
713
+ user_id: auth.userId,
714
+ expires: auth.expires.getTime(),
715
+ },
716
+ }
717
+ : null,
718
+ auth,
719
+ };
720
+ if (normalized.requiresAPIClient) {
721
+ // Recreate apiClient with auth credentials
722
+ ctx.apiClient = createAPIClient(baseCtx, ctx.config);
723
+ }
724
+ if ((normalized.requiresRegion || normalized.optionalRegion) && ctx.apiClient) {
725
+ const apiClient = ctx.apiClient;
726
+ const region = await resolveRegion({
727
+ options: baseCtx.options,
728
+ apiClient,
729
+ logger: baseCtx.logger,
730
+ required: !!normalized.requiresRegion,
731
+ });
732
+ if (region) {
733
+ ctx.region = region;
734
+ }
735
+ }
736
+ await cmdDef.handler(ctx);
737
+ }
738
+ else if (normalized.optionalAuth) {
739
+ const continueText = typeof normalized.optionalAuth === 'string'
740
+ ? normalized.optionalAuth
741
+ : undefined;
742
+ // Create apiClient before optionalAuth since login command needs it
743
+ if (normalized.requiresAPIClient) {
744
+ baseCtx.apiClient = createAPIClient(baseCtx, baseCtx.config ?? null);
745
+ }
746
+ const auth = await optionalAuth(baseCtx, continueText);
747
+ const ctx = {
748
+ ...baseCtx,
749
+ config: auth
750
+ ? baseCtx.config
751
+ ? {
752
+ ...baseCtx.config,
753
+ auth: {
754
+ api_key: auth.apiKey,
755
+ user_id: auth.userId,
756
+ expires: auth.expires.getTime(),
757
+ },
758
+ }
759
+ : {
760
+ auth: {
761
+ api_key: auth.apiKey,
762
+ user_id: auth.userId,
763
+ expires: auth.expires.getTime(),
764
+ },
765
+ }
766
+ : baseCtx.config,
767
+ auth,
768
+ };
769
+ if (normalized.requiresAPIClient) {
770
+ // Recreate apiClient with auth credentials if auth was provided
771
+ ctx.apiClient = createAPIClient(baseCtx, ctx.config);
772
+ }
773
+ if ((normalized.requiresRegion || normalized.optionalRegion) && ctx.apiClient) {
774
+ const apiClient = ctx.apiClient;
775
+ const region = await resolveRegion({
776
+ options: baseCtx.options,
777
+ apiClient,
778
+ logger: baseCtx.logger,
779
+ required: !!normalized.requiresRegion,
780
+ });
781
+ if (region) {
782
+ ctx.region = region;
783
+ }
784
+ }
785
+ await cmdDef.handler(ctx);
786
+ }
787
+ else {
788
+ const ctx = {
789
+ ...baseCtx,
790
+ };
791
+ if (normalized.requiresAPIClient && !ctx.apiClient) {
792
+ ctx.apiClient = createAPIClient(baseCtx, baseCtx.config);
793
+ }
794
+ if ((normalized.requiresRegion || normalized.optionalRegion) && ctx.apiClient) {
795
+ const apiClient = ctx.apiClient;
796
+ const region = await resolveRegion({
797
+ options: baseCtx.options,
798
+ apiClient,
799
+ logger: baseCtx.logger,
800
+ required: !!normalized.requiresRegion,
801
+ });
802
+ if (region) {
803
+ ctx.region = region;
804
+ }
805
+ }
806
+ await cmdDef.handler(ctx);
807
+ }
808
+ });
809
+ }
810
+ else {
811
+ cmd.action(() => cmd.help());
812
+ }
813
+ for (const sub of cmdDef.subcommands) {
814
+ await registerSubcommand(cmd, sub, baseCtx);
815
+ }
816
+ }
817
+ else {
818
+ await registerSubcommand(program, cmdDef, baseCtx, cmdDef.hidden);
819
+ }
820
+ }
821
+ }
822
+ //# sourceMappingURL=cli.js.map