@agentuity/cli 0.0.95 → 0.0.96

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 (267) hide show
  1. package/AGENTS.md +54 -0
  2. package/dist/auth.d.ts +1 -1
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +8 -5
  5. package/dist/auth.js.map +1 -1
  6. package/dist/cli.d.ts.map +1 -1
  7. package/dist/cli.js +190 -27
  8. package/dist/cli.js.map +1 -1
  9. package/dist/cmd/build/entry-generator.d.ts +20 -0
  10. package/dist/cmd/build/entry-generator.d.ts.map +1 -0
  11. package/dist/cmd/build/entry-generator.js +366 -0
  12. package/dist/cmd/build/entry-generator.js.map +1 -0
  13. package/dist/cmd/build/index.d.ts.map +1 -1
  14. package/dist/cmd/build/index.js +5 -23
  15. package/dist/cmd/build/index.js.map +1 -1
  16. package/dist/cmd/build/vite/agent-discovery.d.ts +33 -0
  17. package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -0
  18. package/dist/cmd/build/vite/agent-discovery.js +297 -0
  19. package/dist/cmd/build/vite/agent-discovery.js.map +1 -0
  20. package/dist/cmd/build/vite/browser-env-plugin.d.ts +9 -0
  21. package/dist/cmd/build/vite/browser-env-plugin.d.ts.map +1 -0
  22. package/dist/cmd/build/vite/browser-env-plugin.js +28 -0
  23. package/dist/cmd/build/vite/browser-env-plugin.js.map +1 -0
  24. package/dist/cmd/build/vite/bun-dev-server.d.ts +29 -0
  25. package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -0
  26. package/dist/cmd/build/vite/bun-dev-server.js +54 -0
  27. package/dist/cmd/build/vite/bun-dev-server.js.map +1 -0
  28. package/dist/cmd/build/vite/config-loader.d.ts +23 -0
  29. package/dist/cmd/build/vite/config-loader.d.ts.map +1 -0
  30. package/dist/cmd/build/vite/config-loader.js +50 -0
  31. package/dist/cmd/build/vite/config-loader.js.map +1 -0
  32. package/dist/cmd/build/vite/index.d.ts +26 -0
  33. package/dist/cmd/build/vite/index.d.ts.map +1 -0
  34. package/dist/cmd/build/vite/index.js +127 -0
  35. package/dist/cmd/build/vite/index.js.map +1 -0
  36. package/dist/cmd/build/vite/lifecycle-generator.d.ts +11 -0
  37. package/dist/cmd/build/vite/lifecycle-generator.d.ts.map +1 -0
  38. package/dist/cmd/build/vite/lifecycle-generator.js +35 -0
  39. package/dist/cmd/build/vite/lifecycle-generator.js.map +1 -0
  40. package/dist/cmd/build/vite/metadata-generator.d.ts +32 -0
  41. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -0
  42. package/dist/cmd/build/vite/metadata-generator.js +489 -0
  43. package/dist/cmd/build/vite/metadata-generator.js.map +1 -0
  44. package/dist/cmd/build/vite/patch-plugin.d.ts +21 -0
  45. package/dist/cmd/build/vite/patch-plugin.d.ts.map +1 -0
  46. package/dist/cmd/build/vite/patch-plugin.js +70 -0
  47. package/dist/cmd/build/vite/patch-plugin.js.map +1 -0
  48. package/dist/cmd/build/vite/registry-generator.d.ts +19 -0
  49. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -0
  50. package/dist/cmd/build/{route-registry.js → vite/registry-generator.js} +126 -48
  51. package/dist/cmd/build/vite/registry-generator.js.map +1 -0
  52. package/dist/cmd/build/vite/route-discovery.d.ts +58 -0
  53. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -0
  54. package/dist/cmd/build/vite/route-discovery.js +125 -0
  55. package/dist/cmd/build/vite/route-discovery.js.map +1 -0
  56. package/dist/cmd/build/vite/server-bundler.d.ts +16 -0
  57. package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -0
  58. package/dist/cmd/build/vite/server-bundler.js +194 -0
  59. package/dist/cmd/build/vite/server-bundler.js.map +1 -0
  60. package/dist/cmd/build/vite/vite-asset-server-config.d.ts +19 -0
  61. package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -0
  62. package/dist/cmd/build/vite/vite-asset-server-config.js +105 -0
  63. package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -0
  64. package/dist/cmd/build/vite/vite-asset-server.d.ts +23 -0
  65. package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -0
  66. package/dist/cmd/build/vite/vite-asset-server.js +40 -0
  67. package/dist/cmd/build/vite/vite-asset-server.js.map +1 -0
  68. package/dist/cmd/build/vite/vite-builder.d.ts +44 -0
  69. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -0
  70. package/dist/cmd/build/vite/vite-builder.js +232 -0
  71. package/dist/cmd/build/vite/vite-builder.js.map +1 -0
  72. package/dist/cmd/build/vite/workbench-generator.d.ts +10 -0
  73. package/dist/cmd/build/vite/workbench-generator.d.ts.map +1 -0
  74. package/dist/cmd/build/vite/workbench-generator.js +135 -0
  75. package/dist/cmd/build/vite/workbench-generator.js.map +1 -0
  76. package/dist/cmd/build/vite-bundler.d.ts +23 -0
  77. package/dist/cmd/build/vite-bundler.d.ts.map +1 -0
  78. package/dist/cmd/build/vite-bundler.js +79 -0
  79. package/dist/cmd/build/vite-bundler.js.map +1 -0
  80. package/dist/cmd/cloud/agent/get.d.ts.map +1 -1
  81. package/dist/cmd/cloud/agent/get.js +1 -0
  82. package/dist/cmd/cloud/agent/get.js.map +1 -1
  83. package/dist/cmd/cloud/agent/list.d.ts.map +1 -1
  84. package/dist/cmd/cloud/agent/list.js +1 -0
  85. package/dist/cmd/cloud/agent/list.js.map +1 -1
  86. package/dist/cmd/cloud/db/get.d.ts.map +1 -1
  87. package/dist/cmd/cloud/db/get.js +1 -0
  88. package/dist/cmd/cloud/db/get.js.map +1 -1
  89. package/dist/cmd/cloud/db/list.d.ts.map +1 -1
  90. package/dist/cmd/cloud/db/list.js +1 -0
  91. package/dist/cmd/cloud/db/list.js.map +1 -1
  92. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  93. package/dist/cmd/cloud/deploy.js +152 -128
  94. package/dist/cmd/cloud/deploy.js.map +1 -1
  95. package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
  96. package/dist/cmd/cloud/deployment/list.js +4 -0
  97. package/dist/cmd/cloud/deployment/list.js.map +1 -1
  98. package/dist/cmd/cloud/env/list.d.ts.map +1 -1
  99. package/dist/cmd/cloud/env/list.js +1 -0
  100. package/dist/cmd/cloud/env/list.js.map +1 -1
  101. package/dist/cmd/cloud/keyvalue/get.d.ts.map +1 -1
  102. package/dist/cmd/cloud/keyvalue/get.js +1 -0
  103. package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
  104. package/dist/cmd/cloud/keyvalue/keys.d.ts.map +1 -1
  105. package/dist/cmd/cloud/keyvalue/keys.js +1 -0
  106. package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
  107. package/dist/cmd/cloud/keyvalue/list-namespaces.d.ts.map +1 -1
  108. package/dist/cmd/cloud/keyvalue/list-namespaces.js +1 -0
  109. package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
  110. package/dist/cmd/cloud/keyvalue/stats.d.ts.map +1 -1
  111. package/dist/cmd/cloud/keyvalue/stats.js +1 -0
  112. package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
  113. package/dist/cmd/cloud/secret/list.d.ts.map +1 -1
  114. package/dist/cmd/cloud/secret/list.js +1 -0
  115. package/dist/cmd/cloud/secret/list.js.map +1 -1
  116. package/dist/cmd/cloud/session/list.d.ts.map +1 -1
  117. package/dist/cmd/cloud/session/list.js +4 -0
  118. package/dist/cmd/cloud/session/list.js.map +1 -1
  119. package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
  120. package/dist/cmd/cloud/storage/get.js +1 -0
  121. package/dist/cmd/cloud/storage/get.js.map +1 -1
  122. package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
  123. package/dist/cmd/cloud/storage/list.js +3 -0
  124. package/dist/cmd/cloud/storage/list.js.map +1 -1
  125. package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
  126. package/dist/cmd/cloud/stream/get.js +1 -0
  127. package/dist/cmd/cloud/stream/get.js.map +1 -1
  128. package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
  129. package/dist/cmd/cloud/stream/list.js +1 -0
  130. package/dist/cmd/cloud/stream/list.js.map +1 -1
  131. package/dist/cmd/cloud/vector/get.d.ts.map +1 -1
  132. package/dist/cmd/cloud/vector/get.js +1 -0
  133. package/dist/cmd/cloud/vector/get.js.map +1 -1
  134. package/dist/cmd/cloud/vector/search.d.ts.map +1 -1
  135. package/dist/cmd/cloud/vector/search.js +1 -0
  136. package/dist/cmd/cloud/vector/search.js.map +1 -1
  137. package/dist/cmd/dev/index.d.ts.map +1 -1
  138. package/dist/cmd/dev/index.js +289 -758
  139. package/dist/cmd/dev/index.js.map +1 -1
  140. package/dist/cmd/dev/sync.d.ts +1 -1
  141. package/dist/cmd/dev/sync.d.ts.map +1 -1
  142. package/dist/cmd/dev/sync.js +3 -0
  143. package/dist/cmd/dev/sync.js.map +1 -1
  144. package/dist/cmd/profile/show.d.ts.map +1 -1
  145. package/dist/cmd/profile/show.js +3 -4
  146. package/dist/cmd/profile/show.js.map +1 -1
  147. package/dist/cmd/project/create.d.ts.map +1 -1
  148. package/dist/cmd/project/create.js +3 -4
  149. package/dist/cmd/project/create.js.map +1 -1
  150. package/dist/cmd/project/list.d.ts.map +1 -1
  151. package/dist/cmd/project/list.js +1 -0
  152. package/dist/cmd/project/list.js.map +1 -1
  153. package/dist/cmd/project/show.d.ts.map +1 -1
  154. package/dist/cmd/project/show.js +1 -0
  155. package/dist/cmd/project/show.js.map +1 -1
  156. package/dist/cmd/upgrade/index.d.ts.map +1 -1
  157. package/dist/cmd/upgrade/index.js +5 -3
  158. package/dist/cmd/upgrade/index.js.map +1 -1
  159. package/dist/config.d.ts +1 -1
  160. package/dist/config.d.ts.map +1 -1
  161. package/dist/config.js +29 -11
  162. package/dist/config.js.map +1 -1
  163. package/dist/index.d.ts +1 -1
  164. package/dist/index.d.ts.map +1 -1
  165. package/dist/index.js.map +1 -1
  166. package/dist/runtime-bootstrap.d.ts +3 -2
  167. package/dist/runtime-bootstrap.d.ts.map +1 -1
  168. package/dist/runtime-bootstrap.js +7 -2
  169. package/dist/runtime-bootstrap.js.map +1 -1
  170. package/dist/schemas/deploy.d.ts +1 -1
  171. package/dist/types.d.ts +40 -1
  172. package/dist/types.d.ts.map +1 -1
  173. package/dist/types.js.map +1 -1
  174. package/dist/utils/bun-version-checker.d.ts +11 -0
  175. package/dist/utils/bun-version-checker.d.ts.map +1 -0
  176. package/dist/utils/bun-version-checker.js +56 -0
  177. package/dist/utils/bun-version-checker.js.map +1 -0
  178. package/dist/version-check.d.ts.map +1 -1
  179. package/dist/version-check.js +5 -2
  180. package/dist/version-check.js.map +1 -1
  181. package/package.json +10 -3
  182. package/src/auth.ts +9 -5
  183. package/src/cli.ts +228 -29
  184. package/src/cmd/build/entry-generator.ts +404 -0
  185. package/src/cmd/build/index.ts +7 -28
  186. package/src/cmd/build/vite/agent-discovery.ts +467 -0
  187. package/src/cmd/build/vite/browser-env-plugin.ts +34 -0
  188. package/src/cmd/build/vite/bun-dev-server.ts +78 -0
  189. package/src/cmd/build/vite/config-loader.ts +70 -0
  190. package/src/cmd/build/vite/index.ts +166 -0
  191. package/src/cmd/build/vite/lifecycle-generator.ts +43 -0
  192. package/src/cmd/build/vite/metadata-generator.ts +602 -0
  193. package/src/cmd/build/vite/patch-plugin.ts +88 -0
  194. package/src/cmd/build/vite/registry-generator.ts +288 -0
  195. package/src/cmd/build/vite/route-discovery.ts +186 -0
  196. package/src/cmd/build/vite/server-bundler.ts +258 -0
  197. package/src/cmd/build/vite/vite-asset-server-config.ts +134 -0
  198. package/src/cmd/build/vite/vite-asset-server.ts +63 -0
  199. package/src/cmd/build/vite/vite-builder.ts +284 -0
  200. package/src/cmd/build/vite/workbench-generator.ts +152 -0
  201. package/src/cmd/build/vite-bundler.ts +110 -0
  202. package/src/cmd/cloud/agent/get.ts +2 -0
  203. package/src/cmd/cloud/agent/list.ts +1 -0
  204. package/src/cmd/cloud/db/get.ts +1 -0
  205. package/src/cmd/cloud/db/list.ts +1 -0
  206. package/src/cmd/cloud/deploy.ts +175 -144
  207. package/src/cmd/cloud/deployment/list.ts +4 -0
  208. package/src/cmd/cloud/env/list.ts +1 -0
  209. package/src/cmd/cloud/keyvalue/get.ts +1 -0
  210. package/src/cmd/cloud/keyvalue/keys.ts +1 -0
  211. package/src/cmd/cloud/keyvalue/list-namespaces.ts +1 -0
  212. package/src/cmd/cloud/keyvalue/stats.ts +2 -0
  213. package/src/cmd/cloud/secret/list.ts +1 -0
  214. package/src/cmd/cloud/session/list.ts +4 -0
  215. package/src/cmd/cloud/storage/get.ts +1 -0
  216. package/src/cmd/cloud/storage/list.ts +4 -0
  217. package/src/cmd/cloud/stream/get.ts +1 -0
  218. package/src/cmd/cloud/stream/list.ts +1 -0
  219. package/src/cmd/cloud/vector/get.ts +1 -0
  220. package/src/cmd/cloud/vector/search.ts +1 -0
  221. package/src/cmd/dev/index.ts +319 -921
  222. package/src/cmd/dev/sync.ts +5 -1
  223. package/src/cmd/profile/show.ts +3 -4
  224. package/src/cmd/project/create.ts +3 -4
  225. package/src/cmd/project/list.ts +1 -0
  226. package/src/cmd/project/show.ts +1 -0
  227. package/src/cmd/upgrade/index.ts +6 -3
  228. package/src/config.ts +31 -11
  229. package/src/index.ts +2 -0
  230. package/src/runtime-bootstrap.ts +8 -2
  231. package/src/types.ts +48 -1
  232. package/src/utils/bun-version-checker.ts +70 -0
  233. package/src/version-check.ts +6 -2
  234. package/dist/cmd/build/bundler.d.ts +0 -28
  235. package/dist/cmd/build/bundler.d.ts.map +0 -1
  236. package/dist/cmd/build/bundler.js +0 -800
  237. package/dist/cmd/build/bundler.js.map +0 -1
  238. package/dist/cmd/build/config-loader.d.ts +0 -16
  239. package/dist/cmd/build/config-loader.d.ts.map +0 -1
  240. package/dist/cmd/build/config-loader.js +0 -227
  241. package/dist/cmd/build/config-loader.js.map +0 -1
  242. package/dist/cmd/build/file.d.ts +0 -2
  243. package/dist/cmd/build/file.d.ts.map +0 -1
  244. package/dist/cmd/build/file.js +0 -10
  245. package/dist/cmd/build/file.js.map +0 -1
  246. package/dist/cmd/build/fix-duplicate-exports.d.ts +0 -2
  247. package/dist/cmd/build/fix-duplicate-exports.d.ts.map +0 -1
  248. package/dist/cmd/build/fix-duplicate-exports.js +0 -170
  249. package/dist/cmd/build/fix-duplicate-exports.js.map +0 -1
  250. package/dist/cmd/build/plugin.d.ts +0 -6
  251. package/dist/cmd/build/plugin.d.ts.map +0 -1
  252. package/dist/cmd/build/plugin.js +0 -645
  253. package/dist/cmd/build/plugin.js.map +0 -1
  254. package/dist/cmd/build/route-discovery.d.ts +0 -54
  255. package/dist/cmd/build/route-discovery.d.ts.map +0 -1
  256. package/dist/cmd/build/route-discovery.js +0 -148
  257. package/dist/cmd/build/route-discovery.js.map +0 -1
  258. package/dist/cmd/build/route-registry.d.ts +0 -38
  259. package/dist/cmd/build/route-registry.d.ts.map +0 -1
  260. package/dist/cmd/build/route-registry.js.map +0 -1
  261. package/src/cmd/build/bundler.ts +0 -965
  262. package/src/cmd/build/config-loader.ts +0 -268
  263. package/src/cmd/build/file.ts +0 -10
  264. package/src/cmd/build/fix-duplicate-exports.ts +0 -207
  265. package/src/cmd/build/plugin.ts +0 -782
  266. package/src/cmd/build/route-discovery.ts +0 -202
  267. package/src/cmd/build/route-registry.ts +0 -222
