@agentuity/cli 1.0.1 → 1.0.3

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 (331) hide show
  1. package/AGENTS.md +40 -24
  2. package/bin/cli.ts +47 -22
  3. package/dist/agent-detection.d.ts +23 -38
  4. package/dist/agent-detection.d.ts.map +1 -1
  5. package/dist/agent-detection.js +412 -153
  6. package/dist/agent-detection.js.map +1 -1
  7. package/dist/ai-help.d.ts +23 -0
  8. package/dist/ai-help.d.ts.map +1 -0
  9. package/dist/ai-help.js +328 -0
  10. package/dist/ai-help.js.map +1 -0
  11. package/dist/api.js +1 -1
  12. package/dist/api.js.map +1 -1
  13. package/dist/auth.d.ts +10 -1
  14. package/dist/auth.d.ts.map +1 -1
  15. package/dist/auth.js +176 -16
  16. package/dist/auth.js.map +1 -1
  17. package/dist/banner.d.ts.map +1 -1
  18. package/dist/banner.js +5 -0
  19. package/dist/banner.js.map +1 -1
  20. package/dist/cache/agent-intro.d.ts +13 -0
  21. package/dist/cache/agent-intro.d.ts.map +1 -0
  22. package/dist/cache/agent-intro.js +54 -0
  23. package/dist/cache/agent-intro.js.map +1 -0
  24. package/dist/cache/index.d.ts +1 -0
  25. package/dist/cache/index.d.ts.map +1 -1
  26. package/dist/cache/index.js +1 -0
  27. package/dist/cache/index.js.map +1 -1
  28. package/dist/cache/resource-region.d.ts +3 -2
  29. package/dist/cache/resource-region.d.ts.map +1 -1
  30. package/dist/cache/resource-region.js +13 -4
  31. package/dist/cache/resource-region.js.map +1 -1
  32. package/dist/catalyst.d.ts +7 -0
  33. package/dist/catalyst.d.ts.map +1 -0
  34. package/dist/catalyst.js +15 -0
  35. package/dist/catalyst.js.map +1 -0
  36. package/dist/cli.d.ts +12 -1
  37. package/dist/cli.d.ts.map +1 -1
  38. package/dist/cli.js +290 -67
  39. package/dist/cli.js.map +1 -1
  40. package/dist/cmd/ai/detect.d.ts +3 -0
  41. package/dist/cmd/ai/detect.d.ts.map +1 -0
  42. package/dist/cmd/ai/detect.js +49 -0
  43. package/dist/cmd/ai/detect.js.map +1 -0
  44. package/dist/cmd/ai/index.d.ts.map +1 -1
  45. package/dist/cmd/ai/index.js +18 -1
  46. package/dist/cmd/ai/index.js.map +1 -1
  47. package/dist/cmd/ai/intro.d.ts +7 -0
  48. package/dist/cmd/ai/intro.d.ts.map +1 -0
  49. package/dist/cmd/ai/intro.js +141 -0
  50. package/dist/cmd/ai/intro.js.map +1 -0
  51. package/dist/cmd/ai/opencode/run.d.ts.map +1 -1
  52. package/dist/cmd/ai/opencode/run.js +5 -0
  53. package/dist/cmd/ai/opencode/run.js.map +1 -1
  54. package/dist/cmd/build/ast.d.ts.map +1 -1
  55. package/dist/cmd/build/ast.js +79 -0
  56. package/dist/cmd/build/ast.js.map +1 -1
  57. package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
  58. package/dist/cmd/build/vite/bun-dev-server.js +2 -0
  59. package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
  60. package/dist/cmd/build/vite/docs-generator.d.ts.map +1 -1
  61. package/dist/cmd/build/vite/docs-generator.js +15 -1
  62. package/dist/cmd/build/vite/docs-generator.js.map +1 -1
  63. package/dist/cmd/build/vite/env-types-generator.d.ts +26 -0
  64. package/dist/cmd/build/vite/env-types-generator.d.ts.map +1 -0
  65. package/dist/cmd/build/vite/env-types-generator.js +110 -0
  66. package/dist/cmd/build/vite/env-types-generator.js.map +1 -0
  67. package/dist/cmd/build/vite/index.d.ts +2 -0
  68. package/dist/cmd/build/vite/index.d.ts.map +1 -1
  69. package/dist/cmd/build/vite/index.js +12 -1
  70. package/dist/cmd/build/vite/index.js.map +1 -1
  71. package/dist/cmd/build/vite/public-asset-path-plugin.d.ts.map +1 -1
  72. package/dist/cmd/build/vite/public-asset-path-plugin.js.map +1 -1
  73. package/dist/cmd/build/vite/vite-builder.d.ts +2 -0
  74. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  75. package/dist/cmd/build/vite/vite-builder.js +10 -1
  76. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  77. package/dist/cmd/cloud/db/create.js.map +1 -1
  78. package/dist/cmd/cloud/db/delete.js.map +1 -1
  79. package/dist/cmd/cloud/db/get.d.ts.map +1 -1
  80. package/dist/cmd/cloud/db/get.js +27 -12
  81. package/dist/cmd/cloud/db/get.js.map +1 -1
  82. package/dist/cmd/cloud/deploy-fork.d.ts.map +1 -1
  83. package/dist/cmd/cloud/deploy-fork.js +2 -0
  84. package/dist/cmd/cloud/deploy-fork.js.map +1 -1
  85. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  86. package/dist/cmd/cloud/deploy.js +17 -0
  87. package/dist/cmd/cloud/deploy.js.map +1 -1
  88. package/dist/cmd/cloud/env/import.js.map +1 -1
  89. package/dist/cmd/cloud/env/list.js.map +1 -1
  90. package/dist/cmd/cloud/env/push.js.map +1 -1
  91. package/dist/cmd/cloud/keyvalue/util.d.ts.map +1 -1
  92. package/dist/cmd/cloud/keyvalue/util.js +3 -3
  93. package/dist/cmd/cloud/keyvalue/util.js.map +1 -1
  94. package/dist/cmd/cloud/machine/list.js +3 -3
  95. package/dist/cmd/cloud/machine/list.js.map +1 -1
  96. package/dist/cmd/cloud/region/index.js.map +1 -1
  97. package/dist/cmd/cloud/region-lookup.d.ts +7 -4
  98. package/dist/cmd/cloud/region-lookup.d.ts.map +1 -1
  99. package/dist/cmd/cloud/region-lookup.js +59 -14
  100. package/dist/cmd/cloud/region-lookup.js.map +1 -1
  101. package/dist/cmd/cloud/sandbox/cp.d.ts.map +1 -1
  102. package/dist/cmd/cloud/sandbox/cp.js +7 -5
  103. package/dist/cmd/cloud/sandbox/cp.js.map +1 -1
  104. package/dist/cmd/cloud/sandbox/create.js +2 -2
  105. package/dist/cmd/cloud/sandbox/create.js.map +1 -1
  106. package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
  107. package/dist/cmd/cloud/sandbox/delete.js +8 -7
  108. package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
  109. package/dist/cmd/cloud/sandbox/download.d.ts.map +1 -1
  110. package/dist/cmd/cloud/sandbox/download.js +7 -5
  111. package/dist/cmd/cloud/sandbox/download.js.map +1 -1
  112. package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -1
  113. package/dist/cmd/cloud/sandbox/env.js +7 -5
  114. package/dist/cmd/cloud/sandbox/env.js.map +1 -1
  115. package/dist/cmd/cloud/sandbox/exec.d.ts.map +1 -1
  116. package/dist/cmd/cloud/sandbox/exec.js +7 -5
  117. package/dist/cmd/cloud/sandbox/exec.js.map +1 -1
  118. package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
  119. package/dist/cmd/cloud/sandbox/get.js +12 -7
  120. package/dist/cmd/cloud/sandbox/get.js.map +1 -1
  121. package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -1
  122. package/dist/cmd/cloud/sandbox/list.js +40 -63
  123. package/dist/cmd/cloud/sandbox/list.js.map +1 -1
  124. package/dist/cmd/cloud/sandbox/ls.d.ts.map +1 -1
  125. package/dist/cmd/cloud/sandbox/ls.js +7 -5
  126. package/dist/cmd/cloud/sandbox/ls.js.map +1 -1
  127. package/dist/cmd/cloud/sandbox/mkdir.d.ts.map +1 -1
  128. package/dist/cmd/cloud/sandbox/mkdir.js +7 -5
  129. package/dist/cmd/cloud/sandbox/mkdir.js.map +1 -1
  130. package/dist/cmd/cloud/sandbox/rm.d.ts.map +1 -1
  131. package/dist/cmd/cloud/sandbox/rm.js +7 -5
  132. package/dist/cmd/cloud/sandbox/rm.js.map +1 -1
  133. package/dist/cmd/cloud/sandbox/rmdir.d.ts.map +1 -1
  134. package/dist/cmd/cloud/sandbox/rmdir.js +7 -5
  135. package/dist/cmd/cloud/sandbox/rmdir.js.map +1 -1
  136. package/dist/cmd/cloud/sandbox/run.js +1 -1
  137. package/dist/cmd/cloud/sandbox/run.js.map +1 -1
  138. package/dist/cmd/cloud/sandbox/snapshot/build.js.map +1 -1
  139. package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
  140. package/dist/cmd/cloud/sandbox/upload.d.ts.map +1 -1
  141. package/dist/cmd/cloud/sandbox/upload.js +7 -5
  142. package/dist/cmd/cloud/sandbox/upload.js.map +1 -1
  143. package/dist/cmd/cloud/sandbox/util.d.ts +2 -2
  144. package/dist/cmd/cloud/sandbox/util.d.ts.map +1 -1
  145. package/dist/cmd/cloud/sandbox/util.js +14 -13
  146. package/dist/cmd/cloud/sandbox/util.js.map +1 -1
  147. package/dist/cmd/cloud/ssh.d.ts.map +1 -1
  148. package/dist/cmd/cloud/ssh.js +3 -3
  149. package/dist/cmd/cloud/ssh.js.map +1 -1
  150. package/dist/cmd/cloud/storage/create.js.map +1 -1
  151. package/dist/cmd/cloud/storage/delete.js.map +1 -1
  152. package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
  153. package/dist/cmd/cloud/storage/get.js +5 -11
  154. package/dist/cmd/cloud/storage/get.js.map +1 -1
  155. package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
  156. package/dist/cmd/cloud/storage/list.js +6 -6
  157. package/dist/cmd/cloud/storage/list.js.map +1 -1
  158. package/dist/cmd/cloud/stream/create.d.ts.map +1 -1
  159. package/dist/cmd/cloud/stream/create.js +7 -4
  160. package/dist/cmd/cloud/stream/create.js.map +1 -1
  161. package/dist/cmd/cloud/stream/delete.d.ts.map +1 -1
  162. package/dist/cmd/cloud/stream/delete.js +25 -4
  163. package/dist/cmd/cloud/stream/delete.js.map +1 -1
  164. package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
  165. package/dist/cmd/cloud/stream/get.js +91 -62
  166. package/dist/cmd/cloud/stream/get.js.map +1 -1
  167. package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
  168. package/dist/cmd/cloud/stream/list.js +66 -38
  169. package/dist/cmd/cloud/stream/list.js.map +1 -1
  170. package/dist/cmd/cloud/stream/util.d.ts +20 -0
  171. package/dist/cmd/cloud/stream/util.d.ts.map +1 -1
  172. package/dist/cmd/cloud/stream/util.js +27 -3
  173. package/dist/cmd/cloud/stream/util.js.map +1 -1
  174. package/dist/cmd/cloud/vector/util.d.ts.map +1 -1
  175. package/dist/cmd/cloud/vector/util.js +3 -3
  176. package/dist/cmd/cloud/vector/util.js.map +1 -1
  177. package/dist/cmd/dev/index.js.map +1 -1
  178. package/dist/cmd/git/account/add.js.map +1 -1
  179. package/dist/cmd/git/list.js.map +1 -1
  180. package/dist/cmd/project/add/database.d.ts +2 -0
  181. package/dist/cmd/project/add/database.d.ts.map +1 -0
  182. package/dist/cmd/project/add/database.js +123 -0
  183. package/dist/cmd/project/add/database.js.map +1 -0
  184. package/dist/cmd/project/add/domain.d.ts +2 -0
  185. package/dist/cmd/project/add/domain.d.ts.map +1 -0
  186. package/dist/cmd/project/add/domain.js +152 -0
  187. package/dist/cmd/project/add/domain.js.map +1 -0
  188. package/dist/cmd/project/add/index.d.ts +2 -0
  189. package/dist/cmd/project/add/index.d.ts.map +1 -0
  190. package/dist/cmd/project/add/index.js +35 -0
  191. package/dist/cmd/project/add/index.js.map +1 -0
  192. package/dist/cmd/project/add/storage.d.ts +2 -0
  193. package/dist/cmd/project/add/storage.d.ts.map +1 -0
  194. package/dist/cmd/project/add/storage.js +123 -0
  195. package/dist/cmd/project/add/storage.js.map +1 -0
  196. package/dist/cmd/project/auth/init.js.map +1 -1
  197. package/dist/cmd/project/index.d.ts.map +1 -1
  198. package/dist/cmd/project/index.js +7 -0
  199. package/dist/cmd/project/index.js.map +1 -1
  200. package/dist/cmd/project/reconcile.d.ts.map +1 -1
  201. package/dist/cmd/project/reconcile.js +32 -0
  202. package/dist/cmd/project/reconcile.js.map +1 -1
  203. package/dist/cmd/support/report.js.map +1 -1
  204. package/dist/cmd/support/system.js +2 -2
  205. package/dist/cmd/support/system.js.map +1 -1
  206. package/dist/config.d.ts +6 -3
  207. package/dist/config.d.ts.map +1 -1
  208. package/dist/config.js +31 -7
  209. package/dist/config.js.map +1 -1
  210. package/dist/errors.d.ts +2 -1
  211. package/dist/errors.d.ts.map +1 -1
  212. package/dist/errors.js +5 -0
  213. package/dist/errors.js.map +1 -1
  214. package/dist/index.d.ts +4 -1
  215. package/dist/index.d.ts.map +1 -1
  216. package/dist/index.js +3 -0
  217. package/dist/index.js.map +1 -1
  218. package/dist/repl.js +2 -1
  219. package/dist/repl.js.map +1 -1
  220. package/dist/tui/box.d.ts +3 -1
  221. package/dist/tui/box.d.ts.map +1 -1
  222. package/dist/tui/box.js +22 -7
  223. package/dist/tui/box.js.map +1 -1
  224. package/dist/tui/colors.d.ts +0 -3
  225. package/dist/tui/colors.d.ts.map +1 -1
  226. package/dist/tui/colors.js +76 -23
  227. package/dist/tui/colors.js.map +1 -1
  228. package/dist/tui/prompt.d.ts +2 -0
  229. package/dist/tui/prompt.d.ts.map +1 -1
  230. package/dist/tui/prompt.js +44 -3
  231. package/dist/tui/prompt.js.map +1 -1
  232. package/dist/tui/symbols.d.ts +0 -4
  233. package/dist/tui/symbols.d.ts.map +1 -1
  234. package/dist/tui/symbols.js +5 -0
  235. package/dist/tui/symbols.js.map +1 -1
  236. package/dist/tui.d.ts +8 -0
  237. package/dist/tui.d.ts.map +1 -1
  238. package/dist/tui.js +54 -9
  239. package/dist/tui.js.map +1 -1
  240. package/dist/types.d.ts +37 -2
  241. package/dist/types.d.ts.map +1 -1
  242. package/dist/types.js +1 -0
  243. package/dist/types.js.map +1 -1
  244. package/dist/version-check.d.ts.map +1 -1
  245. package/dist/version-check.js +5 -0
  246. package/dist/version-check.js.map +1 -1
  247. package/package.json +6 -6
  248. package/src/agent-detection.ts +457 -160
  249. package/src/ai-help.ts +393 -0
  250. package/src/api.ts +1 -1
  251. package/src/auth.ts +226 -17
  252. package/src/banner.ts +5 -0
  253. package/src/cache/agent-intro.ts +62 -0
  254. package/src/cache/index.ts +2 -0
  255. package/src/cache/resource-region.ts +28 -7
  256. package/src/catalyst.ts +16 -0
  257. package/src/cli.ts +375 -93
  258. package/src/cmd/ai/detect.ts +54 -0
  259. package/src/cmd/ai/index.ts +18 -1
  260. package/src/cmd/ai/intro.ts +154 -0
  261. package/src/cmd/ai/opencode/run.ts +5 -0
  262. package/src/cmd/build/ast.ts +97 -0
  263. package/src/cmd/build/vite/bun-dev-server.ts +2 -0
  264. package/src/cmd/build/vite/docs-generator.ts +15 -1
  265. package/src/cmd/build/vite/env-types-generator.ts +145 -0
  266. package/src/cmd/build/vite/index.ts +15 -0
  267. package/src/cmd/build/vite/public-asset-path-plugin.ts +8 -2
  268. package/src/cmd/build/vite/vite-builder.ts +31 -11
  269. package/src/cmd/cloud/db/create.ts +16 -16
  270. package/src/cmd/cloud/db/delete.ts +19 -19
  271. package/src/cmd/cloud/db/get.ts +32 -17
  272. package/src/cmd/cloud/deploy-fork.ts +2 -0
  273. package/src/cmd/cloud/deploy.ts +17 -0
  274. package/src/cmd/cloud/env/import.ts +6 -6
  275. package/src/cmd/cloud/env/list.ts +11 -11
  276. package/src/cmd/cloud/env/push.ts +6 -6
  277. package/src/cmd/cloud/keyvalue/util.ts +3 -3
  278. package/src/cmd/cloud/machine/list.ts +3 -3
  279. package/src/cmd/cloud/region/index.ts +3 -3
  280. package/src/cmd/cloud/region-lookup.ts +82 -22
  281. package/src/cmd/cloud/sandbox/cp.ts +9 -4
  282. package/src/cmd/cloud/sandbox/create.ts +2 -2
  283. package/src/cmd/cloud/sandbox/delete.ts +10 -7
  284. package/src/cmd/cloud/sandbox/download.ts +8 -5
  285. package/src/cmd/cloud/sandbox/env.ts +8 -5
  286. package/src/cmd/cloud/sandbox/exec.ts +10 -5
  287. package/src/cmd/cloud/sandbox/get.ts +13 -7
  288. package/src/cmd/cloud/sandbox/list.ts +47 -73
  289. package/src/cmd/cloud/sandbox/ls.ts +9 -5
  290. package/src/cmd/cloud/sandbox/mkdir.ts +9 -5
  291. package/src/cmd/cloud/sandbox/rm.ts +9 -5
  292. package/src/cmd/cloud/sandbox/rmdir.ts +9 -5
  293. package/src/cmd/cloud/sandbox/run.ts +1 -1
  294. package/src/cmd/cloud/sandbox/snapshot/build.ts +31 -31
  295. package/src/cmd/cloud/sandbox/snapshot/get.ts +17 -17
  296. package/src/cmd/cloud/sandbox/upload.ts +8 -5
  297. package/src/cmd/cloud/sandbox/util.ts +15 -14
  298. package/src/cmd/cloud/ssh.ts +2 -4
  299. package/src/cmd/cloud/storage/create.ts +16 -16
  300. package/src/cmd/cloud/storage/delete.ts +19 -19
  301. package/src/cmd/cloud/storage/get.ts +5 -16
  302. package/src/cmd/cloud/storage/list.ts +12 -6
  303. package/src/cmd/cloud/stream/create.ts +8 -4
  304. package/src/cmd/cloud/stream/delete.ts +28 -4
  305. package/src/cmd/cloud/stream/get.ts +102 -64
  306. package/src/cmd/cloud/stream/list.ts +76 -44
  307. package/src/cmd/cloud/stream/util.ts +39 -3
  308. package/src/cmd/cloud/vector/util.ts +3 -3
  309. package/src/cmd/dev/index.ts +4 -4
  310. package/src/cmd/git/account/add.ts +5 -5
  311. package/src/cmd/git/list.ts +7 -7
  312. package/src/cmd/project/add/database.ts +145 -0
  313. package/src/cmd/project/add/domain.ts +181 -0
  314. package/src/cmd/project/add/index.ts +35 -0
  315. package/src/cmd/project/add/storage.ts +147 -0
  316. package/src/cmd/project/auth/init.ts +6 -6
  317. package/src/cmd/project/index.ts +7 -0
  318. package/src/cmd/project/reconcile.ts +40 -0
  319. package/src/cmd/support/report.ts +5 -5
  320. package/src/cmd/support/system.ts +2 -2
  321. package/src/config.ts +40 -12
  322. package/src/errors.ts +7 -0
  323. package/src/index.ts +11 -0
  324. package/src/repl.ts +4 -1
  325. package/src/tui/box.ts +24 -9
  326. package/src/tui/colors.ts +83 -26
  327. package/src/tui/prompt.ts +55 -3
  328. package/src/tui/symbols.ts +6 -0
  329. package/src/tui.ts +55 -9
  330. package/src/types.ts +46 -2
  331. package/src/version-check.ts +6 -0
