@agentuity/cli 0.0.94 → 0.0.96

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (277) hide show
  1. package/AGENTS.md +54 -0
  2. package/dist/auth.d.ts +1 -1
  3. package/dist/auth.d.ts.map +1 -1
  4. package/dist/auth.js +8 -5
  5. package/dist/auth.js.map +1 -1
  6. package/dist/banner.js +1 -1
  7. package/dist/banner.js.map +1 -1
  8. package/dist/cli.d.ts.map +1 -1
  9. package/dist/cli.js +190 -27
  10. package/dist/cli.js.map +1 -1
  11. package/dist/cmd/auth/signup.js +1 -1
  12. package/dist/cmd/auth/signup.js.map +1 -1
  13. package/dist/cmd/build/ast.d.ts.map +1 -1
  14. package/dist/cmd/build/ast.js +7 -0
  15. package/dist/cmd/build/ast.js.map +1 -1
  16. package/dist/cmd/build/entry-generator.d.ts +20 -0
  17. package/dist/cmd/build/entry-generator.d.ts.map +1 -0
  18. package/dist/cmd/build/entry-generator.js +366 -0
  19. package/dist/cmd/build/entry-generator.js.map +1 -0
  20. package/dist/cmd/build/index.d.ts.map +1 -1
  21. package/dist/cmd/build/index.js +5 -23
  22. package/dist/cmd/build/index.js.map +1 -1
  23. package/dist/cmd/build/vite/agent-discovery.d.ts +33 -0
  24. package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -0
  25. package/dist/cmd/build/vite/agent-discovery.js +297 -0
  26. package/dist/cmd/build/vite/agent-discovery.js.map +1 -0
  27. package/dist/cmd/build/vite/browser-env-plugin.d.ts +9 -0
  28. package/dist/cmd/build/vite/browser-env-plugin.d.ts.map +1 -0
  29. package/dist/cmd/build/vite/browser-env-plugin.js +28 -0
  30. package/dist/cmd/build/vite/browser-env-plugin.js.map +1 -0
  31. package/dist/cmd/build/vite/bun-dev-server.d.ts +29 -0
  32. package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -0
  33. package/dist/cmd/build/vite/bun-dev-server.js +54 -0
  34. package/dist/cmd/build/vite/bun-dev-server.js.map +1 -0
  35. package/dist/cmd/build/vite/config-loader.d.ts +23 -0
  36. package/dist/cmd/build/vite/config-loader.d.ts.map +1 -0
  37. package/dist/cmd/build/vite/config-loader.js +50 -0
  38. package/dist/cmd/build/vite/config-loader.js.map +1 -0
  39. package/dist/cmd/build/vite/index.d.ts +26 -0
  40. package/dist/cmd/build/vite/index.d.ts.map +1 -0
  41. package/dist/cmd/build/vite/index.js +127 -0
  42. package/dist/cmd/build/vite/index.js.map +1 -0
  43. package/dist/cmd/build/vite/lifecycle-generator.d.ts +11 -0
  44. package/dist/cmd/build/vite/lifecycle-generator.d.ts.map +1 -0
  45. package/dist/cmd/build/vite/lifecycle-generator.js +35 -0
  46. package/dist/cmd/build/vite/lifecycle-generator.js.map +1 -0
  47. package/dist/cmd/build/vite/metadata-generator.d.ts +32 -0
  48. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -0
  49. package/dist/cmd/build/vite/metadata-generator.js +489 -0
  50. package/dist/cmd/build/vite/metadata-generator.js.map +1 -0
  51. package/dist/cmd/build/vite/patch-plugin.d.ts +21 -0
  52. package/dist/cmd/build/vite/patch-plugin.d.ts.map +1 -0
  53. package/dist/cmd/build/vite/patch-plugin.js +70 -0
  54. package/dist/cmd/build/vite/patch-plugin.js.map +1 -0
  55. package/dist/cmd/build/vite/registry-generator.d.ts +19 -0
  56. package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -0
  57. package/dist/cmd/build/{route-registry.js → vite/registry-generator.js} +126 -48
  58. package/dist/cmd/build/vite/registry-generator.js.map +1 -0
  59. package/dist/cmd/build/vite/route-discovery.d.ts +58 -0
  60. package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -0
  61. package/dist/cmd/build/vite/route-discovery.js +125 -0
  62. package/dist/cmd/build/vite/route-discovery.js.map +1 -0
  63. package/dist/cmd/build/vite/server-bundler.d.ts +16 -0
  64. package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -0
  65. package/dist/cmd/build/vite/server-bundler.js +194 -0
  66. package/dist/cmd/build/vite/server-bundler.js.map +1 -0
  67. package/dist/cmd/build/vite/vite-asset-server-config.d.ts +19 -0
  68. package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -0
  69. package/dist/cmd/build/vite/vite-asset-server-config.js +105 -0
  70. package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -0
  71. package/dist/cmd/build/vite/vite-asset-server.d.ts +23 -0
  72. package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -0
  73. package/dist/cmd/build/vite/vite-asset-server.js +40 -0
  74. package/dist/cmd/build/vite/vite-asset-server.js.map +1 -0
  75. package/dist/cmd/build/vite/vite-builder.d.ts +44 -0
  76. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -0
  77. package/dist/cmd/build/vite/vite-builder.js +232 -0
  78. package/dist/cmd/build/vite/vite-builder.js.map +1 -0
  79. package/dist/cmd/build/vite/workbench-generator.d.ts +10 -0
  80. package/dist/cmd/build/vite/workbench-generator.d.ts.map +1 -0
  81. package/dist/cmd/build/vite/workbench-generator.js +135 -0
  82. package/dist/cmd/build/vite/workbench-generator.js.map +1 -0
  83. package/dist/cmd/build/vite-bundler.d.ts +23 -0
  84. package/dist/cmd/build/vite-bundler.d.ts.map +1 -0
  85. package/dist/cmd/build/vite-bundler.js +79 -0
  86. package/dist/cmd/build/vite-bundler.js.map +1 -0
  87. package/dist/cmd/cloud/agent/get.d.ts.map +1 -1
  88. package/dist/cmd/cloud/agent/get.js +1 -0
  89. package/dist/cmd/cloud/agent/get.js.map +1 -1
  90. package/dist/cmd/cloud/agent/list.d.ts.map +1 -1
  91. package/dist/cmd/cloud/agent/list.js +1 -0
  92. package/dist/cmd/cloud/agent/list.js.map +1 -1
  93. package/dist/cmd/cloud/db/get.d.ts.map +1 -1
  94. package/dist/cmd/cloud/db/get.js +1 -0
  95. package/dist/cmd/cloud/db/get.js.map +1 -1
  96. package/dist/cmd/cloud/db/list.d.ts.map +1 -1
  97. package/dist/cmd/cloud/db/list.js +1 -0
  98. package/dist/cmd/cloud/db/list.js.map +1 -1
  99. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  100. package/dist/cmd/cloud/deploy.js +152 -128
  101. package/dist/cmd/cloud/deploy.js.map +1 -1
  102. package/dist/cmd/cloud/deployment/list.d.ts.map +1 -1
  103. package/dist/cmd/cloud/deployment/list.js +4 -0
  104. package/dist/cmd/cloud/deployment/list.js.map +1 -1
  105. package/dist/cmd/cloud/env/list.d.ts.map +1 -1
  106. package/dist/cmd/cloud/env/list.js +1 -0
  107. package/dist/cmd/cloud/env/list.js.map +1 -1
  108. package/dist/cmd/cloud/keyvalue/get.d.ts.map +1 -1
  109. package/dist/cmd/cloud/keyvalue/get.js +1 -0
  110. package/dist/cmd/cloud/keyvalue/get.js.map +1 -1
  111. package/dist/cmd/cloud/keyvalue/keys.d.ts.map +1 -1
  112. package/dist/cmd/cloud/keyvalue/keys.js +1 -0
  113. package/dist/cmd/cloud/keyvalue/keys.js.map +1 -1
  114. package/dist/cmd/cloud/keyvalue/list-namespaces.d.ts.map +1 -1
  115. package/dist/cmd/cloud/keyvalue/list-namespaces.js +1 -0
  116. package/dist/cmd/cloud/keyvalue/list-namespaces.js.map +1 -1
  117. package/dist/cmd/cloud/keyvalue/stats.d.ts.map +1 -1
  118. package/dist/cmd/cloud/keyvalue/stats.js +1 -0
  119. package/dist/cmd/cloud/keyvalue/stats.js.map +1 -1
  120. package/dist/cmd/cloud/secret/list.d.ts.map +1 -1
  121. package/dist/cmd/cloud/secret/list.js +1 -0
  122. package/dist/cmd/cloud/secret/list.js.map +1 -1
  123. package/dist/cmd/cloud/session/list.d.ts.map +1 -1
  124. package/dist/cmd/cloud/session/list.js +4 -0
  125. package/dist/cmd/cloud/session/list.js.map +1 -1
  126. package/dist/cmd/cloud/storage/get.d.ts.map +1 -1
  127. package/dist/cmd/cloud/storage/get.js +1 -0
  128. package/dist/cmd/cloud/storage/get.js.map +1 -1
  129. package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
  130. package/dist/cmd/cloud/storage/list.js +3 -0
  131. package/dist/cmd/cloud/storage/list.js.map +1 -1
  132. package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
  133. package/dist/cmd/cloud/stream/get.js +1 -0
  134. package/dist/cmd/cloud/stream/get.js.map +1 -1
  135. package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
  136. package/dist/cmd/cloud/stream/list.js +1 -0
  137. package/dist/cmd/cloud/stream/list.js.map +1 -1
  138. package/dist/cmd/cloud/vector/get.d.ts.map +1 -1
  139. package/dist/cmd/cloud/vector/get.js +1 -0
  140. package/dist/cmd/cloud/vector/get.js.map +1 -1
  141. package/dist/cmd/cloud/vector/search.d.ts.map +1 -1
  142. package/dist/cmd/cloud/vector/search.js +1 -0
  143. package/dist/cmd/cloud/vector/search.js.map +1 -1
  144. package/dist/cmd/dev/index.d.ts.map +1 -1
  145. package/dist/cmd/dev/index.js +291 -751
  146. package/dist/cmd/dev/index.js.map +1 -1
  147. package/dist/cmd/dev/sync.d.ts +1 -1
  148. package/dist/cmd/dev/sync.d.ts.map +1 -1
  149. package/dist/cmd/dev/sync.js +3 -0
  150. package/dist/cmd/dev/sync.js.map +1 -1
  151. package/dist/cmd/profile/show.d.ts.map +1 -1
  152. package/dist/cmd/profile/show.js +3 -4
  153. package/dist/cmd/profile/show.js.map +1 -1
  154. package/dist/cmd/project/create.d.ts.map +1 -1
  155. package/dist/cmd/project/create.js +3 -4
  156. package/dist/cmd/project/create.js.map +1 -1
  157. package/dist/cmd/project/list.d.ts.map +1 -1
  158. package/dist/cmd/project/list.js +1 -0
  159. package/dist/cmd/project/list.js.map +1 -1
  160. package/dist/cmd/project/show.d.ts.map +1 -1
  161. package/dist/cmd/project/show.js +1 -0
  162. package/dist/cmd/project/show.js.map +1 -1
  163. package/dist/cmd/upgrade/index.d.ts.map +1 -1
  164. package/dist/cmd/upgrade/index.js +5 -3
  165. package/dist/cmd/upgrade/index.js.map +1 -1
  166. package/dist/config.d.ts +1 -1
  167. package/dist/config.d.ts.map +1 -1
  168. package/dist/config.js +29 -11
  169. package/dist/config.js.map +1 -1
  170. package/dist/index.d.ts +1 -1
  171. package/dist/index.d.ts.map +1 -1
  172. package/dist/index.js.map +1 -1
  173. package/dist/runtime-bootstrap.d.ts +3 -2
  174. package/dist/runtime-bootstrap.d.ts.map +1 -1
  175. package/dist/runtime-bootstrap.js +7 -2
  176. package/dist/runtime-bootstrap.js.map +1 -1
  177. package/dist/schemas/deploy.d.ts +1 -1
  178. package/dist/types.d.ts +40 -1
  179. package/dist/types.d.ts.map +1 -1
  180. package/dist/types.js.map +1 -1
  181. package/dist/utils/bun-version-checker.d.ts +11 -0
  182. package/dist/utils/bun-version-checker.d.ts.map +1 -0
  183. package/dist/utils/bun-version-checker.js +56 -0
  184. package/dist/utils/bun-version-checker.js.map +1 -0
  185. package/dist/version-check.d.ts.map +1 -1
  186. package/dist/version-check.js +5 -2
  187. package/dist/version-check.js.map +1 -1
  188. package/package.json +10 -3
  189. package/src/auth.ts +9 -5
  190. package/src/banner.ts +1 -1
  191. package/src/cli.ts +228 -29
  192. package/src/cmd/auth/signup.ts +1 -1
  193. package/src/cmd/build/ast.ts +7 -0
  194. package/src/cmd/build/entry-generator.ts +404 -0
  195. package/src/cmd/build/index.ts +7 -28
  196. package/src/cmd/build/vite/agent-discovery.ts +467 -0
  197. package/src/cmd/build/vite/browser-env-plugin.ts +34 -0
  198. package/src/cmd/build/vite/bun-dev-server.ts +78 -0
  199. package/src/cmd/build/vite/config-loader.ts +70 -0
  200. package/src/cmd/build/vite/index.ts +166 -0
  201. package/src/cmd/build/vite/lifecycle-generator.ts +43 -0
  202. package/src/cmd/build/vite/metadata-generator.ts +602 -0
  203. package/src/cmd/build/vite/patch-plugin.ts +88 -0
  204. package/src/cmd/build/vite/registry-generator.ts +288 -0
  205. package/src/cmd/build/vite/route-discovery.ts +186 -0
  206. package/src/cmd/build/vite/server-bundler.ts +258 -0
  207. package/src/cmd/build/vite/vite-asset-server-config.ts +134 -0
  208. package/src/cmd/build/vite/vite-asset-server.ts +63 -0
  209. package/src/cmd/build/vite/vite-builder.ts +284 -0
  210. package/src/cmd/build/vite/workbench-generator.ts +152 -0
  211. package/src/cmd/build/vite-bundler.ts +110 -0
  212. package/src/cmd/cloud/agent/get.ts +2 -0
  213. package/src/cmd/cloud/agent/list.ts +1 -0
  214. package/src/cmd/cloud/db/get.ts +1 -0
  215. package/src/cmd/cloud/db/list.ts +1 -0
  216. package/src/cmd/cloud/deploy.ts +175 -144
  217. package/src/cmd/cloud/deployment/list.ts +4 -0
  218. package/src/cmd/cloud/env/list.ts +1 -0
  219. package/src/cmd/cloud/keyvalue/get.ts +1 -0
  220. package/src/cmd/cloud/keyvalue/keys.ts +1 -0
  221. package/src/cmd/cloud/keyvalue/list-namespaces.ts +1 -0
  222. package/src/cmd/cloud/keyvalue/stats.ts +2 -0
  223. package/src/cmd/cloud/secret/list.ts +1 -0
  224. package/src/cmd/cloud/session/list.ts +4 -0
  225. package/src/cmd/cloud/storage/get.ts +1 -0
  226. package/src/cmd/cloud/storage/list.ts +4 -0
  227. package/src/cmd/cloud/stream/get.ts +1 -0
  228. package/src/cmd/cloud/stream/list.ts +1 -0
  229. package/src/cmd/cloud/vector/get.ts +1 -0
  230. package/src/cmd/cloud/vector/search.ts +1 -0
  231. package/src/cmd/dev/index.ts +323 -914
  232. package/src/cmd/dev/sync.ts +5 -1
  233. package/src/cmd/profile/show.ts +3 -4
  234. package/src/cmd/project/create.ts +3 -4
  235. package/src/cmd/project/list.ts +1 -0
  236. package/src/cmd/project/show.ts +1 -0
  237. package/src/cmd/upgrade/index.ts +6 -3
  238. package/src/config.ts +31 -11
  239. package/src/index.ts +2 -0
  240. package/src/runtime-bootstrap.ts +8 -2
  241. package/src/types.ts +48 -1
  242. package/src/utils/bun-version-checker.ts +70 -0
  243. package/src/version-check.ts +6 -2
  244. package/dist/cmd/build/bundler.d.ts +0 -22
  245. package/dist/cmd/build/bundler.d.ts.map +0 -1
  246. package/dist/cmd/build/bundler.js +0 -766
  247. package/dist/cmd/build/bundler.js.map +0 -1
  248. package/dist/cmd/build/config-loader.d.ts +0 -16
  249. package/dist/cmd/build/config-loader.d.ts.map +0 -1
  250. package/dist/cmd/build/config-loader.js +0 -227
  251. package/dist/cmd/build/config-loader.js.map +0 -1
  252. package/dist/cmd/build/file.d.ts +0 -2
  253. package/dist/cmd/build/file.d.ts.map +0 -1
  254. package/dist/cmd/build/file.js +0 -10
  255. package/dist/cmd/build/file.js.map +0 -1
  256. package/dist/cmd/build/fix-duplicate-exports.d.ts +0 -2
  257. package/dist/cmd/build/fix-duplicate-exports.d.ts.map +0 -1
  258. package/dist/cmd/build/fix-duplicate-exports.js +0 -170
  259. package/dist/cmd/build/fix-duplicate-exports.js.map +0 -1
  260. package/dist/cmd/build/plugin.d.ts +0 -6
  261. package/dist/cmd/build/plugin.d.ts.map +0 -1
  262. package/dist/cmd/build/plugin.js +0 -645
  263. package/dist/cmd/build/plugin.js.map +0 -1
  264. package/dist/cmd/build/route-discovery.d.ts +0 -54
  265. package/dist/cmd/build/route-discovery.d.ts.map +0 -1
  266. package/dist/cmd/build/route-discovery.js +0 -148
  267. package/dist/cmd/build/route-discovery.js.map +0 -1
  268. package/dist/cmd/build/route-registry.d.ts +0 -38
  269. package/dist/cmd/build/route-registry.d.ts.map +0 -1
  270. package/dist/cmd/build/route-registry.js.map +0 -1
  271. package/src/cmd/build/bundler.ts +0 -927
  272. package/src/cmd/build/config-loader.ts +0 -268
  273. package/src/cmd/build/file.ts +0 -10
  274. package/src/cmd/build/fix-duplicate-exports.ts +0 -207
  275. package/src/cmd/build/plugin.ts +0 -782
  276. package/src/cmd/build/route-discovery.ts +0 -202
  277. package/src/cmd/build/route-registry.ts +0 -222