package/src/cli.ts CHANGED
@@ -20,7 +20,7 @@ import enquirer from 'enquirer';
20
20
  import * as tui from './tui';
21
21
  import { parseArgsSchema, parseOptionsSchema, buildValidationInput } from './schema-parser';
22
22
  import { defaultProfileName, loadProjectConfig } from './config';
23
- import { APIClient, getAPIBaseURL, type APIClient as APIClientType } from './api';
23
+ import { APIClient, getAPIBaseURL, getAppBaseURL, type APIClient as APIClientType } from './api';
24
24
  import { ErrorCode, ExitCode, createError, exitWithError } from './errors';
25
25
  import { getCommand } from './command-prefix';
26
26
  import { isValidateMode, outputValidation, type ValidationResult } from './output';
@@ -55,6 +55,38 @@ function createAPIClient(baseCtx: CommandContext, config: Config | null): APICli
55
55
  }
56
56
  }
57
57
 
58
+ type WebUrlSpec = string | ((ctx: CommandContext) => string | undefined | null);
59
+
60
+ function resolveWebUrl(ctx: CommandContext, spec?: WebUrlSpec): string | undefined {
61
+ if (!spec) return undefined;
62
+
63
+ const raw = typeof spec === 'function' ? spec(ctx) : spec;
64
+ if (!raw) return undefined;
65
+
66
+ if (raw.startsWith('http://') || raw.startsWith('https://')) {
67
+ return raw;
68
+ }
69
+
70
+ const appBase = getAppBaseURL(ctx.config ?? null).replace(/\/$/, '');
71
+ const path = raw.startsWith('/') ? raw : `/${raw}`;
72
+ return `${appBase}${path}`;
73
+ }
74
+
75
+ function maybeRenderWebLink(ctx: CommandContext, spec?: WebUrlSpec): void {
76
+ if (ctx.options.json) return;
77
+ if (isValidateMode(ctx.options)) return;
78
+
79
+ const url = resolveWebUrl(ctx, spec);
80
+ if (!url) return;
81
+
82
+ if (tui.supportsHyperlinks()) {
83
+ tui.output(tui.muted(`→ ${tui.link(url, 'View on the web', '')}`));
84
+ } else {
85
+ tui.output(tui.muted(`→ View on the web: ${url}`));
86
+ }
87
+ tui.newline();
88
+ }
89
+
58
90
  /**
59
91
  * Execute handler or output validation result based on mode
60
92
  */