package/src/cli.ts CHANGED
@@ -14,20 +14,36 @@ import type {
14
14
  GlobalOptions,
15
15
  } from './types';
16
16
  import { showBanner, generateBanner } from './banner';
17
- import { requireAuth, optionalAuth, requireOrg, optionalOrg as selectOptionalOrg } from './auth';
17
+ import { getExecutingAgent } from './agent-detection';
18
+ import {
19
+ requireAuth,
20
+ optionalAuth,
21
+ requireOrg,
22
+ optionalOrg as selectOptionalOrg,
23
+ hasPrefixedResourceId,
24
+ resolveOrgIdWithoutPrompt,
25
+ } from './auth';
18
26
  import { type RegionList, ValidationOutputError } from '@agentuity/server';
19
27
  import { fetchRegionsWithCache } from './regions';
20
28
  import enquirer from 'enquirer';
21
29
  import * as tui from './tui';
22
30
  import { parseArgsSchema, parseOptionsSchema, buildValidationInputAsync } from './schema-parser';
23
- import { defaultProfileName, loadProjectConfig } from './config';
31
+ import { defaultProfileName, loadProjectConfig, saveProjectId, saveRegion } from './config';
24
32
  import { APIClient, getAPIBaseURL, getAppBaseURL, type APIClient as APIClientType } from './api';
