@agentuity/cli 0.0.106 → 0.0.108

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 (74) hide show
  1. package/dist/cmd/build/entry-generator.d.ts.map +1 -1
  2. package/dist/cmd/build/entry-generator.js +43 -50
  3. package/dist/cmd/build/entry-generator.js.map +1 -1
  4. package/dist/cmd/build/index.d.ts.map +1 -1
  5. package/dist/cmd/build/index.js +9 -9
  6. package/dist/cmd/build/index.js.map +1 -1
  7. package/dist/cmd/build/typecheck.d.ts +23 -0
  8. package/dist/cmd/build/typecheck.d.ts.map +1 -0
  9. package/dist/cmd/build/typecheck.js +38 -0
  10. package/dist/cmd/build/typecheck.js.map +1 -0
  11. package/dist/cmd/build/vite/metadata-generator.d.ts +2 -1
  12. package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
  13. package/dist/cmd/build/vite/metadata-generator.js +14 -0
  14. package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
  15. package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
  16. package/dist/cmd/build/vite/vite-asset-server-config.js +15 -8
  17. package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
  18. package/dist/cmd/build/vite/vite-asset-server.d.ts.map +1 -1
  19. package/dist/cmd/build/vite/vite-asset-server.js +6 -2
  20. package/dist/cmd/build/vite/vite-asset-server.js.map +1 -1
  21. package/dist/cmd/build/vite/vite-builder.d.ts +2 -1
  22. package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
  23. package/dist/cmd/build/vite/vite-builder.js +15 -2
  24. package/dist/cmd/build/vite/vite-builder.js.map +1 -1
  25. package/dist/cmd/build/vite-bundler.d.ts +2 -1
  26. package/dist/cmd/build/vite-bundler.d.ts.map +1 -1
  27. package/dist/cmd/build/vite-bundler.js +2 -1
  28. package/dist/cmd/build/vite-bundler.js.map +1 -1
  29. package/dist/cmd/cloud/deploy.d.ts.map +1 -1
  30. package/dist/cmd/cloud/deploy.js +50 -24
  31. package/dist/cmd/cloud/deploy.js.map +1 -1
  32. package/dist/cmd/dev/index.d.ts.map +1 -1
  33. package/dist/cmd/dev/index.js +623 -578
  34. package/dist/cmd/dev/index.js.map +1 -1
  35. package/dist/schema-parser.d.ts.map +1 -1
  36. package/dist/schema-parser.js +17 -3
  37. package/dist/schema-parser.js.map +1 -1
  38. package/dist/tsc-output-parser.d.ts +54 -0
  39. package/dist/tsc-output-parser.d.ts.map +1 -0
  40. package/dist/tsc-output-parser.js +926 -0
  41. package/dist/tsc-output-parser.js.map +1 -0
  42. package/dist/tui.d.ts +77 -0
  43. package/dist/tui.d.ts.map +1 -1
  44. package/dist/tui.js +27 -2
  45. package/dist/tui.js.map +1 -1
  46. package/dist/types.d.ts +24 -0
  47. package/dist/types.d.ts.map +1 -1
  48. package/dist/types.js +22 -0
  49. package/dist/types.js.map +1 -1
  50. package/dist/typescript-errors.d.ts +26 -0
  51. package/dist/typescript-errors.d.ts.map +1 -0
  52. package/dist/typescript-errors.js +249 -0
  53. package/dist/typescript-errors.js.map +1 -0
  54. package/package.json +4 -4
  55. package/src/cmd/build/entry-generator.ts +43 -51
  56. package/src/cmd/build/index.ts +13 -10
  57. package/src/cmd/build/typecheck.ts +55 -0
  58. package/src/cmd/build/vite/metadata-generator.ts +17 -1
  59. package/src/cmd/build/vite/vite-asset-server-config.ts +17 -8
  60. package/src/cmd/build/vite/vite-asset-server.ts +6 -2
  61. package/src/cmd/build/vite/vite-builder.ts +16 -3
  62. package/src/cmd/build/vite-bundler.ts +4 -1
  63. package/src/cmd/cloud/deploy.ts +68 -32
  64. package/src/cmd/dev/index.ts +713 -657
  65. package/src/schema-parser.ts +17 -3
  66. package/src/tsc-output-parser.ts +1115 -0
  67. package/src/tui.ts +40 -2
  68. package/src/types.ts +25 -0
  69. package/src/typescript-errors.ts +382 -0
  70. package/dist/schemas/deploy.d.ts +0 -24
  71. package/dist/schemas/deploy.d.ts.map +0 -1
  72. package/dist/schemas/deploy.js +0 -26
  73. package/dist/schemas/deploy.js.map +0 -1
  74. package/src/schemas/deploy.ts +0 -28