@@ -62,7 +94,8 @@ async function executeOrValidate(
62
94
  ctx: CommandContext,
63
95
  commandName: string,
64
96
  handler?: (ctx: CommandContext) => unknown | Promise<unknown>,
65
- hasResponseSchema?: boolean
97
+ hasResponseSchema?: boolean,
98
+ webUrl?: WebUrlSpec
66
99
  ): Promise<void> {
67
100
  if (isValidateMode(ctx.options)) {
68
101
  // In validate mode, just output success (validation already passed via Zod)
@@ -72,6 +105,9 @@ async function executeOrValidate(
72
105
  };
73
106
  outputValidation(result, ctx.options);
74
107
  } else if (handler) {
108
+ // Render "View on the web" link before normal execution
109
+ maybeRenderWebLink(ctx, webUrl);
110
+
75
111
  // Normal execution
76
112
  const result = await handler(ctx);
77
113
 
@@ -225,6 +261,82 @@ function handleProjectConfigError(
225
261
  throw error;
226
262
  }
227
263
 
264
+ /**
265
+ * Prompt user to select a project from their available projects
266
+ */
267
+ async function promptProjectSelection(baseCtx: CommandContext): Promise<ProjectConfig | null> {
268
+ const { config } = baseCtx;
269
+
270
+ // Need auth and API client to fetch projects
271
+ const auth = await requireAuth(baseCtx);
272
+ if (!auth) {
273
+ return null;
274
+ }
275
+
276
+ const apiClient = createAPIClient(baseCtx, config);
277
+
278
+ // Fetch available projects
279
+ const { projectList } = await import('@agentuity/server');
280
+ const projects = await projectList(apiClient);
281
+
282
+ if (!projects || projects.length === 0) {
283
+ tui.warning('No projects found. Please create a project first.');
284
+ return null;
285
+ }
286
+
287
+ // Sort projects: prioritize those matching orgId in preferences
288
+ const preferredOrgId = config?.preferences?.orgId;
289
+ const sortedProjects = [...projects].sort((a, b) => {
290
+ // Prioritize preferred org
291
+ if (preferredOrgId) {
292
+ if (a.orgId === preferredOrgId && b.orgId !== preferredOrgId) return -1;
293
+ if (b.orgId === preferredOrgId && a.orgId !== preferredOrgId) return 1;
294
+ }
295
+ // Otherwise sort by name
296
+ return a.name.localeCompare(b.name);
297
+ });
298
+
299
+ // Build select options with aligned formatting
300
+ const { createPrompt } = tui;
301
+ const prompt = createPrompt();
302
+
303
+ // Calculate max name length for padding (with reasonable max)
304
+ const maxNameLength = Math.min(40, Math.max(...sortedProjects.map((p) => p.name.length)));
305
+
306
+ const selectedProjectId = await prompt.select<string>({
307
+ message: 'Select a project',
308
+ options: sortedProjects.map((p) => {
309
+ // Truncate and pad name for alignment
310
+ const displayName =
311
+ p.name.length > maxNameLength
312
+ ? p.name.substring(0, maxNameLength - 1) + '…'
313
+ : p.name.padEnd(maxNameLength);
314
+
315
+ return {
316
+ value: p.id,
317
+ label: `${displayName} ${tui.muted(p.id)}`,
318
+ };
319
+ }),
320
+ });
321
+
322
+ // Cleanup stdin after prompt to prevent hanging
323
+ if (process.stdin.isTTY) {
324
+ process.stdin.pause();
325
+ }
326
+
327
+ const selectedProject = sortedProjects.find((p) => p.id === selectedProjectId);
328
+ if (!selectedProject) {
329
+ return null;
330
+ }
331
+
332
+ // Convert to ProjectConfig format
333
+ return {
334
+ projectId: selectedProject.id,
335
+ orgId: selectedProject.orgId,
336
+ region: selectedProject.cloudRegion || '',
337
+ };
338
+ }
339
+
228
340
  export async function createCLI(version: string): Promise<Command> {
229
341
  const program = new Command();
230
342
 
@@ -370,11 +482,13 @@ export async function createCLI(version: string): Promise<Command> {
370
482
  // Format each section (show banner for root command)
371
483
  let output = '';
372
484
 
373
- // Show banner if this is the root command (no parent)
485
+ // Show banner (full for root, compact for subcommands)
374
486
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
375
487
  const isRootCommand = !(cmd as any).parent;
376
488
  if (isRootCommand) {
377
489
  output += `${generateBanner(version)}\n\n`;
490
+ } else {
491
+ output += `${generateBanner(version, true)}\n`;
378
492
  }
379
493
 
380
494
  // Description
@@ -610,6 +724,7 @@ async function registerSubcommand(
610
724
  cmd.help();
611
725
  });
612
726
 
727
+ // Don't add options to parent commands - only to leaf commands
613
728
  return;
614
729
  }
615
730
 
@@ -647,6 +762,9 @@ async function registerSubcommand(
647
762
  }
648
763
  }
649
764
 
765
+ // Track if projectId is defined in schema options
766
+ let hasProjectIdInSchema = false;
767
+
650
768
  if (subcommand.schema?.options) {
651
769
  const parsed = parseOptionsSchema(subcommand.schema.options);
652
770
  for (const opt of parsed) {
@@ -654,6 +772,12 @@ async function registerSubcommand(
654
772
  .replace(/([a-z0-9])([A-Z])/g, '$1-$2')
655
773
  .replace(/([A-Z]+)([A-Z][a-z])/g, '$1-$2')
656
774
  .toLowerCase();
775
+
776
+ // Track if this schema defines projectId (as 'projectId' or 'project-id')
777
+ if (opt.name === 'projectId' || opt.name === 'project-id' || flag === 'project-id') {
778
+ hasProjectIdInSchema = true;
779
+ }
780
+
657
781
  const desc = opt.description || '';
658
782
  // Add short flag alias for verbose
659
783
  const flagSpec = flag === 'verbose' ? `-v, --${flag}` : `--${flag}`;
@@ -710,6 +834,11 @@ async function registerSubcommand(
710
834
  }
711
835
  }
712
836
 
837
+ // Add --project-id if command requires/optional project and doesn't define it in schema
838
+ if ((requiresProject || optionalProject) && !hasProjectIdInSchema) {
839
+ cmd.option('--project-id <id>', 'project ID (alternative to --dir)');
840
+ }
841
+
713
842
  cmd.action(async (...rawArgs: unknown[]) => {
714
843
  const cmdObj = rawArgs[rawArgs.length - 1] as { opts: () => Record<string, unknown> };
715
844
  const options = cmdObj.opts();
@@ -726,35 +855,99 @@ async function registerSubcommand(
726
855
  const dirNeeded = normalized.requiresProject || normalized.optionalProject;
727
856
 
728
857
  if (dirNeeded) {
729
- const dir = (options.dir as string | undefined) ?? process.cwd();
730
- projectDir = dir;
731
- if (projectDir.startsWith('~/')) {
732
- projectDir = projectDir.replace('~/', homedir());
733
- }
734
- projectDir = resolve(projectDir);
735
- try {
736
- project = await loadProjectConfig(dir, baseCtx.config);
737
- } catch (error) {
738
- if (normalized.requiresProject) {
739
- if (
740
- error &&
741
- typeof error === 'object' &&
742
- 'name' in error &&
743
- error.name === 'ProjectConfigNotFoundExpection'
744
- ) {
858
+ const projectId = options.projectId as string | undefined;
859
+
860
+ // If --project-id is provided, fetch project details from API
861
+ if (projectId) {
862
+ try {
863
+ const auth = await requireAuth(baseCtx);
864
+ if (auth) {
865
+ const apiClient = createAPIClient(baseCtx, baseCtx.config);
866
+ const { projectGet } = await import('@agentuity/server');
867
+ const projectDetails = await projectGet(apiClient, { id: projectId, mask: true });
868
+ project = {
869
+ projectId: projectDetails.id,
870
+ orgId: projectDetails.orgId,
871
+ region: projectDetails.cloudRegion || '',
872
+ };
873
+ }
874
+ } catch (_error) {
875
+ if (normalized.requiresProject) {
745
876
  exitWithError(
746
- createError(ErrorCode.PROJECT_NOT_FOUND, 'Invalid project folder', undefined, [
747
- 'Use --dir to specify a different directory',
748
- 'Change to a directory containing agentuity.json',
749
- `Run "${getCommand('project create')}" to create a new project`,
750
- ]),
877
+ createError(
878
+ ErrorCode.PROJECT_NOT_FOUND,
879
+ `Project not found: ${projectId}`,
880
+ undefined,
881
+ [
882
+ 'Verify the project ID is correct',
883
+ `Run "${getCommand('project list')}" to see available projects`,
884
+ ]
885
+ ),
751
886
  baseCtx.logger,
752
887
  baseCtx.options.errorFormat
753
888
  );
754
889
  }
755
- throw error;
756
890
  }
757
- // For optional projects, silently continue without project config
891
+ } else {
892
+ // Try to load from directory
893
+ const dir = (options.dir as string | undefined) ?? process.cwd();
894
+ projectDir = dir;
895
+ if (projectDir.startsWith('~/')) {
896
+ projectDir = projectDir.replace('~/', homedir());
897
+ }
898
+ projectDir = resolve(projectDir);
899
+ try {
900
+ project = await loadProjectConfig(dir, baseCtx.config);
901
+ } catch (error) {
902
+ if (normalized.requiresProject) {
903
+ if (
904
+ error &&
905
+ typeof error === 'object' &&
906
+ 'name' in error &&
907
+ error.name === 'ProjectConfigNotFoundExpection'
908
+ ) {
909
+ // If TTY is available, prompt user to select a project
910
+ const hasTTY = process.stdin.isTTY && process.stdout.isTTY;
911
+
912
+ if (hasTTY) {
913
+ // Try to prompt for project selection
914
+ try {
915
+ const selectedProject = await promptProjectSelection(baseCtx);
916
+ if (selectedProject) {
917
+ // Set the project ID in options so it can be used by the command
918
+ (options as Record<string, unknown>).projectId =
919
+ selectedProject.projectId;
920
+ project = selectedProject;
921
+ }
922
+ } catch (promptError) {
923
+ // If prompting fails, fall through to the original error
924
+ baseCtx.logger.trace('Project selection prompt failed: %s', promptError);
925
+ }
926
+ }
927
+
928
+ if (!project) {
929
+ exitWithError(
930
+ createError(
931
+ ErrorCode.PROJECT_NOT_FOUND,
932
+ 'Invalid project folder',
933
+ undefined,
934
+ [
935
+ 'Use --dir to specify a different directory',
936
+ 'Use --project-id to specify a project by ID',
937
+ 'Change to a directory containing agentuity.json',
938
+ `Run "${getCommand('project create')}" to create a new project`,
939
+ ]
940
+ ),
941
+ baseCtx.logger,
942
+ baseCtx.options.errorFormat
943
+ );
944
+ }
945
+ } else {
946
+ throw error;
947
+ }
948
+ }
949
+ // For optional projects, silently continue without project config
950
+ }
758
951
  }
759
952
  }
760
953
 
@@ -833,7 +1026,8 @@ async function registerSubcommand(
833
1026
  ctx as CommandContext,
834
1027
  `${parent.name()} ${subcommand.name}`,
835
1028
  subcommand.handler,
836
- !!subcommand.schema?.response
1029
+ !!subcommand.schema?.response,
1030
+ subcommand.webUrl
837
1031
  );
838
1032
  } catch (error) {
839
1033
  if (error && typeof error === 'object' && 'issues' in error) {
@@ -896,6 +1090,7 @@ async function registerSubcommand(
896
1090
  }
897
1091
  }
898
1092
  if (subcommand.handler) {
1093
+ maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
899
1094
  const result = await subcommand.handler(ctx as CommandContext);
900
1095
 
901
1096
  // If --json flag is set
@@ -1010,7 +1205,8 @@ async function registerSubcommand(
1010
1205
  ctx as CommandContext,
1011
1206
  `${parent.name()} ${subcommand.name}`,
1012
1207
  subcommand.handler,
1013
- !!subcommand.schema?.response
1208
+ !!subcommand.schema?.response,
1209
+ subcommand.webUrl
1014
1210
  );
1015
1211
  } catch (error) {
1016
1212
  if (error && typeof error === 'object' && 'issues' in error) {
@@ -1069,6 +1265,7 @@ async function registerSubcommand(
1069
1265
  }
1070
1266
  }
1071
1267
  if (subcommand.handler) {
1268
+ maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
1072
1269
  const result = await subcommand.handler(ctx as CommandContext);
1073
1270
 
1074
1271
  // If --json flag is set
@@ -1133,7 +1330,8 @@ async function registerSubcommand(
1133
1330
  ctx as CommandContext,
1134
1331
  `${parent.name()} ${subcommand.name}`,
1135
1332
  subcommand.handler,
1136
- !!subcommand.schema?.response
1333
+ !!subcommand.schema?.response,
1334
+ subcommand.webUrl
1137
1335
  );
1138
1336
  } catch (error) {
1139
1337
  if (error && typeof error === 'object' && 'issues' in error) {
@@ -1179,6 +1377,7 @@ async function registerSubcommand(
1179
1377
  }
1180
1378
  }
1181
1379
  if (subcommand.handler) {
1380
+ maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
1182
1381
  const result = await subcommand.handler(ctx as CommandContext);
1183
1382
 
1184
1383
  // If --json flag is set