@@ -3,6 +3,7 @@ import { join, resolve } from 'node:path';
3
3
  import { createPublicKey } from 'node:crypto';
4
4
  import { createReadStream, createWriteStream, existsSync, mkdirSync, writeFileSync } from 'node:fs';
5
5
  import { tmpdir } from 'node:os';
6
+ import { StructuredError } from '@agentuity/core';
6
7
  import { createSubcommand } from '../../types';
7
8
  import * as tui from '../../tui';
8
9
  import { saveProjectDir, getDefaultConfigDir } from '../../config';
@@ -14,7 +15,7 @@ import {
14
15
  type Step,
15
16
  type StepContext,
16
17
  } from '../../steps';
17
- import { bundle } from '../build/bundler';
18
+ import { viteBundle } from '../build/vite-bundler';
18
19
  import { loadBuildMetadata, getStreamURL } from '../../config';
19
20
  import {
20
21
  projectEnvUpdate,
@@ -42,6 +43,11 @@ import { checkCustomDomainForDNS } from './domain';
42
43
  import { DeployOptionsSchema } from '../../schemas/deploy';
43
44
  import { ErrorCode } from '../../errors';
44
45
 
46
+ const DeploymentCancelledError = StructuredError(
47
+ 'DeploymentCancelled',
48
+ 'Deployment cancelled by user'
49
+ );
50
+
45
51
  const DeployResponseSchema = z.object({
46
52
  success: z.boolean().describe('Whether deployment succeeded'),
47
53
  deploymentId: z.string().describe('Deployment ID'),
@@ -90,7 +96,7 @@ export const deploySubcommand = createSubcommand({
90
96
  },
91
97
 
92
98
  async handler(ctx) {
93
- const { project, apiClient, projectDir, config, options, opts, logger } = ctx;
99
+ const { project, apiClient, projectDir, config, options, logger } = ctx;
94
100
 
95
101
  let deployment: Deployment | undefined;
96
102
  let build: BuildMetadata | undefined;
@@ -190,18 +196,12 @@ export const deploySubcommand = createSubcommand({
190
196
  }
191
197
  let capturedOutput: string[] = [];
192
198
  try {
193
- const bundleResult = await bundle({
199
+ const bundleResult = await viteBundle({
194
200
  rootDir: resolve(projectDir),
195
201
  dev: false,
196
202
  deploymentId: deployment.id,
197
203
  orgId: deployment.orgId,
198
204
  projectId: project.projectId,
199
- project,
200
- commitUrl: opts?.commitUrl,
201
- logsUrl: opts?.logsUrl,
202
- provider: opts?.provider,
203
- trigger: opts?.trigger,
204
- tag: opts?.tag,
205
205
  region: project.region,
206
206
  logger: ctx.logger,
207
207
  });
@@ -240,18 +240,17 @@ export const deploySubcommand = createSubcommand({
240
240
  const deploymentZip = join(tmpdir(), `${deployment.id}.zip`);
241
241
  await zipDir(join(projectDir, '.agentuity'), deploymentZip, {
242
242
  filter: (_filename: string, relative: string) => {
243
- // we don't include assets in the deployment
244
- if (relative.startsWith('web/assets/')) {
243
+ // Exclude Vite-specific build artifacts
244
+ if (relative.endsWith('.generated.ts')) {
245
245
  return false;
246
246
  }
247
- if (relative.startsWith('web/chunk/')) {
247
+ if (relative.startsWith('.vite/')) {
248
248
  return false;
249
249
  }
250
- if (relative.startsWith('web/public/')) {
250
+ if (relative.startsWith('workbench-src/')) {
251
251
  return false;
252
252
  }
253
- // exclude sourcemaps from deployment
254
- if (relative.endsWith('.map')) {
253
+ if (relative.startsWith('workbench/')) {
255
254
  return false;
256
255
  }
257
256
  // ignore common stuff we never want to include in the zip
@@ -345,9 +344,8 @@ export const deploySubcommand = createSubcommand({
345
344
  );
346
345
  }
347
346
 
348
- const file = Bun.file(
349
- join(projectDir, '.agentuity', 'web', asset.filename)
350
- );
347
+ // Asset filename already includes the subdirectory (e.g., "client/assets/main-abc123.js")
348
+ const file = Bun.file(join(projectDir, '.agentuity', asset.filename));
351
349
  promises.push(
352
350
  fetch(assetUrl, {
353
351
  method: 'PUT',
@@ -403,154 +401,187 @@ export const deploySubcommand = createSubcommand({
403
401
  const maxAttempts = 600;
404
402
  let attempts = 0;
405
403
 
406
- if (streamId) {
407
- // Use progress logger to stream logs while polling
408
- const streamsUrl = getStreamURL(project.region, config);
409
-
410
- await tui
411
- .progress({
412
- message: 'Deploying project...',
413
- type: 'logger',
414
- maxLines: 2,
415
- clearOnSuccess: true,
416
- callback: async (log) => {
417
- // Start log streaming
418
- const logStreamController = new AbortController();
419
- const logStreamPromise = (async () => {
420
- try {
421
- logger.debug('fetching stream: %s/%s', streamsUrl, streamId);
422
- const resp = await fetch(`${streamsUrl}/${streamId}`, {
423
- signal: logStreamController.signal,
424
- });
425
- if (!resp.ok || !resp.body) {
426
- ctx.logger.trace(
427
- `Failed to connect to warmup log stream: ${resp.status}`
428
- );
429
- return;
430
- }
431
- const reader = resp.body.getReader();
432
- const decoder = new TextDecoder();
433
- let buffer = '';
434
- while (true) {
435
- const { done, value } = await reader.read();
436
- if (done) break;
437
- buffer += decoder.decode(value, { stream: true });
438
- const lines = buffer.split('\n');
439
- buffer = lines.pop() || ''; // Keep incomplete line in buffer
440
- for (const line of lines) {
441
- // Strip ISO 8601 timestamp prefix if present
442
- const message = line.replace(
443
- /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s?/,
444
- ''
404
+ // Create abort controller to allow Ctrl+C to interrupt polling
405
+ const pollAbortController = new AbortController();
406
+ const sigintHandler = () => {
407
+ pollAbortController.abort();
408
+ };
409
+ process.on('SIGINT', sigintHandler);
410
+
411
+ try {
412
+ if (streamId) {
413
+ // Use progress logger to stream logs while polling
414
+ const streamsUrl = getStreamURL(project.region, config);
415
+
416
+ await tui
417
+ .progress({
418
+ message: 'Deploying project...',
419
+ type: 'logger',
420
+ maxLines: 2,
421
+ clearOnSuccess: true,
422
+ callback: async (log) => {
423
+ // Start log streaming
424
+ const logStreamController = new AbortController();
425
+ const logStreamPromise = (async () => {
426
+ try {
427
+ logger.debug('fetching stream: %s/%s', streamsUrl, streamId);
428
+ const resp = await fetch(`${streamsUrl}/${streamId}`, {
429
+ signal: logStreamController.signal,
430
+ });
431
+ if (!resp.ok || !resp.body) {
432
+ ctx.logger.trace(
433
+ `Failed to connect to warmup log stream: ${resp.status}`
445
434
  );
446
- if (message) {
447
- logs.push(message);
448
- log(message);
435
+ return;
436
+ }
437
+ const reader = resp.body.getReader();
438
+ const decoder = new TextDecoder();
439
+ let buffer = '';
440
+ while (true) {
441
+ const { done, value } = await reader.read();
442
+ if (done) break;
443
+ buffer += decoder.decode(value, { stream: true });
444
+ const lines = buffer.split('\n');
445
+ buffer = lines.pop() || ''; // Keep incomplete line in buffer
446
+ for (const line of lines) {
447
+ // Strip ISO 8601 timestamp prefix if present
448
+ const message = line.replace(
449
+ /^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}\.\d+Z\s?/,
450
+ ''
451
+ );
452
+ if (message) {
453
+ logs.push(message);
454
+ log(message);
455
+ }
449
456
  }
450
457
  }
458
+ } catch (err) {
459
+ if (err instanceof Error && err.name === 'AbortError') {
460
+ return;
461
+ }
462
+ ctx.logger.trace(`Warmup log stream error: ${err}`);
451
463
  }
452
- } catch (err) {
453
- if (err instanceof Error && err.name === 'AbortError') {
454
- return;
464
+ })();
465
+
466
+ // Poll for deployment status
467
+ while (attempts < maxAttempts) {
468
+ // Check if user pressed Ctrl+C
469
+ if (pollAbortController.signal.aborted) {
470
+ logStreamController.abort();
471
+ throw new DeploymentCancelledError();
455
472
  }
456
- ctx.logger.trace(`Warmup log stream error: ${err}`);
457
- }
458
- })();
459
473
 
460
- // Poll for deployment status
461
- while (attempts < maxAttempts) {
462
- attempts++;
463
- try {
464
- statusResult = await projectDeploymentStatus(
465
- apiClient,
466
- deployment?.id ?? ''
467
- );
474
+ attempts++;
475
+ try {
476
+ statusResult = await projectDeploymentStatus(
477
+ apiClient,
478
+ deployment?.id ?? ''
479
+ );
480
+
481
+ logger.trace('status result: %s', statusResult);
468
482
 
469
- logger.trace('status result: %s', statusResult);
483
+ if (statusResult.state === 'completed') {
484
+ logStreamController.abort();
485
+ break;
486
+ }
487
+
488
+ if (statusResult.state === 'failed') {
489
+ throw new Error('Deployment failed');
490
+ }
470
491
 
471
- if (statusResult.state === 'completed') {
492
+ await Bun.sleep(pollInterval);
493
+ } catch (err) {
472
494
  logStreamController.abort();
473
- break;
495
+ throw err;
474
496
  }
497
+ }
475
498
 
476
- if (statusResult.state === 'failed') {
477
- throw new Error('Deployment failed');
478
- }
499
+ // Wait for log stream to finish
500
+ await logStreamPromise;
479
501
 
480
- await Bun.sleep(pollInterval);
481
- } catch (err) {
482
- logStreamController.abort();
483
- throw err;
502
+ if (attempts >= maxAttempts) {
503
+ throw new Error('Deployment timed out');
504
+ }
505
+ },
506
+ })
507
+ .then(() => {
508
+ tui.success('Your project was deployed!');
509
+ })
510
+ .catch((ex) => {
511
+ // Handle cancellation
512
+ if (ex instanceof DeploymentCancelledError) {
513
+ tui.warning('Deployment cancelled');
514
+ process.exit(130); // Standard exit code for SIGINT
515
+ }
516
+ const exwithmessage = ex as { message: string };
517
+ const msg =
518
+ exwithmessage.message === 'Deployment failed'
519
+ ? ''
520
+ : exwithmessage.toString();
521
+ tui.error(`Your deployment failed to start${msg ? `: ${msg}` : ''}`);
522
+ if (logs.length) {
523
+ const logsDir = join(getDefaultConfigDir(), 'logs');
524
+ if (!existsSync(logsDir)) {
525
+ mkdirSync(logsDir, { recursive: true });
526
+ }
527
+ const errorFile = join(logsDir, `${deployment?.id ?? Date.now()}.txt`);
528
+ writeFileSync(errorFile, logs.join('\n'));
529
+ const count = Math.min(logs.length, 10);
530
+ const last = logs.length - count;
531
+ tui.newline();
532
+ tui.warning(`The last ${count} lines of the log:`);
533
+ let offset = last + 1; // we want to show the offset from inside the log starting at 1
534
+ const max = String(logs.length).length;
535
+ for (const _log of logs.slice(last)) {
536
+ console.log(tui.muted(`${offset.toFixed().padEnd(max)} | ${_log}`));
537
+ offset++;
484
538
  }
539
+ tui.newline();
540
+ tui.fatal(`The logs were written to ${errorFile}`, ErrorCode.BUILD_FAILED);
485
541
  }
542
+ tui.fatal('Deployment failed', ErrorCode.BUILD_FAILED);
543
+ });
544
+ } else {
545
+ // No stream ID - poll without log streaming
546
+ await tui.spinner({
547
+ message: 'Deploying project...',
548
+ type: 'simple',
549
+ clearOnSuccess: true,
550
+ callback: async () => {
551
+ while (attempts < maxAttempts) {
552
+ // Check if user pressed Ctrl+C
553
+ if (pollAbortController.signal.aborted) {
554
+ throw new DeploymentCancelledError();
555
+ }
556
+
557
+ attempts++;
558
+ statusResult = await projectDeploymentStatus(
559
+ apiClient,
560
+ deployment?.id ?? ''
561
+ );
562
+
563
+ if (statusResult.state === 'completed') {
564
+ break;
565
+ }
566
+
567
+ if (statusResult.state === 'failed') {
568
+ throw new Error('Deployment failed');
569
+ }
486
570
 
487
- // Wait for log stream to finish
488
- await logStreamPromise;
571
+ await Bun.sleep(pollInterval);
572
+ }
489
573
 
490
574
  if (attempts >= maxAttempts) {
491
575
  throw new Error('Deployment timed out');
492
576
  }
493
577
  },
494
- })
495
- .then(() => {
496
- tui.success('Your project was deployed!');
497
- })
498
- .catch((ex) => {
499
- const exwithmessage = ex as { message: string };
500
- const msg =
501
- exwithmessage.message === 'Deployment failed' ? '' : exwithmessage.toString();
502
- tui.error(`Your deployment failed to start${msg ? `: ${msg}` : ''}`);
503
- if (logs.length) {
504
- const logsDir = join(getDefaultConfigDir(), 'logs');
505
- if (!existsSync(logsDir)) {
506
- mkdirSync(logsDir, { recursive: true });
507
- }
508
- const errorFile = join(logsDir, `${deployment?.id ?? Date.now()}.txt`);
509
- writeFileSync(errorFile, logs.join('\n'));
510
- const count = Math.min(logs.length, 10);
511
- const last = logs.length - count;
512
- tui.newline();
513
- tui.warning(`The last ${count} lines of the log:`);
514
- let offset = last + 1; // we want to show the offset from inside the log starting at 1
515
- const max = String(logs.length).length;
516
- for (const _log of logs.slice(last)) {
517
- console.log(tui.muted(`${offset.toFixed().padEnd(max)} | ${_log}`));
518
- offset++;
519
- }
520
- tui.newline();
521
- tui.fatal(`The logs were written to ${errorFile}`, ErrorCode.BUILD_FAILED);
522
- }
523
- tui.fatal('Deployment failed', ErrorCode.BUILD_FAILED);
524
578
  });
525
- } else {
526
- // No stream ID - poll without log streaming
527
- await tui.spinner({
528
- message: 'Deploying project...',
529
- type: 'simple',
530
- clearOnSuccess: true,
531
- callback: async () => {
532
- while (attempts < maxAttempts) {
533
- attempts++;
534
- statusResult = await projectDeploymentStatus(apiClient, deployment?.id ?? '');
535
-
536
- if (statusResult.state === 'completed') {
537
- break;
538
- }
539
-
540
- if (statusResult.state === 'failed') {
541
- throw new Error('Deployment failed');
542
- }
543
579
 
544
- await Bun.sleep(pollInterval);
545
- }
546
-
547
- if (attempts >= maxAttempts) {
548
- throw new Error('Deployment timed out');
549
- }
550
- },
551
- });
552
-
553
- tui.success('Your project was deployed!');
580
+ tui.success('Your project was deployed!');
581
+ }
582
+ } finally {
583
+ // Clean up signal handler
584
+ process.off('SIGINT', sigintHandler);
554
585
  }
555
586
 
556
587
  const appUrl = getAppBaseURL(config?.name, config?.overrides);
@@ -60,6 +60,10 @@ export const listSubcommand = createSubcommand({
60
60
  }),
61
61
  response: DeploymentListResponseSchema,
62
62
  },
63
+ webUrl: (ctx) => {
64
+ const projectId = ctx.opts?.['project-id'] || ctx.project?.projectId;
65
+ return projectId ? `/projects/${encodeURIComponent(projectId)}/deployments` : undefined;
66
+ },
63
67
  async handler(ctx) {
64
68
  const projectId = resolveProjectId(ctx, { projectId: ctx.opts['project-id'] });
65
69
  const { apiClient, opts, options } = ctx;
@@ -29,6 +29,7 @@ export const listSubcommand = createSubcommand({
29
29
  }),
30
30
  response: EnvListResponseSchema,
31
31
  },
32
+ webUrl: (ctx) => `/projects/${encodeURIComponent(ctx.project.projectId)}/settings`,
32
33
 
33
34
  async handler(ctx) {
34
35
  const { opts, apiClient, project, options } = ctx;
@@ -27,6 +27,7 @@ export const getSubcommand = createCommand({
27
27
  }),
28
28
  response: KVGetResponseSchema,
29
29
  },
30
+ webUrl: (ctx) => `/services/kv/${encodeURIComponent(ctx.args.namespace)}`,
30
31
  idempotent: true,
31
32
 
32
33
  async handler(ctx) {
@@ -26,6 +26,7 @@ export const keysSubcommand = createCommand({
26
26
  }),
27
27
  response: KVKeysResponseSchema,
28
28
  },
29
+ webUrl: (ctx) => `/services/kv/${encodeURIComponent(ctx.args.name)}`,
29
30
 
30
31
  async handler(ctx) {
31
32
  const { args, options } = ctx;
@@ -19,6 +19,7 @@ export const listNamespacesSubcommand = createCommand({
19
19
  schema: {
20
20
  response: NamespaceListResponseSchema,
21
21
  },
22
+ webUrl: '/services/kv',
22
23
  idempotent: true,
23
24
 
24
25
  async handler(ctx) {
@@ -42,6 +42,8 @@ export const statsSubcommand = createCommand({
42
42
  }),
43
43
  response: KVStatsResponseSchema,
44
44
  },
45
+ webUrl: (ctx) =>
46
+ ctx.args.name ? `/services/kv/${encodeURIComponent(ctx.args.name)}` : '/services/kv',
45
47
 
46
48
  async handler(ctx) {
47
49
  const { args, options } = ctx;
@@ -26,6 +26,7 @@ export const listSubcommand = createSubcommand({
26
26
  }),
27
27
  response: SecretListResponseSchema,
28
28
  },
29
+ webUrl: (ctx) => `/projects/${encodeURIComponent(ctx.project.projectId)}/settings`,
29
30
 
30
31
  async handler(ctx) {
31
32
  const { opts, apiClient, project, options } = ctx;
@@ -88,6 +88,10 @@ export const listSubcommand = createSubcommand({
88
88
  }),
89
89
  response: SessionListResponseSchema,
90
90
  },
91
+ webUrl: (ctx) => {
92
+ const projectId = ctx.opts?.projectId || ctx.project?.projectId;
93
+ return projectId ? `/projects/${encodeURIComponent(projectId)}/sessions` : undefined;
94
+ },
91
95
  async handler(ctx) {
92
96
  const { logger, auth, project, opts, options, region } = ctx;
93
97
  const catalystClient = getCatalystAPIClient(logger, auth, region);
@@ -49,6 +49,7 @@ export const getSubcommand = createSubcommand({
49
49
  }),
50
50
  response: StorageGetResponseSchema,
51
51
  },
52
+ webUrl: (ctx) => `/services/storage/${encodeURIComponent(ctx.args.name)}`,
52
53
 
53
54
  async handler(ctx) {
54
55
  const { logger, args, opts, options, orgId, region, auth } = ctx;
@@ -72,6 +72,10 @@ export const listSubcommand = createSubcommand({
72
72
  }),
73
73
  response: StorageListResponseSchema,
74
74
  },
75
+ webUrl: (ctx) =>
76
+ ctx.args.name
77
+ ? `/services/storage/${encodeURIComponent(ctx.args.name)}`
78
+ : '/services/storage',
75
79
 
76
80
  async handler(ctx) {
77
81
  const { logger, args, opts, options, orgId, region, auth } = ctx;
@@ -46,6 +46,7 @@ export const getSubcommand = createCommand({
46
46
  }),
47
47
  response: GetStreamResponseSchema,
48
48
  },
49
+ webUrl: (ctx) => `/services/stream/${encodeURIComponent(ctx.args.id)}`,
49
50
 
50
51
  async handler(ctx) {
51
52
  const { args, opts, options } = ctx;
@@ -56,6 +56,7 @@ export const listSubcommand = createCommand({
56
56
  }),
57
57
  response: ListStreamsResponseSchema,
58
58
  },
59
+ webUrl: '/services/stream',
59
60
 
60
61
  async handler(ctx) {
61
62
  const { opts, options } = ctx;
@@ -39,6 +39,7 @@ export const getSubcommand = createCommand({
39
39
  }),
40
40
  response: VectorGetResponseSchema,
41
41
  },
42
+ webUrl: (ctx) => `/services/vector/${encodeURIComponent(ctx.args.namespace)}`,
42
43
 
43
44
  async handler(ctx) {
44
45
  const { args, options } = ctx;
@@ -66,6 +66,7 @@ export const searchSubcommand = createCommand({
66
66
  }),
67
67
  response: VectorSearchResponseSchema,
68
68
  },
69
+ webUrl: '/services/vector',
69
70
 
70
71
  async handler(ctx) {
71
72
  const { args, opts, options } = ctx;