@@ -6,6 +6,7 @@
6
6
  */
7
7
 
8
8
  import { join } from 'node:path';
9
+ import { createRequire } from 'node:module';
9
10
  import type { InlineConfig } from 'vite';
10
11
  import type { Logger } from '../../../types';
11
12
 
@@ -116,14 +117,22 @@ export async function generateAssetServerConfig(
116
117
  },
117
118
 
118
119
  // Plugins: User plugins first (e.g., Tailwind), then React and browser env
119
- plugins: [
120
- // User-defined plugins from agentuity.config.ts (e.g., Tailwind CSS)
121
- ...userPlugins,
122
- // React plugin for JSX/TSX transformation and Fast Refresh
123
- (await import('@vitejs/plugin-react')).default(),
124
- // Browser env plugin to map process.env to import.meta.env
125
- (await import('./browser-env-plugin')).browserEnvPlugin(),
126
- ],
120
+ // Resolve @vitejs/plugin-react from the project's node_modules
121
+ plugins: await (async () => {
122
+ const projectRequire = createRequire(join(rootDir, 'package.json'));
123
+ const reactPlugin = (
124
+ await import(projectRequire.resolve('@vitejs/plugin-react'))
125
+ ).default();
126
+ const { browserEnvPlugin } = await import('./browser-env-plugin');
127
+ return [
128
+ // User-defined plugins from agentuity.config.ts (e.g., Tailwind CSS)
129
+ ...userPlugins,
130
+ // React plugin for JSX/TSX transformation and Fast Refresh
131
+ reactPlugin,
132
+ // Browser env plugin to map process.env to import.meta.env
133
+ browserEnvPlugin(),
134
+ ];
135
+ })(),
127
136
 
128
137
  // Suppress build-related options (this is dev-only)
129
138
  build: {
@@ -5,6 +5,8 @@
5
5
  * Does NOT handle API routes or WebSocket - the Bun server proxies to this.
6
6
  */
7
7
 
8
+ import { join } from 'node:path';
9
+ import { createRequire } from 'node:module';
8
10
  import type { ViteDevServer } from 'vite';
9
11
  import type { Logger } from '../../../types';
10
12
  import { generateAssetServerConfig } from './vite-asset-server-config';
@@ -43,8 +45,10 @@ export async function startViteAssetServer(
43
45
  port: preferredPort,
44
46
  });
45
47
 
46
- // Dynamically import vite
47
- const { createServer } = await import('vite');
48
+ // Dynamically import vite from the project's node_modules
49
+ // This ensures we resolve from the target project directory, not the CWD
50
+ const projectRequire = createRequire(join(rootDir, 'package.json'));
51
+ const { createServer } = await import(projectRequire.resolve('vite'));
48
52
 
49
53
  // Create Vite server with config
50
54
  const server = await createServer(config);
@@ -6,8 +6,9 @@
6
6
 
7
7
  import { join } from 'node:path';
8
8
  import { existsSync, renameSync, rmSync } from 'node:fs';
9
+ import { createRequire } from 'node:module';
9
10
  import type { InlineConfig, Plugin } from 'vite';
10
- import type { Logger } from '../../../types';
11
+ import type { Logger, DeployOptions } from '../../../types';
11
12
  import { browserEnvPlugin } from './browser-env-plugin';
12
13
 
