@agentuity/cli 1.0.0 → 1.0.2

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 +11 -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 +1 -1
  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 +391 -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 +61 -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 +52 -0
  259. package/src/cmd/ai/index.ts +11 -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 +1 -1
  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
@@ -1,9 +1,16 @@
1
1
  import { z } from 'zod';
2
+ import { streamList, type StreamInfo } from '@agentuity/server';
3
+ import { StructuredError } from '@agentuity/core';
2
4
  import { createCommand } from '../../../types';
3
5
  import * as tui from '../../../tui';
4
- import { createStorageAdapter } from './util';
5
6
  import { getCommand } from '../../../command-prefix';
6
7
 
8
+ const StreamListError = StructuredError('StreamListError')<{
9
+ namespace?: string;
10
+ projectId?: string;
11
+ orgId?: string;
12
+ }>();
13
+
7
14
  const StreamInfoSchema = z.object({
8
15
  id: z.string().describe('Stream ID'),
9
16
  namespace: z.string().describe('Stream namespace'),
@@ -22,7 +29,7 @@ export const listSubcommand = createCommand({
22
29
  aliases: ['ls'],
23
30
  description: 'List recent streams with optional filtering',
24
31
  tags: ['read-only', 'slow', 'requires-auth'],
25
- requires: { auth: true, region: true },
32
+ requires: { auth: true, apiClient: true },
26
33
  optional: { project: true },
27
34
  idempotent: true,
28
35
  examples: [
@@ -40,6 +47,14 @@ export const listSubcommand = createCommand({
40
47
  description: 'Filter by metadata',
41
48
  },
42
49
  { command: getCommand('cloud stream ls --json'), description: 'Output as JSON' },
50
+ {
51
+ command: getCommand('cloud stream list --project-id proj_123'),
52
+ description: 'Filter by project',
53
+ },
54
+ {
55
+ command: getCommand('cloud stream list --org-id org_123'),
56
+ description: 'Filter by organization',
57
+ },
43
58
  ],
44
59
  schema: {
45
60
  options: z.object({
@@ -50,14 +65,17 @@ export const listSubcommand = createCommand({
50
65
  .string()
51
66
  .optional()
52
67
  .describe('filter by metadata (format: key=value or key1=value1,key2=value2)'),
68
+ projectId: z.string().optional().describe('filter by project ID'),
69
+ orgId: z.string().optional().describe('filter by organization ID'),
53
70
  }),
54
71
  response: ListStreamsResponseSchema,
55
72
  },
56
73
  webUrl: '/services/stream',
57
74
 
58
75
  async handler(ctx) {
59
- const { opts, options } = ctx;
60
- const storage = await createStorageAdapter(ctx);
76
+ const { opts, options, apiClient, project } = ctx;
77
+ // Use project context if available, or explicit flag
78
+ const projectId = opts.projectId || project?.projectId;
61
79
 
62
80
  // Parse metadata filter if provided
63
81
  let metadataFilter: Record<string, string> | undefined;
@@ -96,53 +114,67 @@ export const listSubcommand = createCommand({
96
114
  }
97
115
  }
98
116
 
99
- const result = await storage.list({
100
- limit: opts.size,
101
- offset: opts.offset,
102
- namespace: opts.namespace,
103
- metadata: metadataFilter,
104
- });
117
+ try {
118
+ const result = await streamList(apiClient, {
119
+ limit: opts.size,
120
+ offset: opts.offset,
121
+ namespace: opts.namespace,
122
+ metadata: metadataFilter,
123
+ projectId,
124
+ orgId: opts.orgId,
125
+ });
126
+
127
+ if (options.json) {
128
+ console.log(JSON.stringify(result, null, 2));
129
+ return {
130
+ streams: result.streams,
131
+ total: result.total,
132
+ };
133
+ }
134
+
135
+ if (result.streams.length === 0) {
136
+ tui.info('No streams found');
137
+ } else {
138
+ const tableData = result.streams.map((stream: StreamInfo) => {
139
+ const sizeBytes = stream.sizeBytes ?? 0;
140
+ const metadataStr =
141
+ Object.keys(stream.metadata).length > 0 ? JSON.stringify(stream.metadata) : '-';
142
+ return {
143
+ Namespace: stream.namespace,
144
+ ID: stream.id,
145
+ Size: tui.formatBytes(sizeBytes),
146
+ Metadata:
147
+ metadataStr.length > 40 ? metadataStr.substring(0, 37) + '...' : metadataStr,
148
+ URL: tui.link(stream.url),
149
+ };
150
+ });
151
+
152
+ tui.table(tableData, [
153
+ { name: 'Namespace', alignment: 'left' },
154
+ { name: 'ID', alignment: 'left' },
155
+ { name: 'Size', alignment: 'right' },
156
+ { name: 'Metadata', alignment: 'left' },
157
+ { name: 'URL', alignment: 'left' },
158
+ ]);
159
+
160
+ tui.info(`Total: ${result.total} ${tui.plural(result.total, 'stream', 'streams')}`);
161
+ }
105
162
 
106
- if (options.json) {
107
- console.log(JSON.stringify(result, null, 2));
108
163
  return {
109
164
  streams: result.streams,
110
165
  total: result.total,
111
166
  };
112
- }
113
-
114
- if (result.streams.length === 0) {
115
- tui.info('No streams found');
116
- } else {
117
- const tableData = result.streams.map((stream) => {
118
- const sizeBytes = stream.sizeBytes ?? 0;
119
- const metadataStr =
120
- Object.keys(stream.metadata).length > 0 ? JSON.stringify(stream.metadata) : '-';
121
- return {
122
- Namespace: stream.namespace,
123
- ID: stream.id,
124
- Size: tui.formatBytes(sizeBytes),
125
- Metadata:
126
- metadataStr.length > 40 ? metadataStr.substring(0, 37) + '...' : metadataStr,
127
- URL: tui.link(stream.url),
128
- };
167
+ } catch (ex) {
168
+ if (ex instanceof StreamListError) {
169
+ throw ex;
170
+ }
171
+ throw new StreamListError({
172
+ message: `Failed to list streams: ${ex}`,
173
+ namespace: opts.namespace,
174
+ projectId,
175
+ orgId: opts.orgId,
129
176
  });
130
-
131
- tui.table(tableData, [
132
- { name: 'Namespace', alignment: 'left' },
133
- { name: 'ID', alignment: 'left' },
134
- { name: 'Size', alignment: 'right' },
135
- { name: 'Metadata', alignment: 'left' },
136
- { name: 'URL', alignment: 'left' },
137
- ]);
138
-
139
- tui.info(`Total: ${result.total} ${tui.plural(result.total, 'stream', 'streams')}`);
140
177
  }
141
-
142
- return {
143
- streams: result.streams,
144
- total: result.total,
145
- };
146
178
  },
147
179
  });
148
180
 
@@ -4,6 +4,16 @@ import { loadProjectSDKKey } from '../../../config';
4
4
  import type { AuthData, Config, GlobalOptions, ProjectConfig } from '../../../types';
5
5
  import * as tui from '../../../tui';
6
6
 
7
+ /**
8
+ * Create a storage adapter for stream operations that create new streams.
9
+ * This is used by the `stream create` command.
10
+ *
11
+ * For listing and deleting streams, use the CLI API endpoints (streamList, streamGet)
12
+ * which handle org resolution automatically based on user's org membership.
13
+ *
14
+ * @param ctx - Command context including auth, region, and optional project context
15
+ * @returns A StreamStorageService instance configured for the org
16
+ */
7
17
  export async function createStorageAdapter(ctx: {
8
18
  logger: Logger;
9
19
  projectDir: string;
@@ -26,8 +36,7 @@ export async function createStorageAdapter(ctx: {
26
36
  } else {
27
37
  // Use CLI key auth with orgId query param
28
38
  // Pulse server expects orgId as query param for CLI tokens (ck_*)
29
- // IMPORTANT: For CLI key auth, prefer user's org ID over project's org ID
30
- // because the CLI key is validated against the user's orgs, not the project's org
39
+ // For create operations, we need to know which org to create the stream in
31
40
  const orgId =
32
41
  ctx.options.orgId ??
33
42
  process.env.AGENTUITY_CLOUD_ORG_ID ??
@@ -36,7 +45,7 @@ export async function createStorageAdapter(ctx: {
36
45
 
37
46
  if (!orgId) {
38
47
  tui.fatal(
39
- 'Organization ID is required. Either run from a project directory, use --org-id flag, or set AGENTUITY_CLOUD_ORG_ID environment variable.'
48
+ 'Organization ID is required for creating streams. Either run from a project directory, use --org-id flag, or set AGENTUITY_CLOUD_ORG_ID environment variable.'
40
49
  );
41
50
  }
42
51
 
@@ -61,3 +70,30 @@ export async function createStorageAdapter(ctx: {
61
70
 
62
71
  return new StreamStorageService(baseUrl, adapter);
63
72
  }
73
+
74
+ /**
75
+ * Create a storage adapter for a specific org ID.
76
+ * Used when listing streams across multiple orgs.
77
+ */
78
+ export function createStorageAdapterForOrg(ctx: {
79
+ logger: Logger;
80
+ auth: AuthData;
81
+ region: string;
82
+ orgId: string;
83
+ }) {
84
+ const baseUrl = getServiceUrls(ctx.region).stream;
85
+
86
+ const adapter = createServerFetchAdapter(
87
+ {
88
+ headers: {
89
+ Authorization: `Bearer ${ctx.auth.apiKey}`,
90
+ },
91
+ queryParams: { orgId: ctx.orgId },
92
+ },
93
+ ctx.logger
94
+ );
95
+
96
+ ctx.logger.trace('using stream url: %s for org: %s', baseUrl, ctx.orgId);
97
+
98
+ return new StreamStorageService(baseUrl, adapter);
99
+ }
@@ -1,6 +1,7 @@
1
1
  import { type Logger, VectorStorageService } from '@agentuity/core';
2
- import { createServerFetchAdapter, getServiceUrls } from '@agentuity/server';
2
+ import { createServerFetchAdapter } from '@agentuity/server';
3
3
  import type { AuthData, Config, GlobalOptions, ProjectConfig } from '../../../types';
4
+ import { getCatalystUrl } from '../../../catalyst';
4
5
  import * as tui from '../../../tui';
5
6
 
6
7
  export function createStorageAdapter(ctx: {
@@ -31,7 +32,6 @@ export function createStorageAdapter(ctx: {
31
32
  ctx.logger
32
33
  );
33
34
 
34
- const urls = getServiceUrls(ctx.region);
35
- const baseUrl = urls.catalyst;
35
+ const baseUrl = getCatalystUrl(ctx.region);
36
36
  return new VectorStorageService(baseUrl, adapter);
37
37
  }
@@ -1177,10 +1177,10 @@ export const command = createCommand({
1177
1177
  const text = new TextDecoder().decode(chunk);
1178
1178
  const trimmed = text.trim();
1179
1179
 
1180
- // Check for heartbeat port announcement
1181
- const match = trimmed.match(/^HEARTBEAT_PORT=(\d+)$/m);
1182
- if (match?.[1]) {
1183
- const heartbeatPort = parseInt(match[1], 10);
1180
+ // Check for heartbeat port announcement
1181
+ const match = trimmed.match(/^HEARTBEAT_PORT=(\d+)$/m);
1182
+ if (match?.[1]) {
1183
+ const heartbeatPort = parseInt(match[1], 10);
1184
1184
  logger.debug('Gravity heartbeat port detected: %d', heartbeatPort);
1185
1185
 
1186
1186
  // Start sending heartbeats every 5 seconds
@@ -252,11 +252,11 @@ export const addSubcommand = createSubcommand({
252
252
 
253
253
  const sortedOrgs = [...orgStatuses].sort((a, b) => a.name.localeCompare(b.name));
254
254
 
255
- const firstOrg = orgs[0];
256
- if (orgs.length === 1 && firstOrg) {
257
- orgId = firstOrg.id;
258
- selectedOrg = firstOrg;
259
- } else {
255
+ const firstOrg = orgs[0];
256
+ if (orgs.length === 1 && firstOrg) {
257
+ orgId = firstOrg.id;
258
+ selectedOrg = firstOrg;
259
+ } else {
260
260
  const choices = sortedOrgs.map((org) => {
261
261
  const count = org.integrations.length;
262
262
  const suffix =
@@ -53,13 +53,13 @@ export const listSubcommand = createSubcommand({
53
53
  return [];
54
54
  }
55
55
 
56
- // Select org
57
- let orgId = opts.org;
58
- if (!orgId) {
59
- const firstOrg = orgs[0];
60
- if (orgs.length === 1 && firstOrg) {
61
- orgId = firstOrg.id;
62
- } else {
56
+ // Select org
57
+ let orgId = opts.org;
58
+ if (!orgId) {
59
+ const firstOrg = orgs[0];
60
+ if (orgs.length === 1 && firstOrg) {
61
+ orgId = firstOrg.id;
62
+ } else {
63
63
  tui.newline();
64
64
  const orgChoices = orgs.map((o) => ({
65
65
  name: o.id,
@@ -0,0 +1,145 @@
1
+ import { z } from 'zod';
2
+ import { listResources } from '@agentuity/server';
3
+ import { createSubcommand } from '../../../types';
4
+ import * as tui from '../../../tui';
5
+ import { createPrompt } from '../../../tui';
6
+ import { getCatalystAPIClient } from '../../../config';
7
+ import { getCommand } from '../../../command-prefix';
8
+ import { isDryRunMode, outputDryRun } from '../../../explain';
9
+ import { ErrorCode } from '../../../errors';
10
+ import { addResourceEnvVars } from '../../../env-util';
11
+
12
+ export const databaseSubcommand = createSubcommand({
13
+ name: 'database',
14
+ aliases: ['db'],
15
+ description: 'Link an existing database to the current project',
16
+ tags: ['mutating', 'fast', 'requires-auth', 'requires-project'],
17
+ idempotent: true,
18
+ requires: { auth: true, org: true, region: true, project: true },
19
+ examples: [
20
+ {
21
+ command: getCommand('project add database'),
22
+ description: 'Select a database interactively',
23
+ },
24
+ {
25
+ command: getCommand('project add db my-db'),
26
+ description: 'Link a specific database by name',
27
+ },
28
+ {
29
+ command: getCommand('--dry-run project add database my-db'),
30
+ description: 'Preview linking without making changes',
31
+ },
32
+ ],
33
+ schema: {
34
+ args: z.object({
35
+ name: z.string().optional().describe('Database name to link'),
36
+ }),
37
+ options: z.object({}),
38
+ response: z.object({
39
+ success: z.boolean().describe('Whether linking succeeded'),
40
+ name: z.string().describe('Linked database name'),
41
+ }),
42
+ },
43
+
44
+ async handler(ctx) {
45
+ const { logger, args, orgId, region, auth, options, projectDir } = ctx;
46
+
47
+ if (isDryRunMode(options)) {
48
+ const message = args.name
49
+ ? `Would link database "${args.name}" to project in ${projectDir}`
50
+ : `Would prompt to select a database to link to project in ${projectDir}`;
51
+ outputDryRun(message, options);
52
+ if (!options.json) {
53
+ tui.newline();
54
+ tui.info('[DRY RUN] Database linking skipped');
55
+ }
56
+ return {
57
+ success: false,
58
+ name: args.name || 'dry-run-db',
59
+ };
60
+ }
61
+
62
+ const catalystClient = getCatalystAPIClient(logger, auth, region);
63
+
64
+ const resources = await tui.spinner({
65
+ message: 'Fetching databases',
66
+ clearOnSuccess: true,
67
+ callback: async () => {
68
+ return listResources(catalystClient, orgId, region);
69
+ },
70
+ });
71
+
72
+ const availableDatabases = resources.db.filter((db) => !db.internal);
73
+
74
+ if (availableDatabases.length === 0) {
75
+ tui.fatal(
76
+ 'No databases available. Create one first with: ' +
77
+ tui.bold(getCommand('cloud db create')),
78
+ ErrorCode.RESOURCE_NOT_FOUND
79
+ );
80
+ }
81
+
82
+ let selectedDatabase: (typeof availableDatabases)[0] | undefined;
83
+
84
+ if (args.name) {
85
+ selectedDatabase = availableDatabases.find((db) => db.name === args.name);
86
+ if (!selectedDatabase) {
87
+ const availableNames = availableDatabases.map((db) => db.name).join(', ');
88
+ tui.fatal(
89
+ `Database "${args.name}" not found. Available databases: ${availableNames}`,
90
+ ErrorCode.RESOURCE_NOT_FOUND
91
+ );
92
+ }
93
+ } else {
94
+ const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY;
95
+ if (isHeadless) {
96
+ tui.fatal(
97
+ 'Database name is required in non-interactive mode. Usage: ' +
98
+ tui.bold(getCommand('project add database <name>')),
99
+ ErrorCode.MISSING_ARGUMENT
100
+ );
101
+ }
102
+
103
+ const prompt = createPrompt();
104
+ const selected = await prompt.select<string>({
105
+ message: 'Select a database to link',
106
+ options: availableDatabases.map((db) => ({
107
+ value: db.name,
108
+ label: `${tui.tuiColors.primary(db.name)}`,
109
+ })),
110
+ });
111
+
112
+ // Ensure stdin is paused so process can exit
113
+ if (process.stdin.isTTY) {
114
+ process.stdin.pause();
115
+ }
116
+
117
+ if (!selected) {
118
+ tui.fatal('Operation cancelled', ErrorCode.USER_CANCELLED);
119
+ }
120
+
121
+ selectedDatabase = availableDatabases.find((db) => db.name === selected);
122
+ }
123
+
124
+ if (!selectedDatabase) {
125
+ tui.fatal('Failed to select database', ErrorCode.INTERNAL_ERROR);
126
+ }
127
+
128
+ if (selectedDatabase.env && Object.keys(selectedDatabase.env).length > 0) {
129
+ await addResourceEnvVars(projectDir, selectedDatabase.env);
130
+ if (!options.json) {
131
+ tui.success(`Linked database: ${tui.bold(selectedDatabase.name)}`);
132
+ tui.info('Environment variables written to .env');
133
+ }
134
+ } else {
135
+ if (!options.json) {
136
+ tui.warning(`Database "${selectedDatabase.name}" has no environment variables to add`);
137
+ }
138
+ }
139
+
140
+ return {
141
+ success: true,
142
+ name: selectedDatabase.name,
143
+ };
144
+ },
145
+ });
@@ -0,0 +1,181 @@
1
+ import { z } from 'zod';
2
+ import { createSubcommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { createPrompt } from '../../../tui';
5
+ import { getCommand } from '../../../command-prefix';
6
+ import { isDryRunMode, outputDryRun } from '../../../explain';
7
+ import { ErrorCode } from '../../../errors';
8
+ import { loadProjectConfig, updateProjectConfig } from '../../../config';
9
+ import { checkCustomDomainForDNS, isSuccess, isMisconfigured, isError } from '../../../domain';
10
+
11
+ export const domainSubcommand = createSubcommand({
12
+ name: 'domain',
13
+ aliases: ['dns'],
14
+ description: 'Add a custom domain to the current project',
15
+ tags: ['mutating', 'slow', 'requires-auth', 'requires-project'],
16
+ idempotent: true,
17
+ requires: { auth: true, org: true, region: true, project: true },
18
+ examples: [
19
+ {
20
+ command: getCommand('project add domain example.com'),
21
+ description: 'Add a custom domain',
22
+ },
23
+ {
24
+ command: getCommand('project add domain example.com --skip-validation'),
25
+ description: 'Add a domain without DNS validation',
26
+ },
27
+ {
28
+ command: getCommand('--dry-run project add domain example.com'),
29
+ description: 'Preview adding a domain without making changes',
30
+ },
31
+ ],
32
+ schema: {
33
+ args: z.object({
34
+ domain: z.string().describe('Domain name to add'),
35
+ }),
36
+ options: z.object({
37
+ skipValidation: z
38
+ .boolean()
39
+ .optional()
40
+ .describe('Skip DNS validation (domain will be validated on deploy)'),
41
+ }),
42
+ response: z.object({
43
+ success: z.boolean().describe('Whether adding the domain succeeded'),
44
+ domain: z.string().describe('Added domain name'),
45
+ domains: z.array(z.string()).describe('All configured domains'),
46
+ dryRun: z.boolean().optional().describe('True if this was a dry-run preview'),
47
+ }),
48
+ },
49
+
50
+ async handler(ctx) {
51
+ const { args, opts, options, projectDir, config, logger } = ctx;
52
+
53
+ if (isDryRunMode(options)) {
54
+ const message = `Would add domain "${args.domain}" to project in ${projectDir}`;
55
+ outputDryRun(message, options);
56
+ if (!options.json) {
57
+ tui.newline();
58
+ tui.info('[DRY RUN] Domain addition skipped');
59
+ }
60
+ return {
61
+ success: true,
62
+ dryRun: true,
63
+ domain: args.domain,
64
+ domains: [],
65
+ };
66
+ }
67
+
68
+ const project = await loadProjectConfig(projectDir, config);
69
+ const existingDomains = project.deployment?.domains ?? [];
70
+
71
+ const domain = args.domain.toLowerCase().trim();
72
+
73
+ // Validate domain format
74
+ const domainRegex =
75
+ /^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?)+$/;
76
+ if (!domainRegex.test(domain)) {
77
+ logger.fatal('Please enter a valid domain name', ErrorCode.VALIDATION_FAILED);
78
+ }
79
+
80
+ // Check if domain already exists
81
+ if (existingDomains.includes(domain)) {
82
+ if (!options.json) {
83
+ tui.warning(`Domain "${domain}" is already configured for this project`);
84
+ }
85
+ return {
86
+ success: false,
87
+ domain,
88
+ domains: existingDomains,
89
+ };
90
+ }
91
+
92
+ // Validate DNS unless skipped
93
+ if (!opts?.skipValidation) {
94
+ const results = await tui.spinner({
95
+ message: `Checking DNS for ${domain}`,
96
+ clearOnSuccess: true,
97
+ callback: async () => {
98
+ return checkCustomDomainForDNS(project.projectId, [domain], config);
99
+ },
100
+ });
101
+
102
+ // Handle empty results - DNS validation service returned no data
103
+ if (results.length === 0) {
104
+ logger.fatal(
105
+ `DNS validation failed: no response from DNS validation service for domain "${domain}". ` +
106
+ 'Use --skip-validation to add the domain without DNS verification.',
107
+ ErrorCode.VALIDATION_FAILED
108
+ );
109
+ }
110
+
111
+ // Safe to assert non-null since we've checked results.length above
112
+ // (logger.fatal never returns - it exits the process)
113
+ const result = results[0]!;
114
+ if (!isSuccess(result)) {
115
+ if (isError(result)) {
116
+ logger.fatal(`DNS validation failed: ${result.error}`, ErrorCode.VALIDATION_FAILED);
117
+ }
118
+
119
+ tui.newline();
120
+ tui.warning('DNS record not yet configured. Please add the following CNAME record:');
121
+ tui.newline();
122
+ tui.output(` ${tui.colorInfo('Domain:')} ${tui.colorPrimary(result.domain)}`);
123
+ tui.output(` ${tui.colorInfo('Type:')} ${tui.colorPrimary(result.recordType)}`);
124
+ tui.output(` ${tui.colorInfo('Target:')} ${tui.colorPrimary(result.target)}`);
125
+ tui.newline();
126
+
127
+ if (isMisconfigured(result)) {
128
+ tui.error(`Current configuration: ${result.misconfigured}`);
129
+ tui.newline();
130
+ }
131
+
132
+ // In non-interactive mode, fail with guidance
133
+ const isHeadless = !process.stdin.isTTY || !process.stdout.isTTY;
134
+ if (isHeadless) {
135
+ logger.fatal(
136
+ 'DNS is not configured. Add the DNS record above and try again, or use --skip-validation',
137
+ ErrorCode.VALIDATION_FAILED
138
+ );
139
+ }
140
+
141
+ const prompt = createPrompt();
142
+ const proceed = await prompt.confirm({
143
+ message: 'Add domain anyway? (DNS will be validated on deploy)',
144
+ initial: true,
145
+ });
146
+
147
+ if (process.stdin.isTTY) {
148
+ process.stdin.pause();
149
+ }
150
+
151
+ if (!proceed) {
152
+ logger.fatal('Operation cancelled', ErrorCode.USER_CANCELLED);
153
+ }
154
+ }
155
+ }
156
+
157
+ // Update the project config
158
+ const updatedDomains = [...existingDomains, domain];
159
+ await updateProjectConfig(
160
+ projectDir,
161
+ {
162
+ deployment: {
163
+ ...project.deployment,
164
+ domains: updatedDomains,
165
+ },
166
+ },
167
+ config
168
+ );
169
+
170
+ if (!options.json) {
171
+ tui.success(`Added domain: ${tui.bold(domain)}`);
172
+ tui.info('Domain will be active after next deployment');
173
+ }
174
+
175
+ return {
176
+ success: true,
177
+ domain,
178
+ domains: updatedDomains,
179
+ };
180
+ },
181
+ });
@@ -0,0 +1,35 @@
1
+ import { createCommand } from '../../../types';
2
+ import { databaseSubcommand } from './database';
3
+ import { domainSubcommand } from './domain';
4
+ import { storageSubcommand } from './storage';
5
+ import { getCommand } from '../../../command-prefix';
6
+
7
+ export const addCommand = createCommand({
8
+ name: 'add',
9
+ aliases: ['link'],
10
+ description: 'Link existing cloud resources to the current project',
11
+ tags: ['fast', 'requires-auth', 'requires-project'],
12
+ examples: [
13
+ {
14
+ command: getCommand('project add database'),
15
+ description: 'Link an existing database to the project',
16
+ },
17
+ {
18
+ command: getCommand('project add storage'),
19
+ description: 'Link an existing storage bucket to the project',
20
+ },
21
+ {
22
+ command: getCommand('project add domain example.com'),
23
+ description: 'Add a custom domain to the project',
24
+ },
25
+ {
26
+ command: getCommand('project add database my-db'),
27
+ description: 'Link a specific database by name',
28
+ },
29
+ {
30
+ command: getCommand('project add storage my-bucket'),
31
+ description: 'Link a specific storage bucket by name',
32
+ },
33
+ ],
34
+ subcommands: [databaseSubcommand, domainSubcommand, storageSubcommand],
35
+ });