@agentuity/cli 0.0.100 → 0.0.102

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 (264) hide show
  1. package/AGENTS.md +19 -188
  2. package/bin/cli.ts +13 -6
  3. package/dist/api.d.ts +1 -0
  4. package/dist/api.d.ts.map +1 -1
  5. package/dist/api.js +1 -1
  6. package/dist/api.js.map +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +41 -12
  9. package/dist/cli.js.map +1 -1
  10. package/dist/cmd/ai/index.d.ts.map +1 -1
  11. package/dist/cmd/ai/index.js +6 -1
  12. package/dist/cmd/ai/index.js.map +1 -1
  13. package/dist/cmd/ai/prompt/agent.d.ts +7 -0
  14. package/dist/cmd/ai/prompt/agent.d.ts.map +1 -1
  15. package/dist/cmd/ai/prompt/agent.js +12 -323
  16. package/dist/cmd/ai/prompt/agent.js.map +1 -1
  17. package/dist/cmd/ai/prompt/api.d.ts +7 -0
  18. package/dist/cmd/ai/prompt/api.d.ts.map +1 -1
  19. package/dist/cmd/ai/prompt/api.js +12 -260
  20. package/dist/cmd/ai/prompt/api.js.map +1 -1
  21. package/dist/cmd/ai/prompt/version.d.ts +35 -0
  22. package/dist/cmd/ai/prompt/version.d.ts.map +1 -0
  23. package/dist/cmd/ai/prompt/version.js +55 -0
  24. package/dist/cmd/ai/prompt/version.js.map +1 -0
  25. package/dist/cmd/ai/prompt/web.d.ts +7 -0
  26. package/dist/cmd/ai/prompt/web.d.ts.map +1 -1
  27. package/dist/cmd/ai/prompt/web.js +12 -283
  28. package/dist/cmd/ai/prompt/web.js.map +1 -1
  29. package/dist/cmd/ai/skills/generate.d.ts +3 -0
  30. package/dist/cmd/ai/skills/generate.d.ts.map +1 -0
  31. package/dist/cmd/ai/skills/generate.js +65 -0
  32. package/dist/cmd/ai/skills/generate.js.map +1 -0
  33. package/dist/cmd/ai/skills/generator.d.ts +4 -0
  34. package/dist/cmd/ai/skills/generator.d.ts.map +1 -0
  35. package/dist/cmd/ai/skills/generator.js +402 -0
  36. package/dist/cmd/ai/skills/generator.js.map +1 -0
  37. package/dist/cmd/ai/skills/index.d.ts +4 -0
  38. package/dist/cmd/ai/skills/index.d.ts.map +1 -0
  39. package/dist/cmd/ai/skills/index.js +21 -0
  40. package/dist/cmd/ai/skills/index.js.map +1 -0
  41. package/dist/cmd/auth/signup.d.ts.map +1 -1
  42. package/dist/cmd/auth/signup.js +1 -0
  43. package/dist/cmd/auth/signup.js.map +1 -1
  44. package/dist/cmd/build/ast.d.ts +2 -1
  45. package/dist/cmd/build/ast.d.ts.map +1 -1
  46. package/dist/cmd/build/ast.js +135 -47
  47. package/dist/cmd/build/ast.js.map +1 -1
  48. package/dist/cmd/build/entry-generator.d.ts.map +1 -1
  49. package/dist/cmd/build/entry-generator.js +255 -188
  50. package/dist/cmd/build/entry-generator.js.map +1 -1
  51. package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -1
  52. package/dist/cmd/build/vite/agent-discovery.js +103 -45
  53. package/dist/cmd/build/vite/agent-discovery.js.map +1 -1
  54. package/dist/cmd/build/vite/bun-dev-server.d.ts +7 -1
  55. package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
  56. package/dist/cmd/build/vite/bun-dev-server.js +52 -26
  57. package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
  58. package/dist/cmd/build/vite/docs-generator.d.ts +13 -0
  59. package/dist/cmd/build/vite/docs-generator.d.ts.map +1 -0
  60. package/dist/cmd/build/vite/docs-generator.js +81 -0
  61. package/dist/cmd/build/vite/docs-generator.js.map +1 -0
  62. package/dist/cmd/build/vite/index.d.ts +3 -3
  63. package/dist/cmd/build/vite/index.d.ts.map +1 -1
  64. package/dist/cmd/build/vite/index.js +9 -7
  65. package/dist/cmd/build/vite/index.js.map +1 -1
  66. package/dist/cmd/build/vite/lifecycle-generator.d.ts +1 -1
  67. package/dist/cmd/build/vite/lifecycle-generator.d.ts.map +1 -1
  68. package/dist/cmd/build/vite/lifecycle-generator.js +19 -5
  69. package/dist/cmd/build/vite/lifecycle-generator.js.map +1 -1
  70. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
  71. package/dist/cmd/build/vite/metadata-generator.js +203 -7
  72. package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
  73. package/dist/cmd/build/vite/prompt-generator.d.ts +23 -0
  74. package/dist/cmd/build/vite/prompt-generator.d.ts.map +1 -0
  75. package/dist/cmd/build/vite/prompt-generator.js +123 -0
  76. package/dist/cmd/build/vite/prompt-generator.js.map +1 -0
  77. package/dist/cmd/build/vite/registry-generator.d.ts +3 -3
  78. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
  79. package/dist/cmd/build/vite/registry-generator.js +644 -103
  80. package/dist/cmd/build/vite/registry-generator.js.map +1 -1
  81. package/dist/cmd/build/vite/route-discovery.d.ts +4 -0
  82. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
  83. package/dist/cmd/build/vite/route-discovery.js.map +1 -1
  84. package/dist/cmd/build/vite/server-bundler.d.ts +4 -0
  85. package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -1
  86. package/dist/cmd/build/vite/server-bundler.js +63 -17
  87. package/dist/cmd/build/vite/server-bundler.js.map +1 -1
  88. package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
  89. package/dist/cmd/build/vite/vite-asset-server-config.js +4 -0
  90. package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
  91. package/dist/cmd/build/vite/vite-builder.d.ts +1 -1
  92. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  93. package/dist/cmd/build/vite/vite-builder.js +118 -96
  94. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  95. package/dist/cmd/build/vite-bundler.js +6 -6
  96. package/dist/cmd/build/vite-bundler.js.map +1 -1
  97. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  98. package/dist/cmd/cloud/deploy.js +89 -32
  99. package/dist/cmd/cloud/deploy.js.map +1 -1
  100. package/dist/cmd/cloud/keyvalue/create-namespace.d.ts.map +1 -1
  101. package/dist/cmd/cloud/keyvalue/create-namespace.js +3 -1
  102. package/dist/cmd/cloud/keyvalue/create-namespace.js.map +1 -1
  103. package/dist/cmd/cloud/keyvalue/delete-namespace.d.ts.map +1 -1
  104. package/dist/cmd/cloud/keyvalue/delete-namespace.js +3 -1
  105. package/dist/cmd/cloud/keyvalue/delete-namespace.js.map +1 -1
  106. package/dist/cmd/cloud/keyvalue/delete.d.ts.map +1 -1
  107. package/dist/cmd/cloud/keyvalue/delete.js +3 -1
  108. package/dist/cmd/cloud/keyvalue/delete.js.map +1 -1
  109. package/dist/cmd/cloud/keyvalue/set.d.ts.map +1 -1
  110. package/dist/cmd/cloud/keyvalue/set.js +4 -2
  111. package/dist/cmd/cloud/keyvalue/set.js.map +1 -1
  112. package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
  113. package/dist/cmd/cloud/stream/get.js +2 -13
  114. package/dist/cmd/cloud/stream/get.js.map +1 -1
  115. package/dist/cmd/cloud/vector/delete-namespace.d.ts +3 -0
  116. package/dist/cmd/cloud/vector/delete-namespace.d.ts.map +1 -0
  117. package/dist/cmd/cloud/vector/delete-namespace.js +77 -0
  118. package/dist/cmd/cloud/vector/delete-namespace.js.map +1 -0
  119. package/dist/cmd/cloud/vector/index.d.ts.map +1 -1
  120. package/dist/cmd/cloud/vector/index.js +21 -4
  121. package/dist/cmd/cloud/vector/index.js.map +1 -1
  122. package/dist/cmd/cloud/vector/list-namespaces.d.ts +3 -0
  123. package/dist/cmd/cloud/vector/list-namespaces.d.ts.map +1 -0
  124. package/dist/cmd/cloud/vector/list-namespaces.js +42 -0
  125. package/dist/cmd/cloud/vector/list-namespaces.js.map +1 -0
  126. package/dist/cmd/cloud/vector/stats.d.ts +3 -0
  127. package/dist/cmd/cloud/vector/stats.d.ts.map +1 -0
  128. package/dist/cmd/cloud/vector/stats.js +142 -0
  129. package/dist/cmd/cloud/vector/stats.js.map +1 -0
  130. package/dist/cmd/cloud/vector/upsert.d.ts +3 -0
  131. package/dist/cmd/cloud/vector/upsert.d.ts.map +1 -0
  132. package/dist/cmd/cloud/vector/upsert.js +192 -0
  133. package/dist/cmd/cloud/vector/upsert.js.map +1 -0
  134. package/dist/cmd/dev/file-watcher.d.ts.map +1 -1
  135. package/dist/cmd/dev/file-watcher.js +94 -33
  136. package/dist/cmd/dev/file-watcher.js.map +1 -1
  137. package/dist/cmd/dev/index.d.ts.map +1 -1
  138. package/dist/cmd/dev/index.js +298 -61
  139. package/dist/cmd/dev/index.js.map +1 -1
  140. package/dist/cmd/dev/skills.d.ts +10 -0
  141. package/dist/cmd/dev/skills.d.ts.map +1 -0
  142. package/dist/cmd/dev/skills.js +57 -0
  143. package/dist/cmd/dev/skills.js.map +1 -0
  144. package/dist/cmd/dev/sync.d.ts.map +1 -1
  145. package/dist/cmd/dev/sync.js +19 -3
  146. package/dist/cmd/dev/sync.js.map +1 -1
  147. package/dist/cmd/index.d.ts.map +1 -1
  148. package/dist/cmd/index.js +1 -0
  149. package/dist/cmd/index.js.map +1 -1
  150. package/dist/cmd/project/create.d.ts.map +1 -1
  151. package/dist/cmd/project/create.js +3 -0
  152. package/dist/cmd/project/create.js.map +1 -1
  153. package/dist/cmd/project/template-flow.d.ts +1 -0
  154. package/dist/cmd/project/template-flow.d.ts.map +1 -1
  155. package/dist/cmd/project/template-flow.js +30 -5
  156. package/dist/cmd/project/template-flow.js.map +1 -1
  157. package/dist/cmd/setup/index.d.ts.map +1 -1
  158. package/dist/cmd/setup/index.js +1 -0
  159. package/dist/cmd/setup/index.js.map +1 -1
  160. package/dist/cmd/upgrade/index.d.ts +15 -0
  161. package/dist/cmd/upgrade/index.d.ts.map +1 -1
  162. package/dist/cmd/upgrade/index.js +59 -4
  163. package/dist/cmd/upgrade/index.js.map +1 -1
  164. package/dist/config.d.ts.map +1 -1
  165. package/dist/config.js +8 -0
  166. package/dist/config.js.map +1 -1
  167. package/dist/domain.d.ts +45 -0
  168. package/dist/domain.d.ts.map +1 -0
  169. package/dist/domain.js +200 -0
  170. package/dist/domain.js.map +1 -0
  171. package/dist/index.d.ts +0 -1
  172. package/dist/index.d.ts.map +1 -1
  173. package/dist/index.js +0 -1
  174. package/dist/index.js.map +1 -1
  175. package/dist/schema-generator.d.ts +2 -0
  176. package/dist/schema-generator.d.ts.map +1 -1
  177. package/dist/schema-generator.js +18 -0
  178. package/dist/schema-generator.js.map +1 -1
  179. package/dist/steps.d.ts +1 -1
  180. package/dist/steps.d.ts.map +1 -1
  181. package/dist/steps.js +16 -5
  182. package/dist/steps.js.map +1 -1
  183. package/dist/tui/prompt.d.ts +1 -2
  184. package/dist/tui/prompt.d.ts.map +1 -1
  185. package/dist/tui/prompt.js +8 -4
  186. package/dist/tui/prompt.js.map +1 -1
  187. package/dist/tui.d.ts +16 -0
  188. package/dist/tui.d.ts.map +1 -1
  189. package/dist/tui.js +23 -2
  190. package/dist/tui.js.map +1 -1
  191. package/dist/types.d.ts +9 -2
  192. package/dist/types.d.ts.map +1 -1
  193. package/dist/types.js +3 -3
  194. package/dist/types.js.map +1 -1
  195. package/package.json +5 -8
  196. package/src/api.ts +1 -1
  197. package/src/cli.ts +47 -12
  198. package/src/cmd/ai/index.ts +6 -1
  199. package/src/cmd/ai/prompt/agent.md +306 -0
  200. package/src/cmd/ai/prompt/agent.ts +12 -322
  201. package/src/cmd/ai/prompt/api.md +360 -0
  202. package/src/cmd/ai/prompt/api.ts +13 -260
  203. package/src/cmd/ai/prompt/version.ts +61 -0
  204. package/src/cmd/ai/prompt/web.md +509 -0
  205. package/src/cmd/ai/prompt/web.ts +12 -282
  206. package/src/cmd/ai/skills/generate.ts +75 -0
  207. package/src/cmd/ai/skills/generator.ts +519 -0
  208. package/src/cmd/ai/skills/index.ts +23 -0
  209. package/src/cmd/auth/signup.ts +1 -0
  210. package/src/cmd/build/ast.ts +161 -48
  211. package/src/cmd/build/entry-generator.ts +258 -187
  212. package/src/cmd/build/vite/agent-discovery.ts +151 -58
  213. package/src/cmd/build/vite/bun-dev-server.ts +57 -27
  214. package/src/cmd/build/vite/docs-generator.ts +87 -0
  215. package/src/cmd/build/vite/index.ts +9 -7
  216. package/src/cmd/build/vite/lifecycle-generator.ts +19 -5
  217. package/src/cmd/build/vite/metadata-generator.ts +251 -7
  218. package/src/cmd/build/vite/prompt-generator.ts +169 -0
  219. package/src/cmd/build/vite/registry-generator.ts +750 -108
  220. package/src/cmd/build/vite/route-discovery.ts +4 -0
  221. package/src/cmd/build/vite/server-bundler.ts +73 -23
  222. package/src/cmd/build/vite/vite-asset-server-config.ts +5 -0
  223. package/src/cmd/build/vite/vite-builder.ts +134 -100
  224. package/src/cmd/build/vite-bundler.ts +6 -6
  225. package/src/cmd/cloud/deploy.ts +114 -36
  226. package/src/cmd/cloud/keyvalue/create-namespace.ts +3 -1
  227. package/src/cmd/cloud/keyvalue/delete-namespace.ts +3 -1
  228. package/src/cmd/cloud/keyvalue/delete.ts +3 -1
  229. package/src/cmd/cloud/keyvalue/set.ts +4 -2
  230. package/src/cmd/cloud/stream/get.ts +2 -9
  231. package/src/cmd/cloud/vector/delete-namespace.ts +89 -0
  232. package/src/cmd/cloud/vector/index.ts +21 -4
  233. package/src/cmd/cloud/vector/list-namespaces.ts +46 -0
  234. package/src/cmd/cloud/vector/stats.ts +160 -0
  235. package/src/cmd/cloud/vector/upsert.ts +216 -0
  236. package/src/cmd/dev/file-watcher.ts +109 -34
  237. package/src/cmd/dev/index.ts +364 -60
  238. package/src/cmd/dev/skills.ts +82 -0
  239. package/src/cmd/dev/sync.ts +41 -6
  240. package/src/cmd/index.ts +1 -0
  241. package/src/cmd/project/create.ts +3 -0
  242. package/src/cmd/project/template-flow.ts +37 -5
  243. package/src/cmd/setup/index.ts +1 -0
  244. package/src/cmd/upgrade/index.ts +68 -4
  245. package/src/config.ts +9 -0
  246. package/src/domain.ts +273 -0
  247. package/src/index.ts +0 -5
  248. package/src/runtime-bootstrap.md +1 -1
  249. package/src/schema-generator.ts +23 -0
  250. package/src/steps.ts +16 -5
  251. package/src/tui/prompt.ts +11 -5
  252. package/src/tui.ts +21 -2
  253. package/src/types/md.d.ts +8 -0
  254. package/src/types.ts +12 -3
  255. package/dist/cmd/cloud/domain.d.ts +0 -17
  256. package/dist/cmd/cloud/domain.d.ts.map +0 -1
  257. package/dist/cmd/cloud/domain.js +0 -79
  258. package/dist/cmd/cloud/domain.js.map +0 -1
  259. package/dist/runtime-bootstrap.d.ts +0 -56
  260. package/dist/runtime-bootstrap.d.ts.map +0 -1
  261. package/dist/runtime-bootstrap.js +0 -95
  262. package/dist/runtime-bootstrap.js.map +0 -1
  263. package/src/cmd/cloud/domain.ts +0 -100
  264. package/src/runtime-bootstrap.ts +0 -131