25
33
  import { ErrorCode, ExitCode, createError, exitWithError } from './errors';
26
34
  import { getCommand } from './command-prefix';
27
35
  import { isValidateMode, outputValidation, type ValidationResult } from './output';
28
36
  import { StructuredError } from '@agentuity/core';
29
37
  import { setProgram } from './program-ref';
30
- import { getCachedProject, setCachedProject } from './cache';
38
+ import { generateIntroPrompt } from './cmd/ai/intro';
39
+ import {
40
+ getCachedProject,
41
+ getResourceInfo,
42
+ setCachedProject,
43
+ type ResourceType,
44
+ hasAgentSeenIntro,
45
+ markAgentIntroSeen,
46
+ } from './cache';
31
47
 
32
48
  /**
33
49
  * Check if an error is a CLI input validation error (Zod error from schema parsing),
@@ -124,12 +140,12 @@ async function executeOrValidate(
124
140
  };
125
141
  outputValidation(result, ctx.options);
126
142
  } else if (handler) {
127
- // Render "View on the web" link before normal execution
128
- maybeRenderWebLink(ctx, webUrl);
129
-
130
143
  // Normal execution
131
144
  const result = await handler(ctx);
132
145
 
146
+ // Render "View on the web" link after successful execution (not shown on errors)
147
+ maybeRenderWebLink(ctx, webUrl);
148
+
133
149
  // If --json flag is set
134
150
  if (ctx.options.json) {
135
151
  // If command has a response schema but returned nothing, that's an error
@@ -455,6 +471,10 @@ async function promptProjectSelection(baseCtx: CommandContext): Promise<ProjectC
455
471
  return null;
456
472
  }
457
473
 
474
+ if (selectedProject.id !== config?.preferences?.projectId) {
475
+ await saveProjectId(selectedProject.id);
476
+ }
477
+
458
478
  // Convert to ProjectConfig format
459
479
  return {
460
480
  projectId: selectedProject.id,
@@ -485,6 +505,11 @@ export async function createCLI(version: string): Promise<Command> {
485
505
  'Use a specific organization when performing operations',
486
506
  process.env.AGENTUITY_CLOUD_ORG_ID
487
507
  )
508
+ .option(
509
+ '--project-id <id>',
510
+ 'Use a specific project when performing operations (AGENTUITY_CLOUD_PROJECT_ID)',
511
+ process.env.AGENTUITY_CLOUD_PROJECT_ID
512
+ )
488
513
  .option('--color-scheme <scheme>', 'Color scheme: light or dark')
489
514
  .option('--color <mode>', 'Color output: auto, always, never', 'auto')
490
515
  .option('--error-format <format>', 'Error output format: json or text', 'text')
@@ -493,7 +518,8 @@ export async function createCLI(version: string): Promise<Command> {
493
518
  .option('--no-progress', 'Disable progress indicators', false)
494
519
  .option('--explain', 'Show what the command would do without executing', false)
495
520
  .option('--dry-run', 'Execute command without making changes', false)
496
- .option('--validate', 'Validate arguments and options without executing', false);
521
+ .option('--validate', 'Validate arguments and options without executing', false)
522
+ .option('--ai-help', 'Show AI-optimized help in dashdash format', false);
497
523
 
498
524
  const skipVersionCheckOption = program.createOption(
499
525
  '--skip-version-check',
@@ -502,6 +528,13 @@ export async function createCLI(version: string): Promise<Command> {
502
528
  skipVersionCheckOption.hideHelp();
503
529
  program.addOption(skipVersionCheckOption);
504
530
 
531
+ const profileOption = program.createOption(
532
+ '--profile <name>',
533
+ 'Override the default profile (takes precedence over AGENTUITY_PROFILE env var)'
534
+ );
535
+ profileOption.hideHelp();
536
+ program.addOption(profileOption);
537
+
505
538
  program.action(() => {
506
539
  program.help();
507
540
  });
@@ -609,13 +642,34 @@ export async function createCLI(version: string): Promise<Command> {
609
642
  // Format each section (show banner for root command)
610
643
  let output = '';
611
644
 
645
+ // Show intro for first-time agents (before normal help output)
646
+ // AGENTUITY_SHOW_INTRO=1 forces showing the intro (useful for testing)
647
+ const agent = getExecutingAgent();
648
+ const forceShowIntro = process.env.AGENTUITY_SHOW_INTRO === '1';
649
+ const hasSeenIntro = agent ? hasAgentSeenIntro(agent) : true;
650
+
651
+ if (agent && (forceShowIntro || !hasSeenIntro)) {
652
+ // Only mark as seen if this is their first time (not on forced re-shows)
653
+ if (!hasSeenIntro) {
654
+ markAgentIntroSeen(agent);
655
+ }
656
+
657
+ const separator = '='.repeat(79);
658
+ output += `${separator}\n\n`;
659
+ output += generateIntroPrompt(agent);
660
+ output += `\n${separator}\n\n`;
661
+ }
662
+
612
663
  // Show banner (full for root, compact for subcommands)
664
+ // Skip banner when running from an AI coding agent
613
665
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
614
666
  const isRootCommand = !(cmd as any).parent;
615
- if (isRootCommand) {
616
- output += `${generateBanner(version)}\n\n`;
617
- } else {
618
- output += `${generateBanner(version, true)}\n`;
667
+ if (!agent) {
668
+ if (isRootCommand) {
669
+ output += `${generateBanner(version)}\n\n`;
670
+ } else {
671
+ output += `${generateBanner(version, true)}\n`;
672
+ }
619
673
  }
620
674
 
621
675
  // Description
@@ -669,15 +723,19 @@ export async function createCLI(version: string): Promise<Command> {
669
723
  return program;
670
724
  }
671
725
 
672
- async function getRegion(regions: RegionList): Promise<string> {
726
+ async function getRegion(regions: RegionList, preferredRegion?: string): Promise<string> {
673
727
  const firstRegion = regions[0];
674
728
  if (regions.length === 1 && firstRegion) {
675
729
  return firstRegion.region;
676
730
  } else {
731
+ const preferredIndex = preferredRegion
732
+ ? regions.findIndex((region) => region.region === preferredRegion)
733
+ : -1;
677
734
  const response = await enquirer.prompt<{ region: string }>({
678
735
  type: 'select',
679
736
  name: 'region',
680
737
  message: 'Select a cloud region:',
738
+ ...(preferredIndex >= 0 && { initial: preferredIndex }),
681
739
  choices: regions.map((r) => ({
682
740
  name: r.region,
683
741
  message: `${r.description.padEnd(15, ' ')} ${tui.muted(r.region)}`,
@@ -687,16 +745,76 @@ async function getRegion(regions: RegionList): Promise<string> {
687
745
  }
688
746
  }
689
747
 
690
- interface ResolveRegionOptions {
748
+ const RESOURCE_PREFIXES: Array<{ prefix: string; type: ResourceType }> = [
749
+ { prefix: 'sbx_', type: 'sandbox' },
750
+ { prefix: 'proj_', type: 'project' },
751
+ { prefix: 'db_', type: 'db' },
752
+ { prefix: 'deploy_', type: 'deployment' },
753
+ { prefix: 'machine_', type: 'machine' },
754
+ { prefix: 'que_', type: 'queue' },
755
+ { prefix: 'vec_', type: 'vector' },
756
+ { prefix: 'kv_', type: 'kv' },
757
+ { prefix: 'stream_', type: 'stream' },
758
+ ];
759
+
760
+ type PrefixedResource = { id: string; type: ResourceType };
761
+
762
+ function getResourceTypeFromId(id: string): ResourceType | undefined {
763
+ for (const entry of RESOURCE_PREFIXES) {
764
+ if (id.startsWith(entry.prefix)) {
765
+ return entry.type;
766
+ }
767
+ }
768
+ return undefined;
769
+ }
770
+
771
+ function collectPrefixedResources(
772
+ values?: Record<string, unknown> | unknown[]
773
+ ): PrefixedResource[] {
774
+ if (!values) {
775
+ return [];
776
+ }
777
+ const results = new Map<string, ResourceType>();
778
+ const addValue = (value: unknown) => {
779
+ if (typeof value === 'string') {
780
+ const resourceType = getResourceTypeFromId(value);
781
+ if (resourceType) {
782
+ results.set(value, resourceType);
783
+ }
784
+ return;
785
+ }
786
+ if (Array.isArray(value)) {
787
+ for (const entry of value) {
788
+ addValue(entry);
789
+ }
790
+ }
791
+ };
792
+
793
+ if (Array.isArray(values)) {
794
+ for (const entry of values) {
795
+ addValue(entry);
796
+ }
797
+ } else {
798
+ for (const value of Object.values(values)) {
799
+ addValue(value);
800
+ }
801
+ }
802
+
803
+ return Array.from(results.entries()).map(([id, type]) => ({ id, type }));
804
+ }
805
+
806
+ export interface ResolveRegionOptions {
691
807
  options: Record<string, unknown>;
692
808
  regions: RegionList;
693
809
  logger: Logger;
694
810
  required: boolean;
695
811
  region?: string;
812
+ config?: Config | null;
813
+ args?: Record<string, unknown> | unknown[];
696
814
  }
697
815
 
698
- async function resolveRegion(opts: ResolveRegionOptions): Promise<string | undefined> {
699
- const { options, regions, logger, required } = opts;
816
+ export async function resolveRegion(opts: ResolveRegionOptions): Promise<string | undefined> {
817
+ const { options, regions, logger, required, config, args } = opts;
700
818
 
701
819
  // No regions available
702
820
  if (regions.length === 0) {
@@ -717,7 +835,7 @@ async function resolveRegion(opts: ResolveRegionOptions): Promise<string | undef
717
835
  }
718
836
 
719
837
  // Check if region was provided via flag
720
- let region = opts.region ?? (options.region as string | undefined);
838
+ let region = options.region as string | undefined;
721
839
 
722
840
  // Validate --region flag if provided
723
841
  if (region) {
@@ -741,6 +859,22 @@ async function resolveRegion(opts: ResolveRegionOptions): Promise<string | undef
741
859
  return region;
742
860
  }
743
861
 
862
+ const profileName = config?.name ?? defaultProfileName;
863
+ const candidateResources = new Map<string, ResourceType>();
864
+ for (const resource of collectPrefixedResources(args)) {
865
+ candidateResources.set(resource.id, resource.type);
866
+ }
867
+ for (const resource of collectPrefixedResources(options)) {
868
+ candidateResources.set(resource.id, resource.type);
869
+ }
870
+ for (const [id, type] of candidateResources.entries()) {
871
+ const cachedInfo = await getResourceInfo(type, profileName, id);
872
+ if (cachedInfo?.region) {
873
+ logger.trace('resolved region from cache for %s (%s): %s', id, type, cachedInfo.region);
874
+ return cachedInfo.region;
875
+ }
876
+ }
877
+
744
878
  // Auto-select if only one region available
745
879
  const singleRegion = regions[0];
746
880
  if (regions.length === 1 && singleRegion) {
@@ -762,6 +896,29 @@ async function resolveRegion(opts: ResolveRegionOptions): Promise<string | undef
762
896
  // If not valid, fall through to error/prompt
763
897
  }
764
898
 
899
+ // Check for preferred region in config
900
+ const preferredRegion = config?.preferences?.region;
901
+ if (preferredRegion) {
902
+ const matchingRegion = regions.find((r) => r.region === preferredRegion);
903
+ if (matchingRegion) {
904
+ if (process.stdin.isTTY) {
905
+ region = await getRegion(regions, matchingRegion.region);
906
+ return region;
907
+ }
908
+ logger.trace('selected preferred region (non-TTY): %s', matchingRegion.region);
909
+ return matchingRegion.region;
910
+ }
911
+ }
912
+
913
+ // Check for project region fallback
914
+ const projectRegion = opts.region;
915
+ if (projectRegion) {
916
+ const matchingRegion = regions.find((r) => r.region === projectRegion);
917
+ if (matchingRegion) {
918
+ return matchingRegion.region;
919
+ }
920
+ }
921
+
765
922
  // No flag provided - handle TTY vs non-TTY
766
923
  if (required && !process.stdin.isTTY) {
767
924
  const errorFormat = (options as Record<string, unknown>).errorFormat as
@@ -786,6 +943,24 @@ async function resolveRegion(opts: ResolveRegionOptions): Promise<string | undef
786
943
  if (process.stdin.isTTY) {
787
944
  // Interactive mode - prompt user
788
945
  region = await getRegion(regions);
946
+
947
+ const hasSavedPreference = !!config?.preferences?.region;
948
+ const hasEnvRegion = !!process.env.AGENTUITY_REGION;
949
+ const hasTTY = process.stdin.isTTY && process.stdout.isTTY;
950
+ if (region && hasTTY && !hasSavedPreference && !hasEnvRegion) {
951
+ const selectedRegionInfo = regions.find((r) => r.region === region);
952
+ const regionLabel = selectedRegionInfo
953
+ ? `${selectedRegionInfo.description} (${selectedRegionInfo.region})`
954
+ : region;
955
+ const shouldSave = await tui.confirm(
956
+ `Would you like to set "${regionLabel}" as your default region?`,
957
+ true
958
+ );
959
+ if (shouldSave) {
960
+ await saveRegion(region);
961
+ }
962
+ }
963
+
789
964
  return region;
790
965
  }
791
966
 
@@ -1040,44 +1215,58 @@ async function registerSubcommand(
1040
1215
  const dirNeeded = normalized.requiresProject || normalized.optionalProject;
1041
1216
 
1042
1217
  if (dirNeeded) {
1043
- const projectId = options.projectId as string | undefined;
1218
+ const optionsProjectId = options.projectId as string | undefined;
1219
+
1220
+ // Helper to fetch project from API by ID
1221
+ const fetchProjectFromAPI = async (
1222
+ projectId: string
1223
+ ): Promise<ProjectConfig | undefined> => {
1224
+ const auth = await requireAuth(baseCtx);
1225
+ if (auth) {
1226
+ // Create config with auth credentials for API client
1227
+ const configWithAuth = {
1228
+ ...baseCtx.config,
1229
+ auth: {
1230
+ api_key: auth.apiKey,
1231
+ user_id: auth.userId,
1232
+ expires: auth.expires.getTime(),
1233
+ },
1234
+ };
1235
+ const apiClient = createAPIClient(baseCtx, configWithAuth as Config);
1236
+ // Check cache first to avoid duplicate API calls
1237
+ const profile = baseCtx.config?.name ?? 'default';
1238
+ let projectDetails = getCachedProject(profile, projectId);
1239
+ if (!projectDetails) {
1240
+ const { projectGet } = await import('@agentuity/server');
1241
+ // Use keys: false to match other callers and ensure cache consistency
1242
+ projectDetails = await projectGet(apiClient, { id: projectId, keys: false });
1243
+ setCachedProject(profile, projectId, projectDetails);
1244
+ }
1245
+ return {
1246
+ projectId: projectDetails.id,
1247
+ orgId: projectDetails.orgId,
1248
+ region: projectDetails.cloudRegion || '',
1249
+ };
1250
+ }
1251
+ return undefined;
1252
+ };
1044
1253
 
1045
- // If --project-id is provided, fetch project details from API
1046
- if (projectId) {
1254
+ // Resolution precedence:
1255
+ // 1. --project-id flag (or AGENTUITY_CLOUD_PROJECT_ID env var)
1256
+ // 2. agentuity.json in project directory
1257
+ // 3. config.preferences.projectId (global preference) - fallback only
1258
+ // 4. Interactive selection (if TTY)
1259
+
1260
+ if (optionsProjectId) {
1261
+ // Priority 1: Explicit flag/env var provided
1047
1262
  try {
1048
- const auth = await requireAuth(baseCtx);
1049
- if (auth) {
1050
- // Create config with auth credentials for API client
1051
- const configWithAuth = {
1052
- ...baseCtx.config,
1053
- auth: {
1054
- api_key: auth.apiKey,
1055
- user_id: auth.userId,
1056
- expires: auth.expires.getTime(),
1057
- },
1058
- };
1059
- const apiClient = createAPIClient(baseCtx, configWithAuth as Config);
1060
- // Check cache first to avoid duplicate API calls
1061
- const profile = baseCtx.config?.name ?? 'default';
1062
- let projectDetails = getCachedProject(profile, projectId);
1063
- if (!projectDetails) {
1064
- const { projectGet } = await import('@agentuity/server');
1065
- // Use keys: false to match other callers and ensure cache consistency
1066
- projectDetails = await projectGet(apiClient, { id: projectId, keys: false });
1067
- setCachedProject(profile, projectId, projectDetails);
1068
- }
1069
- project = {
1070
- projectId: projectDetails.id,
1071
- orgId: projectDetails.orgId,
1072
- region: projectDetails.cloudRegion || '',
1073
- };
1074
- }
1263
+ project = await fetchProjectFromAPI(optionsProjectId);
1075
1264
  } catch (_error) {
1076
1265
  if (normalized.requiresProject) {
1077
1266
  exitWithError(
1078
1267
  createError(
1079
1268
  ErrorCode.PROJECT_NOT_FOUND,
1080
- `Project not found: ${projectId}`,
1269
+ `Project not found: ${optionsProjectId}`,
1081
1270
  undefined,
1082
1271
  [
1083
1272
  'Verify the project ID is correct',
@@ -1090,7 +1279,7 @@ async function registerSubcommand(
1090
1279
  }
1091
1280
  }
1092
1281
  } else {
1093
- // Try to load from directory
1282
+ // Priority 2: Try to load from agentuity.json in directory
1094
1283
  const dir = (options.dir as string | undefined) ?? process.cwd();
1095
1284
  projectDir = dir;
1096
1285
  if (projectDir.startsWith('~/')) {
@@ -1100,14 +1289,35 @@ async function registerSubcommand(
1100
1289
  try {
1101
1290
  project = await loadProjectConfig(dir, baseCtx.config);
1102
1291
  } catch (error) {
1103
- if (normalized.requiresProject) {
1104
- if (
1105
- error &&
1106
- typeof error === 'object' &&
1107
- 'name' in error &&
1108
- error.name === 'ProjectConfigNotFoundException'
1109
- ) {
1110
- // If TTY is available, prompt user to select a project
1292
+ const isConfigNotFound =
1293
+ error &&
1294
+ typeof error === 'object' &&
1295
+ 'name' in error &&
1296
+ error.name === 'ProjectConfigNotFoundException';
1297
+
1298
+ if (isConfigNotFound) {
1299
+ // Priority 3: Try global preference (only when no agentuity.json found)
1300
+ const projectIdFromPreference = baseCtx.config?.preferences?.projectId as
1301
+ | string
1302
+ | undefined;
1303
+ if (projectIdFromPreference) {
1304
+ try {
1305
+ project = await fetchProjectFromAPI(projectIdFromPreference);
1306
+ if (project) {
1307
+ // Set the project ID in options so it can be used by the command
1308
+ (options as Record<string, unknown>).projectId = projectIdFromPreference;
1309
+ }
1310
+ } catch (_preferenceError) {
1311
+ // Preference project not found, fall through to interactive selection
1312
+ baseCtx.logger.trace(
1313
+ 'Preference project not found: %s',
1314
+ projectIdFromPreference
1315
+ );
1316
+ }
1317
+ }
1318
+
1319
+ // Priority 4: Interactive selection (if TTY and still no project)
1320
+ if (!project && normalized.requiresProject) {
1111
1321
  const hasTTY = process.stdin.isTTY && process.stdout.isTTY;
1112
1322
 
1113
1323
  if (hasTTY) {
@@ -1143,9 +1353,9 @@ async function registerSubcommand(
1143
1353
  baseCtx.options.errorFormat
1144
1354
  );
1145
1355
  }
1146
- } else {
1147
- throw error;
1148
1356
  }
1357
+ } else if (normalized.requiresProject) {
1358
+ throw error;
1149
1359
  }
1150
1360
  // For optional projects, silently continue without project config
1151
1361
  }
@@ -1200,11 +1410,25 @@ async function registerSubcommand(
1200
1410
  }
1201
1411
  // Auto-select org when --confirm flag is used
1202
1412
  const autoSelectOrg = options.confirm === true;
1413
+ const hasPrefixedId = hasPrefixedResourceId(
1414
+ ctx.args as Record<string, unknown> | undefined,
1415
+ ctx.opts as Record<string, unknown> | undefined
1416
+ );
1417
+ const prefixedOrgId = hasPrefixedId
1418
+ ? await resolveOrgIdWithoutPrompt({
1419
+ options,
1420
+ config: (ctx.config as Config | null) ?? null,
1421
+ args: ctx.args as Record<string, unknown> | undefined,
1422
+ opts: ctx.opts as Record<string, unknown> | undefined,
1423
+ })
1424
+ : undefined;
1203
1425
  if (normalized.requiresOrg) {
1204
- ctx.orgId = await requireOrg(
1205
- ctx as CommandContext & { apiClient: APIClientType },
1206
- autoSelectOrg
1207
- );
1426
+ ctx.orgId = hasPrefixedId
1427
+ ? prefixedOrgId
1428
+ : await requireOrg(
1429
+ ctx as CommandContext & { apiClient: APIClientType },
1430
+ autoSelectOrg
1431
+ );
1208
1432
  }
1209
1433
  // Skip org handling if --no-register is set (org only needed for registration)
1210
1434
  const skipOrg =
@@ -1214,10 +1438,12 @@ async function registerSubcommand(
1214
1438
  (ctx.opts as Record<string, unknown>).register === false;
1215
1439
 
1216
1440
  if (normalized.optionalOrg && ctx.auth && !skipOrg) {
1217
- ctx.orgId = await selectOptionalOrg(
1218
- ctx as CommandContext & { apiClient: APIClientType },
1219
- autoSelectOrg
1220
- );
1441
+ ctx.orgId = hasPrefixedId
1442
+ ? prefixedOrgId
1443
+ : await selectOptionalOrg(
1444
+ ctx as CommandContext & { apiClient: APIClientType },
1445
+ autoSelectOrg
1446
+ );
1221
1447
  }
1222
1448
  // Skip region handling if --no-register is set (region only needed for registration)
1223
1449
  const skipRegion =
@@ -1252,10 +1478,12 @@ async function registerSubcommand(
1252
1478
  if (normalized.requiresRegion || normalized.optionalRegion) {
1253
1479
  const region = await resolveRegion({
1254
1480
  options: options as Record<string, unknown>,
1481
+ args: ctx.args as Record<string, unknown> | undefined,
1255
1482
  regions,
1256
1483
  logger: baseCtx.logger,
1257
1484
  required: !!normalized.requiresRegion,
1258
1485
  region: project?.region,
1486
+ config: baseCtx.config ?? null,
1259
1487
  });
1260
1488
  if (region) {
1261
1489
  ctx.region = region;
@@ -1308,11 +1536,21 @@ async function registerSubcommand(
1308
1536
  }
1309
1537
  // Auto-select org when --confirm flag is used
1310
1538
  const autoSelectOrg2 = options.confirm === true;
1539
+ const hasPrefixedId = hasPrefixedResourceId(args as unknown[]);
1540
+ const prefixedOrgId = hasPrefixedId
1541
+ ? await resolveOrgIdWithoutPrompt({
1542
+ options,
1543
+ config: (ctx.config as Config | null) ?? null,
1544
+ args: args as unknown[],
1545
+ })
1546
+ : undefined;
1311
1547
  if (normalized.requiresOrg) {
1312
- ctx.orgId = await requireOrg(
1313
- ctx as CommandContext & { apiClient: APIClientType },
1314
- autoSelectOrg2
1315
- );
1548
+ ctx.orgId = hasPrefixedId
1549
+ ? prefixedOrgId
1550
+ : await requireOrg(
1551
+ ctx as CommandContext & { apiClient: APIClientType },
1552
+ autoSelectOrg2
1553
+ );
1316
1554
  }
1317
1555
  // Skip org handling if --no-register is set (org only needed for registration)
1318
1556
  const skipOrg =
@@ -1322,10 +1560,12 @@ async function registerSubcommand(
1322
1560
  (ctx.opts as Record<string, unknown>).register === false;
1323
1561
 
1324
1562
  if (normalized.optionalOrg && ctx.auth && !skipOrg) {
1325
- ctx.orgId = await selectOptionalOrg(
1326
- ctx as CommandContext & { apiClient: APIClientType },
1327
- autoSelectOrg2
1328
- );
1563
+ ctx.orgId = hasPrefixedId
1564
+ ? prefixedOrgId
1565
+ : await selectOptionalOrg(
1566
+ ctx as CommandContext & { apiClient: APIClientType },
1567
+ autoSelectOrg2
1568
+ );
1329
1569
  }
1330
1570
  // Skip region handling if --no-register is set (region only needed for registration)
1331
1571
  const skipRegion =
@@ -1360,10 +1600,12 @@ async function registerSubcommand(
1360
1600
  if (normalized.requiresRegion || normalized.optionalRegion) {
1361
1601
  const region = await resolveRegion({
1362
1602
  options: options as Record<string, unknown>,
1603
+ args: args as unknown[],
1363
1604
  regions,
1364
1605
  logger: baseCtx.logger,
1365
1606
  required: !!normalized.requiresRegion,
1366
1607
  region: project?.region,
1608
+ config: baseCtx.config ?? null,
1367
1609
  });
1368
1610
  if (region) {
1369
1611
  ctx.region = region;
@@ -1371,8 +1613,9 @@ async function registerSubcommand(
1371
1613
  }
1372
1614
  }
1373
1615
  if (subcommand.handler) {
1374
- maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
1375
1616
  const result = await subcommand.handler(ctx as CommandContext);
1617
+ // Render "View on the web" link after successful execution (not shown on errors)
1618
+ maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
1376
1619
 
1377
1620
  // If --json flag is set
1378
1621
  if (baseCtx.options.json) {
@@ -1466,11 +1709,25 @@ async function registerSubcommand(
1466
1709
  );
1467
1710
  // Auto-select org when --confirm flag is used
1468
1711
  const autoSelectOrg3 = options.confirm === true;
1712
+ const hasPrefixedId3 = hasPrefixedResourceId(
1713
+ ctx.args as Record<string, unknown> | undefined,
1714
+ ctx.opts as Record<string, unknown> | undefined
1715
+ );
1716
+ const prefixedOrgId3 = hasPrefixedId3
1717
+ ? await resolveOrgIdWithoutPrompt({
1718
+ options,
1719
+ config: (ctx.config as Config | null) ?? null,
1720
+ args: ctx.args as Record<string, unknown> | undefined,
1721
+ opts: ctx.opts as Record<string, unknown> | undefined,
1722
+ })
1723
+ : undefined;
1469
1724
  if (normalized.requiresOrg && ctx.apiClient) {
1470
- ctx.orgId = await requireOrg(
1471
- ctx as CommandContext & { apiClient: APIClientType },
1472
- autoSelectOrg3
1473
- );
1725
+ ctx.orgId = hasPrefixedId3
1726
+ ? prefixedOrgId3
1727
+ : await requireOrg(
1728
+ ctx as CommandContext & { apiClient: APIClientType },
1729
+ autoSelectOrg3
1730
+ );
1474
1731
  }
1475
1732
  // Skip org handling if --no-register is set (org only needed for registration)
1476
1733
  const skipOrg =
@@ -1480,10 +1737,12 @@ async function registerSubcommand(
1480
1737
  (ctx.opts as Record<string, unknown>).register === false;
1481
1738
 
1482
1739
  if (normalized.optionalOrg && ctx.apiClient && auth && !skipOrg) {
1483
- ctx.orgId = await selectOptionalOrg(
1484
- ctx as CommandContext & { apiClient?: APIClientType; auth?: AuthData },
1485
- autoSelectOrg3
1486
- );
1740
+ ctx.orgId = hasPrefixedId3
1741
+ ? prefixedOrgId3
1742
+ : await selectOptionalOrg(
1743
+ ctx as CommandContext & { apiClient?: APIClientType; auth?: AuthData },
1744
+ autoSelectOrg3
1745
+ );
1487
1746
  baseCtx.logger.trace('selected orgId: %s', ctx.orgId);
1488
1747
  }
1489
1748
  // Skip region handling if --no-register is set (region only needed for registration)
@@ -1513,10 +1772,12 @@ async function registerSubcommand(
1513
1772
  });
1514
1773
  const region = await resolveRegion({
1515
1774
  options: options as Record<string, unknown>,
1775
+ args: ctx.args as Record<string, unknown> | undefined,
1516
1776
  regions,
1517
1777
  logger: baseCtx.logger,
1518
1778
  required: !!normalized.requiresRegion,
1519
1779
  region: project?.region,
1780
+ config: baseCtx.config ?? null,
1520
1781
  });
1521
1782
  if (region) {
1522
1783
  ctx.region = region;
@@ -1567,11 +1828,21 @@ async function registerSubcommand(
1567
1828
  }
1568
1829
  // Auto-select org when --confirm flag is used
1569
1830
  const autoSelectOrg4 = options.confirm === true;
1831
+ const hasPrefixedId4 = hasPrefixedResourceId(args as unknown[]);
1832
+ const prefixedOrgId4 = hasPrefixedId4
1833
+ ? await resolveOrgIdWithoutPrompt({
1834
+ options,
1835
+ config: (ctx.config as Config | null) ?? null,
1836
+ args: args as unknown[],
1837
+ })
1838
+ : undefined;
1570
1839
  if (normalized.requiresOrg && ctx.apiClient) {
1571
- ctx.orgId = await requireOrg(
1572
- ctx as CommandContext & { apiClient: APIClientType },
1573
- autoSelectOrg4
1574
- );
1840
+ ctx.orgId = hasPrefixedId4
1841
+ ? prefixedOrgId4
1842
+ : await requireOrg(
1843
+ ctx as CommandContext & { apiClient: APIClientType },
1844
+ autoSelectOrg4
1845
+ );
1575
1846
  }
1576
1847
  // Skip org handling if --no-register is set (org only needed for registration)
1577
1848
  // For non-schema commands, check options directly (Commander passes all options)
@@ -1581,10 +1852,12 @@ async function registerSubcommand(
1581
1852
  (options as Record<string, unknown>).register === false;
1582
1853
 
1583
1854
  if (normalized.optionalOrg && ctx.apiClient && !skipOrg) {
1584
- ctx.orgId = await selectOptionalOrg(
1585
- ctx as CommandContext & { apiClient?: APIClientType; auth?: AuthData },
1586
- autoSelectOrg4
1587
- );
1855
+ ctx.orgId = hasPrefixedId4
1856
+ ? prefixedOrgId4
1857
+ : await selectOptionalOrg(
1858
+ ctx as CommandContext & { apiClient?: APIClientType; auth?: AuthData },
1859
+ autoSelectOrg4
1860
+ );
1588
1861
  }
1589
1862
  // Skip region handling if --no-register is set (region only needed for registration)
1590
1863
  const skipRegion =
@@ -1611,18 +1884,21 @@ async function registerSubcommand(
1611
1884
  });
1612
1885
  const region = await resolveRegion({
1613
1886
  options: options as Record<string, unknown>,
1887
+ args: args as unknown[],
1614
1888
  regions,
1615
1889
  logger: baseCtx.logger,
1616
1890
  required: !!normalized.requiresRegion,
1617
1891
  region: project?.region,
1892
+ config: baseCtx.config ?? null,
1618
1893
  });
1619
1894
  if (region) {
1620
1895
  ctx.region = region;
1621
1896
  }
1622
1897
  }
1623
1898
  if (subcommand.handler) {
1624
- maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
1625
1899
  const result = await subcommand.handler(ctx as CommandContext);
1900
+ // Render "View on the web" link after successful execution (not shown on errors)
1901
+ maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
1626
1902
 
1627
1903
  // If --json flag is set
1628
1904
  if (baseCtx.options.json) {
@@ -1750,18 +2026,21 @@ async function registerSubcommand(
1750
2026
  });
1751
2027
  const region = await resolveRegion({
1752
2028
  options: options as Record<string, unknown>,
2029
+ args: args as unknown[],
1753
2030
  regions,
1754
2031
  logger: baseCtx.logger,
1755
2032
  required: !!normalized.requiresRegion,
1756
2033
  region: project?.region,
2034
+ config: baseCtx.config ?? null,
1757
2035
  });
1758
2036
  if (region) {
1759
2037
  ctx.region = region;
1760
2038
  }
1761
2039
  }
1762
2040
  if (subcommand.handler) {
1763
- maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
1764
2041
  const result = await subcommand.handler(ctx as CommandContext);
2042
+ // Render "View on the web" link after successful execution (not shown on errors)
2043
+ maybeRenderWebLink(ctx as CommandContext, subcommand.webUrl);
1765
2044
 
1766
2045
  // If --json flag is set
1767
2046
  if (baseCtx.options.json) {
@@ -1892,6 +2171,7 @@ export async function registerCommands(
1892
2171
  regions,
1893
2172
  logger: baseCtx.logger,
1894
2173
  required: !!normalized.requiresRegion,
2174
+ config: baseCtx.config ?? null,
1895
2175
  });
1896
2176
  if (region) {
1897
2177
  ctx.region = region;
@@ -1960,6 +2240,7 @@ export async function registerCommands(
1960
2240
  regions,
1961
2241
  logger: baseCtx.logger,
1962
2242
  required: !!normalized.requiresRegion,
2243
+ config: baseCtx.config ?? null,
1963
2244
  });
1964
2245
  if (region) {
1965
2246
  ctx.region = region;
@@ -1991,6 +2272,7 @@ export async function registerCommands(
1991
2272
  regions,
1992
2273
  logger: baseCtx.logger,
1993
2274
  required: !!normalized.requiresRegion,
2275
+ config: baseCtx.config ?? null,
1994
2276
  });
1995
2277
  if (region) {
1996
2278
  ctx.region = region;