13
14
  /**
@@ -54,6 +55,7 @@ export interface ViteBuildOptions {
54
55
  workbenchRoute?: string;
55
56
  workbenchEnabled?: boolean;
56
57
  logger: Logger;
58
+ deploymentOptions?: DeployOptions;
57
59
  }
58
60
 
59
61
  /**
@@ -105,8 +107,18 @@ export async function runViteBuild(options: ViteBuildOptions): Promise<void> {
105
107
  }
106
108
 
107
109
  // Dynamically import vite and react plugin
108
- const { build: viteBuild } = await import('vite');
109
- const reactModule = await import('@vitejs/plugin-react');
110
+ // Try project's node_modules first (for custom vite configs), fall back to CLI's
111
+ const projectRequire = createRequire(join(rootDir, 'package.json'));
112
+ let vitePath = 'vite';
113
+ let reactPluginPath = '@vitejs/plugin-react';
114
+ try {
115
+ vitePath = projectRequire.resolve('vite');
116
+ reactPluginPath = projectRequire.resolve('@vitejs/plugin-react');
117
+ } catch {
118
+ // Project doesn't have vite, use CLI's bundled version
119
+ }
120
+ const { build: viteBuild } = await import(vitePath);
121
+ const reactModule = await import(reactPluginPath);
110
122
  const react = reactModule.default;
111
123
 
112
124
  // For client/workbench, use inline config (no agentuity plugin needed)
@@ -341,6 +353,7 @@ export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Pro
341
353
  routes,
342
354
  logger,
343
355
  dev,
356
+ deploymentOptions: options.deploymentOptions,
344
357
  });
345
358
 
346
359
  writeMetadataFile(rootDir, metadata, dev, logger);
@@ -7,7 +7,7 @@
7
7
  import { join } from 'node:path';
8
8
  import { stat } from 'node:fs/promises';
9
9
  import { StructuredError } from '@agentuity/core';
10
- import type { Logger } from '../../types';
10
+ import type { Logger, DeployOptions } from '../../types';
11
11
  import { runAllBuilds } from './vite/vite-builder';
12
12
  import { checkAndUpgradeDependencies } from '../../utils/dependency-checker';
13
13
  import { checkBunVersion } from '../../utils/bun-version-checker';
@@ -25,6 +25,7 @@ export interface ViteBundleOptions {
25
25
  deploymentId?: string;
26
26
  port?: number;
27
27
  logger: Logger;
28
+ deploymentOptions?: DeployOptions;
28
29
  }
29
30
 
30
31
  /**
@@ -39,6 +40,7 @@ export async function viteBundle(options: ViteBundleOptions): Promise<{ output:
39
40
  deploymentId = '',
40
41
  port = 3500,
41
42
  logger,
43
+ deploymentOptions,
42
44
  } = options;
43
45
 
44
46
  const output: string[] = [];
@@ -87,6 +89,7 @@ export async function viteBundle(options: ViteBundleOptions): Promise<{ output:
87
89
  region,
88
90
  deploymentId,
89
91
  logger,
92
+ deploymentOptions,
90
93
  });
91
94
 
92
95
  if (result.client.included) {
@@ -5,7 +5,7 @@ import { createReadStream, createWriteStream, existsSync, mkdirSync, writeFileSy
5
5
  import { tmpdir } from 'node:os';
6
6
  import { StructuredError } from '@agentuity/core';
7
7
  import { isRunningFromExecutable } from '../upgrade';
8
- import { createSubcommand } from '../../types';
8
+ import { createSubcommand, DeployOptionsSchema } from '../../types';
9
9
  import { getUserAgent } from '../../api';
10
10
  import * as tui from '../../tui';
11
11
  import { saveProjectDir, getDefaultConfigDir, loadProjectSDKKey } from '../../config';
@@ -43,8 +43,8 @@ import { zipDir } from '../../utils/zip';
43
43
  import { encryptFIPSKEMDEMStream } from '../../crypto/box';
44
44
  import { getCommand } from '../../command-prefix';
45
45
  import * as domain from '../../domain';
46
- import { DeployOptionsSchema } from '../../schemas/deploy';
47
46
  import { ErrorCode } from '../../errors';
47
+ import { typecheck } from '../build/typecheck';
48
48
 
49
49
  const DeploymentCancelledError = StructuredError(
50
50
  'DeploymentCancelled',
@@ -84,22 +84,23 @@ export const deploySubcommand = createSubcommand({
84
84
  command: getCommand('cloud deploy --log-level=debug'),
85
85
  description: 'Deploy with verbose output',
86
86
  },
87
- {
88
- command: getCommand('cloud deploy --tag a --tag b'),
89
- description: 'Deploy with specific tags',
90
- },
91
87
  ],
92
88
  toplevel: true,
93
89
  idempotent: false,
94
90
  requires: { auth: true, project: true, apiClient: true },
95
91
  prerequisites: ['auth login'],
96
92
  schema: {
97
- options: DeployOptionsSchema,
93
+ options: z.intersection(
94
+ DeployOptionsSchema,
95
+ z.object({
96
+ saveTypeErrors: z.string().optional().describe('file path to save typecheck errors'),
97
+ })
98
+ ),
98
99
  response: DeployResponseSchema,
99
100
  },
100
101
 
101
102
  async handler(ctx) {
102
- const { project, apiClient, projectDir, config, options, logger } = ctx;
103
+ const { project, apiClient, projectDir, config, options, logger, opts } = ctx;
103
104
 
104
105
  let deployment: Deployment | undefined;
105
106
  let build: BuildMetadata | undefined;
@@ -108,7 +109,17 @@ export const deploySubcommand = createSubcommand({
108
109
  let statusResult: DeploymentStatusResult | undefined;
109
110
  const logs: string[] = [];
110
111
 
111
- // Check for pre-created deployment from CI/Nova
112
+ const sdkKey = await loadProjectSDKKey(ctx.logger, ctx.projectDir);
113
+
114
+ // Ensure SDK key is present before proceeding
115
+ if (!sdkKey) {
116
+ ctx.logger.fatal(
117
+ 'The AGENTUITY_SDK_KEY value not found in the .env file in this folder. Ensure you are inside a valid Agentuity project folder and run "%s" to pull your environment from the cloud.',
118
+ getCommand('cloud env pull')
119
+ );
120
+ }
121
+
122
+ // Check for pre-created deployment from CI build environment
112
123
  const deploymentEnv = process.env.AGENTUITY_DEPLOYMENT;
113
124
  let useExistingDeployment = false;
114
125
  if (deploymentEnv) {
@@ -123,29 +134,18 @@ export const deploySubcommand = createSubcommand({
123
134
  if (result.success) {
124
135
  deployment = result.data;
125
136
  useExistingDeployment = true;
126
- logger.info(`Using existing deployment: ${result.data.id}`);
137
+ logger.debug('Using existing deployment: %s', result.data.id);
127
138
  } else {
128
139
  const errors = result.error.issues
129
140
  .map((i) => `${i.path.join('.')}: ${i.message}`)
130
141
  .join(', ');
131
- logger.warn(`Invalid AGENTUITY_DEPLOYMENT schema: ${errors}`);
142
+ logger.fatal(`Invalid AGENTUITY_DEPLOYMENT schema: ${errors}`);
132
143
  }
133
144
  } catch (err) {
134
- logger.warn(
135
- `Failed to parse AGENTUITY_DEPLOYMENT: ${err instanceof Error ? err.message : String(err)}`
136
- );
145
+ logger.fatal(`Failed to parse AGENTUITY_DEPLOYMENT: ${err}`);
137
146
  }
138
147
  }
139
148
 
140
- const sdkKey = await loadProjectSDKKey(ctx.logger, ctx.projectDir);
141
-
142
- // Ensure SDK key is present before proceeding
143
- if (!sdkKey) {
144
- ctx.logger.fatal(
145
- 'SDK key not found. Run "agentuity auth login" to authenticate or set AGENTUITY_SDK_KEY environment variable.'
146
- );
147
- }
148
-
149
149
  try {
150
150
  await saveProjectDir(projectDir);
151
151
 
@@ -176,6 +176,9 @@ export const deploySubcommand = createSubcommand({
176
176
  label: 'Sync Env & Secrets',
177
177
  run: async () => {
178
178
  try {
179
+ if (useExistingDeployment) {
180
+ return stepSkipped('skipped in CI build');
181
+ }
179
182
  // Read env file
180
183
  const envFilePath = await findExistingEnvFile(projectDir);
181
184
  const localEnv = await readEnvFile(envFilePath);
@@ -212,8 +215,8 @@ export const deploySubcommand = createSubcommand({
212
215
  {
213
216
  label: 'Create Deployment',
214
217
  run: async () => {
215
- if (useExistingDeployment && deployment) {
216
- return stepSkipped('using existing deployment');
218
+ if (useExistingDeployment) {
219
+ return stepSkipped('skipped in CI build');
217
220
  }
218
221
  try {
219
222
  deployment = await projectDeploymentCreate(
@@ -235,17 +238,34 @@ export const deploySubcommand = createSubcommand({
235
238
  return stepError('deployment was null');
236
239
  }
237
240
  let capturedOutput: string[] = [];
241
+ const rootDir = resolve(projectDir);
242
+ const started = Date.now();
243
+ const typeResult = await typecheck(rootDir);
244
+ if (typeResult.success) {
245
+ capturedOutput.push(
246
+ tui.muted(
247
+ `✓ Typechecked in ${Math.floor(Date.now() - started).toFixed(0)}ms`
248
+ )
249
+ );
250
+ } else {
251
+ if ('errors' in typeResult && opts.saveTypeErrors) {
252
+ const f = Bun.file(opts.saveTypeErrors);
253
+ await f.write(JSON.stringify(typeResult.errors));
254
+ }
255
+ return stepError('Typecheck failed\n\n' + typeResult.output);
256
+ }
238
257
  try {
239
258
  const bundleResult = await viteBundle({
240
- rootDir: resolve(projectDir),
259
+ rootDir,
241
260
  dev: false,
242
261
  deploymentId: deployment.id,
243
262
  orgId: deployment.orgId,
244
263
  projectId: project.projectId,
245
264
  region: project.region,
246
265
  logger: ctx.logger,
266
+ deploymentOptions: opts,
247
267
  });
248
- capturedOutput = bundleResult.output;
268
+ capturedOutput = [...capturedOutput, ...bundleResult.output];
249
269
  build = await loadBuildMetadata(join(projectDir, '.agentuity'));
250
270
  instructions = await projectDeploymentUpdate(
251
271
  apiClient,
@@ -462,7 +482,7 @@ export const deploySubcommand = createSubcommand({
462
482
  },
463
483
  },
464
484
  ].filter(Boolean) as Step[],
465
- useExistingDeployment ? 'debug' : options.logLevel
485
+ options.logLevel
466
486
  );
467
487
 
468
488
  if (!deployment) {
@@ -473,7 +493,14 @@ export const deploySubcommand = createSubcommand({
473
493
  };
474
494
  }
475
495
 
496
+ // TODO: send the deployment failure to the backend otherwise we staying in a deploying state
497
+
476
498
  const streamId = complete?.streamId;
499
+ const appUrl = getAppBaseURL(
500
+ process.env.AGENTUITY_REGION ?? config?.name,
501
+ config?.overrides
502
+ );
503
+ const dashboard = `${appUrl}/r/${deployment.id}`;
477
504
 
478
505
  // Poll for deployment status with optional log streaming
479
506
  const pollInterval = 500;
@@ -662,15 +689,24 @@ export const deploySubcommand = createSubcommand({
662
689
 
663
690
  tui.success('Your project was deployed!');
664
691
  }
692
+ } catch (ex) {
693
+ const lines = [`${ex}`, ''];
694
+ lines.push(
695
+ `${tui.ICONS.arrow} ${
696
+ tui.bold(tui.padRight('Dashboard:', 12)) + tui.link(dashboard)
697
+ }`
698
+ );
699
+ tui.banner(tui.colorError(`Deployment: ${deployment.id} Failed`), lines.join('\n'), {
700
+ centerTitle: false,
701
+ topSpacer: false,
702
+ bottomSpacer: false,
703
+ });
704
+ tui.fatal('Deployment failed', ErrorCode.BUILD_FAILED);
665
705
  } finally {
666
706
  // Clean up signal handler
667
707
  process.off('SIGINT', sigintHandler);
668
708
  }
669
709
 
670
- const appUrl = getAppBaseURL(config?.name, config?.overrides);
671
-
672
- const dashboard = `${appUrl}/r/${deployment.id}`;
673
-
674
710
  // Show deployment URLs
675
711
  if (complete?.publicUrls) {
676
712
  const lines: string[] = [];