@@ -6,13 +6,15 @@ import { tmpdir } from 'node:os';
6
6
  import { StructuredError } from '@agentuity/core';
7
7
  import { isRunningFromExecutable } from '../upgrade';
8
8
  import { createSubcommand } from '../../types';
9
+ import { getUserAgent } from '../../api';
9
10
  import * as tui from '../../tui';
10
- import { saveProjectDir, getDefaultConfigDir } from '../../config';
11
+ import { saveProjectDir, getDefaultConfigDir, loadProjectSDKKey } from '../../config';
11
12
  import {
12
13
  runSteps,
13
14
  stepSuccess,
14
15
  stepSkipped,
15
16
  stepError,
17
+ pauseStepUI,
16
18
  type Step,
17
19
  type StepContext,
18
20
  } from '../../steps';
@@ -40,7 +42,7 @@ import {
40
42
  import { zipDir } from '../../utils/zip';
41
43
  import { encryptFIPSKEMDEMStream } from '../../crypto/box';
42
44
  import { getCommand } from '../../command-prefix';
43
- import { checkCustomDomainForDNS } from './domain';
45
+ import * as domain from '../../domain';
44
46
  import { DeployOptionsSchema } from '../../schemas/deploy';
45
47
  import { ErrorCode } from '../../errors';
46
48
 
@@ -106,6 +108,40 @@ export const deploySubcommand = createSubcommand({
106
108
  let statusResult: DeploymentStatusResult | undefined;
107
109
  const logs: string[] = [];
108
110
 
111
+ // Check for pre-created deployment from CI/Nova
112
+ const deploymentEnv = process.env.AGENTUITY_DEPLOYMENT;
113
+ let useExistingDeployment = false;
114
+ if (deploymentEnv) {
115
+ const ExistingDeploymentSchema = z.object({
116
+ id: z.string(),
117
+ orgId: z.string(),
118
+ publicKey: z.string(),
119
+ });
120
+ try {
121
+ const parsed = JSON.parse(deploymentEnv);
122
+ const result = ExistingDeploymentSchema.safeParse(parsed);
123
+ if (result.success) {
124
+ deployment = result.data;
125
+ useExistingDeployment = true;
126
+ logger.info(`Using existing deployment: ${result.data.id}`);
127
+ } else {
128
+ const errors = result.error.issues.map((i) => `${i.path.join('.')}: ${i.message}`).join(', ');
129
+ logger.warn(`Invalid AGENTUITY_DEPLOYMENT schema: ${errors}`);
130
+ }
131
+ } catch (err) {
132
+ logger.warn(`Failed to parse AGENTUITY_DEPLOYMENT: ${err instanceof Error ? err.message : String(err)}`);
133
+ }
134
+ }
135
+
136
+ const sdkKey = await loadProjectSDKKey(ctx.logger, ctx.projectDir);
137
+
138
+ // Ensure SDK key is present before proceeding
139
+ if (!sdkKey) {
140
+ ctx.logger.fatal(
141
+ 'SDK key not found. Run "agentuity auth login" to authenticate or set AGENTUITY_SDK_KEY environment variable.'
142
+ );
143
+ }
144
+
109
145
  try {
110
146
  await saveProjectDir(projectDir);
111
147
 
@@ -114,24 +150,20 @@ export const deploySubcommand = createSubcommand({
114
150
  !project.deployment?.domains?.length
115
151
  ? null
116
152
  : {
117
- label: `Validate Custom Domain${project.deployment.domains.length > 1 ? `s: ${project.deployment.domains.join(', ')}` : `: ${project.deployment.domains[0]}`}`,
153
+ label: `Validate Custom ${tui.plural(project.deployment.domains.length, 'Domain', 'Domains')}`,
118
154
  run: async () => {
119
155
  if (project.deployment?.domains?.length) {
120
- const result = await checkCustomDomainForDNS(
121
- project.projectId,
122
- project.deployment.domains,
123
- config
124
- );
125
- for (const r of result) {
126
- if (r.success) {
127
- continue;
128
- }
129
- if (r.message) {
130
- return stepError(r.message);
131
- }
132
- return stepError('unknown dns error'); // shouldn't get here
156
+ try {
157
+ await domain.promptForDNS(
158
+ project.projectId,
159
+ project.deployment.domains,
160
+ config!,
161
+ () => pauseStepUI(true)
162
+ );
163
+ return stepSuccess();
164
+ } catch (ex) {
165
+ return stepError(String(ex), ex as Error);
133
166
  }
134
- return stepSuccess();
135
167
  }
136
168
  return stepSkipped();
137
169
  },
@@ -176,6 +208,9 @@ export const deploySubcommand = createSubcommand({
176
208
  {
177
209
  label: 'Create Deployment',
178
210
  run: async () => {
211
+ if (useExistingDeployment && deployment) {
212
+ return stepSkipped('using existing deployment');
213
+ }
179
214
  try {
180
215
  deployment = await projectDeploymentCreate(
181
216
  apiClient,
@@ -241,10 +276,6 @@ export const deploySubcommand = createSubcommand({
241
276
  const deploymentZip = join(tmpdir(), `${deployment.id}.zip`);
242
277
  await zipDir(join(projectDir, '.agentuity'), deploymentZip, {
243
278
  filter: (_filename: string, relative: string) => {
244
- // Exclude Vite-specific build artifacts
245
- if (relative.endsWith('.generated.ts')) {
246
- return false;
247
- }
248
279
  if (relative.startsWith('.vite/')) {
249
280
  return false;
250
281
  }
@@ -328,6 +359,7 @@ export const deploySubcommand = createSubcommand({
328
359
  }
329
360
 
330
361
  progress(80);
362
+ let bytes = 0;
331
363
  if (build?.assets) {
332
364
  ctx.logger.trace(`Uploading ${build.assets.length} assets`);
333
365
  if (!instructions.assets) {
@@ -337,9 +369,9 @@ export const deploySubcommand = createSubcommand({
337
369
  }
338
370
 
339
371
  // Workaround for Bun crash in compiled executables (https://github.com/agentuity/sdk/issues/191)
340
- // Use limited concurrency (2 at a time) for executables to avoid parallel fetch crash
372
+ // Use limited concurrency (1 at a time) for executables to avoid parallel fetch crash
341
373
  const isExecutable = isRunningFromExecutable();
342
- const concurrency = isExecutable ? 2 : build.assets.length;
374
+ const concurrency = isExecutable ? 1 : Math.min(4, build.assets.length);
343
375
 
344
376
  if (isExecutable) {
345
377
  ctx.logger.trace(
@@ -361,15 +393,34 @@ export const deploySubcommand = createSubcommand({
361
393
  }
362
394
 
363
395
  // Asset filename already includes the subdirectory (e.g., "client/assets/main-abc123.js")
364
- const file = Bun.file(join(projectDir, '.agentuity', asset.filename));
396
+ const filePath = join(projectDir, '.agentuity', asset.filename);
397
+
398
+ const headers: Record<string, string> = {
399
+ 'Content-Type': asset.contentType,
400
+ };
401
+
402
+ bytes += asset.size;
403
+
404
+ let body: Uint8Array | Blob;
405
+ if (asset.contentEncoding === 'gzip') {
406
+ const file = Bun.file(filePath);
407
+ const ab = await file.arrayBuffer();
408
+ const gzipped = Bun.gzipSync(new Uint8Array(ab));
409
+ headers['Content-Encoding'] = 'gzip';
410
+ body = gzipped;
411
+ ctx.logger.trace(
412
+ `Compressing ${asset.filename} (${asset.size} -> ${gzipped.byteLength} bytes)`
413
+ );
414
+ } else {
415
+ body = Bun.file(filePath);
416
+ }
417
+
365
418
  promises.push(
366
419
  fetch(assetUrl, {
367
420
  method: 'PUT',
368
421
  duplex: 'half',
369
- headers: {
370
- 'Content-Type': asset.contentType,
371
- },
372
- body: file,
422
+ headers,
423
+ body,
373
424
  })
374
425
  );
375
426
  }
@@ -386,7 +437,14 @@ export const deploySubcommand = createSubcommand({
386
437
  }
387
438
 
388
439
  progress(100);
389
- return stepSuccess();
440
+ const output = build?.assets.length
441
+ ? [
442
+ tui.muted(
443
+ `✓ Uploaded ${build.assets.length} ${tui.plural(build.assets.length, 'asset', 'assets')} (${tui.formatBytes(bytes)}) to CDN`
444
+ ),
445
+ ]
446
+ : undefined;
447
+ return stepSuccess(output);
390
448
  },
391
449
  },
392
450
  {
@@ -400,7 +458,7 @@ export const deploySubcommand = createSubcommand({
400
458
  },
401
459
  },
402
460
  ].filter(Boolean) as Step[],
403
- options.logLevel
461
+ useExistingDeployment ? 'debug' : options.logLevel
404
462
  );
405
463
 
406
464
  if (!deployment) {
@@ -444,6 +502,10 @@ export const deploySubcommand = createSubcommand({
444
502
  logger.debug('fetching stream: %s/%s', streamsUrl, streamId);
445
503
  const resp = await fetch(`${streamsUrl}/${streamId}`, {
446
504
  signal: logStreamController.signal,
505
+ headers: {
506
+ Authorization: `Bearer ${sdkKey}`,
507
+ 'User-Agent': getUserAgent(),
508
+ },
447
509
  });
448
510
  if (!resp.ok || !resp.body) {
449
511
  ctx.logger.trace(
@@ -607,20 +669,36 @@ export const deploySubcommand = createSubcommand({
607
669
 
608
670
  // Show deployment URLs
609
671
  if (complete?.publicUrls) {
672
+ const lines: string[] = [];
610
673
  if (complete.publicUrls.custom?.length) {
611
674
  for (const url of complete.publicUrls.custom) {
612
- tui.arrow(tui.bold(tui.padRight('Deployment URL:', 17)) + tui.link(url));
675
+ lines.push(
676
+ `${tui.ICONS.arrow} ${tui.bold(tui.padRight('Deployment:', 12)) + tui.link(url)}`
677
+ );
613
678
  }
614
679
  } else {
615
- tui.arrow(
616
- tui.bold(tui.padRight('Deployment URL:', 17)) +
680
+ lines.push(
681
+ `${tui.ICONS.arrow} ${
682
+ tui.bold(tui.padRight('Deployment:', 12)) +
617
683
  tui.link(complete.publicUrls.deployment)
684
+ }`
618
685
  );
619
- tui.arrow(
620
- tui.bold(tui.padRight('Project URL:', 17)) + tui.link(complete.publicUrls.latest)
686
+ lines.push(
687
+ `${tui.ICONS.arrow} ${
688
+ tui.bold(tui.padRight('Project:', 12)) + tui.link(complete.publicUrls.latest)
689
+ }`
621
690
  );
622
- tui.arrow(tui.bold(tui.padRight('Dashboard URL:', 17)) + tui.link(dashboard));
623
691
  }
692
+ lines.push(
693
+ `${tui.ICONS.arrow} ${
694
+ tui.bold(tui.padRight('Dashboard:', 12)) + tui.link(dashboard)
695
+ }`
696
+ );
697
+ tui.banner(`Deployment: ${tui.colorPrimary(deployment.id)}`, lines.join('\n'), {
698
+ centerTitle: false,
699
+ topSpacer: false,
700
+ bottomSpacer: false,
701
+ });
624
702
  }
625
703
 
626
704
  return {
@@ -37,7 +37,9 @@ export const createNamespaceSubcommand = createCommand({
37
37
  const kv = await createStorageAdapter(ctx);
38
38
 
39
39
  await kv.createNamespace(args.name);
40
- tui.success(`Namespace ${tui.bold(args.name)} created`);
40
+ if (!ctx.options.json) {
41
+ tui.success(`Namespace ${tui.bold(args.name)} created`);
42
+ }
41
43
 
42
44
  return {
43
45
  success: true,
@@ -68,7 +68,9 @@ export const deleteNamespaceSubcommand = createCommand({
68
68
  }
69
69
 
70
70
  await kv.deleteNamespace(args.name);
71
- tui.success(`Namespace ${tui.bold(args.name)} deleted`);
71
+ if (!ctx.options.json) {
72
+ tui.success(`Namespace ${tui.bold(args.name)} deleted`);
73
+ }
72
74
 
73
75
  return {
74
76
  success: true,
@@ -39,7 +39,9 @@ export const deleteSubcommand = createCommand({
39
39
  const storage = await createStorageAdapter(ctx);
40
40
  await storage.delete(args.namespace, args.key);
41
41
  const durationMs = Date.now() - started;
42
- tui.success(`deleted in ${durationMs.toFixed(1)}ms`);
42
+ if (!ctx.options.json) {
43
+ tui.success(`deleted in ${durationMs.toFixed(1)}ms`);
44
+ }
43
45
 
44
46
  return {
45
47
  success: true,
@@ -47,7 +47,7 @@ export const setSubcommand = createCommand({
47
47
  },
48
48
 
49
49
  async handler(ctx) {
50
- const { args } = ctx;
50
+ const { args, options } = ctx;
51
51
  const started = Date.now();
52
52
  const storage = await createStorageAdapter(ctx);
53
53
  const contentType = isPossiblyJSON(args.value) ? 'application/json' : 'text/plain';
@@ -57,7 +57,9 @@ export const setSubcommand = createCommand({
57
57
  ttl,
58
58
  });
59
59
  const durationMs = Date.now() - started;
60
- tui.success(`saved in ${durationMs.toFixed(1)}ms (${contentType})`);
60
+ if (!options.json) {
61
+ tui.success(`saved in ${durationMs.toFixed(1)}ms (${contentType})`);
62
+ }
61
63
 
62
64
  return {
63
65
  success: true,
@@ -3,13 +3,6 @@ import { createCommand } from '../../../types';
3
3
  import * as tui from '../../../tui';
4
4
  import { createStorageAdapter } from './util';
5
5
  import { getCommand } from '../../../command-prefix';
6
- function formatBytes(bytes: number): string {
7
- if (bytes === 0) return '0 B';
8
- if (bytes < 1024) return `${bytes} B`;
9
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(2)} KB`;
10
- if (bytes < 1024 * 1024 * 1024) return `${(bytes / (1024 * 1024)).toFixed(2)} MB`;
11
- return `${(bytes / (1024 * 1024 * 1024)).toFixed(2)} GB`;
12
- }
13
6
 
14
7
  const GetStreamResponseSchema = z.object({
15
8
  id: z.string().describe('Stream ID'),
@@ -70,7 +63,7 @@ export const getSubcommand = createCommand({
70
63
  const durationMs = Date.now() - started;
71
64
  const stats = await Bun.file(opts.output).stat();
72
65
  tui.success(
73
- `downloaded ${formatBytes(stats.size)} to ${opts.output} in ${durationMs.toFixed(1)}ms`
66
+ `downloaded ${tui.formatBytes(stats.size)} to ${opts.output} in ${durationMs.toFixed(1)}ms`
74
67
  );
75
68
 
76
69
  // Fetch stream metadata to populate the response
@@ -100,7 +93,7 @@ export const getSubcommand = createCommand({
100
93
 
101
94
  console.log(`Name: ${tui.bold(stream.name ?? 'unknown')}`);
102
95
  console.log(`ID: ${stream.id}`);
103
- console.log(`Size: ${formatBytes(sizeBytes)}`);
96
+ console.log(`Size: ${tui.formatBytes(sizeBytes)}`);
104
97
  console.log(`URL: ${tui.link(stream.url ?? 'unknown')}`);
105
98
  if (stream.metadata && Object.keys(stream.metadata).length > 0) {
106
99
  console.log(`Metadata:`);
@@ -0,0 +1,89 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import { ErrorCode } from '../../../errors';
4
+ import * as tui from '../../../tui';
5
+ import { createStorageAdapter } from './util';
6
+ import { getCommand } from '../../../command-prefix';
7
+
8
+ export const deleteNamespaceSubcommand = createCommand({
9
+ name: 'delete-namespace',
10
+ aliases: ['rm-namespace'],
11
+ description: 'Delete a vector namespace and all its vectors',
12
+ tags: ['destructive', 'deletes-resource', 'slow', 'requires-auth'],
13
+ idempotent: true,
14
+ requires: { auth: true, project: true },
15
+ examples: [
16
+ {
17
+ command: getCommand('vector delete-namespace staging'),
18
+ description: 'Delete staging namespace (interactive)',
19
+ },
20
+ {
21
+ command: getCommand('vector rm-namespace cache --confirm'),
22
+ description: 'Delete cache without confirmation',
23
+ },
24
+ {
25
+ command: getCommand('vector delete-namespace old-data --confirm'),
26
+ description: 'Force delete old-data namespace',
27
+ },
28
+ ],
29
+ schema: {
30
+ args: z.object({
31
+ name: z.string().min(1).describe('the namespace name to delete'),
32
+ }),
33
+ options: z.object({
34
+ confirm: z
35
+ .boolean()
36
+ .optional()
37
+ .default(false)
38
+ .describe('if true will not prompt for confirmation'),
39
+ }),
40
+ response: z.object({
41
+ success: z.boolean().describe('Whether the deletion succeeded'),
42
+ namespace: z.string().describe('Deleted namespace name'),
43
+ message: z.string().optional().describe('Confirmation message'),
44
+ }),
45
+ },
46
+
47
+ async handler(ctx) {
48
+ const { args, opts } = ctx;
49
+ const storage = await createStorageAdapter(ctx);
50
+
51
+ if (!opts.confirm) {
52
+ if (!process.stdin.isTTY) {
53
+ tui.fatal(
54
+ 'No TTY and --confirm is not set. Refusing to delete',
55
+ ErrorCode.VALIDATION_FAILED
56
+ );
57
+ }
58
+ tui.warning(
59
+ `This will delete namespace ${tui.bold(args.name)} and ALL its vectors permanently.`
60
+ );
61
+ const confirm = await new Promise<boolean>((resolve) => {
62
+ process.stdout.write('Are you sure? (yes/no): ');
63
+ process.stdin.once('data', (data) => {
64
+ const answer = data.toString().trim().toLowerCase();
65
+ resolve(answer === 'yes' || answer === 'y');
66
+ });
67
+ });
68
+
69
+ if (!confirm) {
70
+ tui.info('Cancelled');
71
+ return { success: false, namespace: args.name, message: 'Cancelled' };
72
+ }
73
+ }
74
+
75
+ await storage.deleteNamespace(args.name);
76
+
77
+ if (!ctx.options.json) {
78
+ tui.success(`Namespace ${tui.bold(args.name)} deleted`);
79
+ }
80
+
81
+ return {
82
+ success: true,
83
+ namespace: args.name,
84
+ message: `Namespace ${args.name} deleted`,
85
+ };
86
+ },
87
+ });
88
+
89
+ export default deleteNamespaceSubcommand;
@@ -1,22 +1,39 @@
1
1
  import { createCommand } from '../../../types';
2
2
  import { deleteSubcommand } from './delete';
3
+ import { deleteNamespaceSubcommand } from './delete-namespace';
3
4
  import { getSubcommand } from './get';
5
+ import { listNamespacesSubcommand } from './list-namespaces';
4
6
  import { searchSubcommand } from './search';
7
+ import { statsSubcommand } from './stats';
8
+ import { upsertSubcommand } from './upsert';
5
9
  import { getCommand } from '../../../command-prefix';
6
10
 
7
11
  export const vectorCommand = createCommand({
8
12
  name: 'vector',
9
13
  aliases: ['vec'],
10
14
  description: 'Manage vector storage for your projects',
11
- tags: ['requires-auth', 'destructive', 'deletes-resource', 'slow'],
15
+ tags: ['requires-auth', 'slow'],
12
16
  examples: [
13
17
  {
14
- command: getCommand('cloud vector search "query text"'),
18
+ command: getCommand('cloud vector search products "query text"'),
15
19
  description: 'Search vector storage',
16
20
  },
17
- { command: getCommand('cloud vec get <id>'), description: 'Get vector by ID' },
21
+ {
22
+ command: getCommand('cloud vec upsert products doc1 --document "text"'),
23
+ description: 'Upsert a vector',
24
+ },
25
+ { command: getCommand('cloud vec get products doc1'), description: 'Get vector by key' },
26
+ { command: getCommand('cloud vec stats'), description: 'Show namespace statistics' },
27
+ ],
28
+ subcommands: [
29
+ upsertSubcommand,
30
+ searchSubcommand,
31
+ getSubcommand,
32
+ deleteSubcommand,
33
+ statsSubcommand,
34
+ listNamespacesSubcommand,
35
+ deleteNamespaceSubcommand,
18
36
  ],
19
- subcommands: [searchSubcommand, getSubcommand, deleteSubcommand],
20
37
  requires: { auth: true, project: true },
21
38
  });
22
39
 
@@ -0,0 +1,46 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { createStorageAdapter } from './util';
5
+ import { getCommand } from '../../../command-prefix';
6
+
7
+ const NamespaceListResponseSchema = z.array(z.string().describe('Namespace name'));
8
+
9
+ export const listNamespacesSubcommand = createCommand({
10
+ name: 'list-namespaces',
11
+ aliases: ['namespaces', 'ns'],
12
+ description: 'List all vector namespaces',
13
+ tags: ['read-only', 'fast', 'requires-auth'],
14
+ requires: { auth: true, project: true },
15
+ examples: [
16
+ { command: getCommand('vector list-namespaces'), description: 'List all namespaces' },
17
+ { command: getCommand('vector namespaces'), description: 'List namespaces (using alias)' },
18
+ { command: getCommand('vector ns'), description: 'List namespaces (short alias)' },
19
+ ],
20
+ schema: {
21
+ response: NamespaceListResponseSchema,
22
+ },
23
+ webUrl: '/services/vector',
24
+ idempotent: true,
25
+
26
+ async handler(ctx) {
27
+ const { options } = ctx;
28
+ const storage = await createStorageAdapter(ctx);
29
+ const namespaces = await storage.getNamespaces();
30
+
31
+ if (!options.json) {
32
+ if (namespaces.length === 0) {
33
+ tui.info('No vector namespaces found');
34
+ } else {
35
+ tui.info(`Found ${namespaces.length} namespace(s):`);
36
+ for (const name of namespaces) {
37
+ tui.arrow(name);
38
+ }
39
+ }
40
+ }
41
+
42
+ return namespaces;
43
+ },
44
+ });
45
+
46
+ export default listNamespacesSubcommand;
@@ -0,0 +1,160 @@
1
+ import { z } from 'zod';
2
+ import { createCommand } from '../../../types';
3
+ import * as tui from '../../../tui';
4
+ import { createStorageAdapter } from './util';
5
+ import { getCommand } from '../../../command-prefix';
6
+
7
+ const VectorItemStatsSchema = z.object({
8
+ embedding: z.array(z.number()).optional().describe('The embedding vector'),
9
+ document: z.string().optional().describe('Original document text'),
10
+ size: z.number().describe('Size in bytes'),
11
+ metadata: z.record(z.string(), z.unknown()).optional().describe('Metadata'),
12
+ firstUsed: z.number().describe('First access timestamp (ms)'),
13
+ lastUsed: z.number().describe('Last access timestamp (ms)'),
14
+ count: z.number().optional().describe('Access count (only available in cloud storage)'),
15
+ });
16
+
17
+ const VectorNamespaceStatsSchema = z.object({
18
+ sum: z.number().describe('Total size in bytes'),
19
+ count: z.number().describe('Number of vectors'),
20
+ createdAt: z.number().optional().describe('Creation timestamp (ms)'),
21
+ lastUsed: z.number().optional().describe('Last used timestamp (ms)'),
22
+ });
23
+
24
+ const VectorStatsResponseSchema = z.union([
25
+ VectorNamespaceStatsSchema.extend({
26
+ namespace: z.string().describe('Namespace name'),
27
+ sampledResults: z.record(z.string(), VectorItemStatsSchema).optional(),
28
+ }),
29
+ z.record(z.string(), VectorNamespaceStatsSchema),
30
+ ]);
31
+
32
+ export const statsSubcommand = createCommand({
33
+ name: 'stats',
34
+ description: 'Get statistics for vector storage',
35
+ tags: ['read-only', 'fast', 'requires-auth'],
36
+ requires: { auth: true, project: true },
37
+ idempotent: true,
38
+ examples: [
39
+ { command: getCommand('vector stats'), description: 'Show stats for all namespaces' },
40
+ {
41
+ command: getCommand('vector stats products'),
42
+ description: 'Show detailed stats for products namespace',
43
+ },
44
+ { command: getCommand('vector stats embeddings'), description: 'Show stats for embeddings' },
45
+ ],
46
+ schema: {
47
+ args: z.object({
48
+ name: z.string().optional().describe('the vector namespace (optional)'),
49
+ }),
50
+ response: VectorStatsResponseSchema,
51
+ },
52
+ webUrl: (ctx) =>
53
+ ctx.args.name ? `/services/vector/${encodeURIComponent(ctx.args.name)}` : '/services/vector',
54
+
55
+ async handler(ctx) {
56
+ const { args, options } = ctx;
57
+ const storage = await createStorageAdapter(ctx);
58
+
59
+ if (args.name) {
60
+ const stats = await storage.getStats(args.name);
61
+
62
+ if (!options.json) {
63
+ if (stats.count === 0 && stats.sum === 0) {
64
+ tui.info(`Namespace ${tui.bold(args.name)} is empty or does not exist`);
65
+ } else {
66
+ tui.info(`Statistics for ${tui.bold(args.name)}:`);
67
+ tui.info(` Vectors: ${stats.count}`);
68
+ const sizeDisplay =
69
+ stats.sum < 1024 * 1024
70
+ ? `${stats.sum.toLocaleString()} bytes`
71
+ : `${(stats.sum / (1024 * 1024)).toFixed(2)} MB`;
72
+ tui.info(` Total size: ${sizeDisplay}`);
73
+
74
+ if (stats.createdAt) {
75
+ tui.info(` Created: ${new Date(stats.createdAt).toLocaleString()}`);
76
+ }
77
+ if (stats.lastUsed) {
78
+ tui.info(` Last used: ${new Date(stats.lastUsed).toLocaleString()}`);
79
+ }
80
+
81
+ if (stats.sampledResults && Object.keys(stats.sampledResults).length > 0) {
82
+ tui.info('');
83
+ tui.info(` Sample vectors (${Object.keys(stats.sampledResults).length}):`);
84
+
85
+ const tableData = Object.entries(stats.sampledResults).map(([key, item]) => {
86
+ const docPreview = item.document
87
+ ? item.document.length > 30
88
+ ? item.document.substring(0, 27) + '...'
89
+ : item.document
90
+ : '-';
91
+ return {
92
+ Key: key,
93
+ Size: `${item.size} bytes`,
94
+ Accesses: item.count ?? '-',
95
+ 'Last Used': new Date(item.lastUsed).toLocaleDateString(),
96
+ Document: docPreview,
97
+ };
98
+ });
99
+
100
+ tui.table(tableData, [
101
+ { name: 'Key', alignment: 'left' },
102
+ { name: 'Size', alignment: 'right' },
103
+ { name: 'Accesses', alignment: 'right' },
104
+ { name: 'Last Used', alignment: 'left' },
105
+ { name: 'Document', alignment: 'left' },
106
+ ]);
107
+ }
108
+ }
109
+ }
110
+
111
+ return {
112
+ namespace: args.name,
113
+ ...stats,
114
+ };
115
+ } else {
116
+ const allStats = await storage.getAllStats();
117
+ const entries = Object.entries(allStats);
118
+
119
+ if (!options.json) {
120
+ if (entries.length === 0) {
121
+ tui.info('No vector namespaces found');
122
+ } else {
123
+ tui.info(
124
+ `Found ${entries.length} ${tui.plural(entries.length, 'namespace', 'namespaces')}:`
125
+ );
126
+
127
+ const tableData = entries.map(([name, stats]) => {
128
+ const sizeDisplay =
129
+ stats.sum < 1024 * 1024
130
+ ? `${stats.sum.toLocaleString()} bytes`
131
+ : `${(stats.sum / (1024 * 1024)).toFixed(2)} MB`;
132
+ return {
133
+ Namespace: name,
134
+ Vectors: stats.count,
135
+ Size: sizeDisplay,
136
+ Created: stats.createdAt
137
+ ? new Date(stats.createdAt).toLocaleDateString()
138
+ : '-',
139
+ 'Last Used': stats.lastUsed
140
+ ? new Date(stats.lastUsed).toLocaleDateString()
141
+ : '-',
142
+ };
143
+ });
144
+
145
+ tui.table(tableData, [
146
+ { name: 'Namespace', alignment: 'left' },
147
+ { name: 'Vectors', alignment: 'right' },
148
+ { name: 'Size', alignment: 'right' },
149
+ { name: 'Created', alignment: 'left' },
150
+ { name: 'Last Used', alignment: 'left' },
151
+ ]);
152
+ }
153
+ }
154
+
155
+ return allStats;
156
+ }
157
+ },
158
+ });
159
+
160
+ export default statsSubcommand;