@agentuity/cli 1.0.9 → 1.0.11
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.
- package/dist/cmd/build/ast.d.ts +1 -1
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +103 -5
- package/dist/cmd/build/ast.js.map +1 -1
- package/dist/cmd/build/entry-generator.d.ts.map +1 -1
- package/dist/cmd/build/entry-generator.js +1 -8
- package/dist/cmd/build/entry-generator.js.map +1 -1
- package/dist/cmd/build/vite/config-loader.d.ts +9 -0
- package/dist/cmd/build/vite/config-loader.d.ts.map +1 -1
- package/dist/cmd/build/vite/config-loader.js +30 -0
- package/dist/cmd/build/vite/config-loader.js.map +1 -1
- package/dist/cmd/build/vite/index.d.ts +2 -0
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +2 -1
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts +4 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +1 -0
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/route-discovery.js +23 -1
- package/dist/cmd/build/vite/route-discovery.js.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-asset-server-config.js +19 -14
- package/dist/cmd/build/vite/vite-asset-server-config.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts +2 -0
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +13 -8
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite-bundler.d.ts +2 -0
- package/dist/cmd/build/vite-bundler.d.ts.map +1 -1
- package/dist/cmd/build/vite-bundler.js +2 -1
- package/dist/cmd/build/vite-bundler.js.map +1 -1
- package/dist/cmd/cloud/db/list.d.ts.map +1 -1
- package/dist/cmd/cloud/db/list.js +14 -1
- package/dist/cmd/cloud/db/list.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +36 -22
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/queue/list.d.ts.map +1 -1
- package/dist/cmd/cloud/queue/list.js +10 -0
- package/dist/cmd/cloud/queue/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/list.js +10 -0
- package/dist/cmd/cloud/sandbox/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/runtime/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/runtime/list.js +10 -0
- package/dist/cmd/cloud/sandbox/runtime/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.js +10 -0
- package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
- package/dist/cmd/cloud/session/get.js +12 -12
- package/dist/cmd/cloud/session/get.js.map +1 -1
- package/dist/cmd/cloud/session/list.d.ts.map +1 -1
- package/dist/cmd/cloud/session/list.js +14 -4
- package/dist/cmd/cloud/session/list.js.map +1 -1
- package/dist/cmd/cloud/storage/list.d.ts.map +1 -1
- package/dist/cmd/cloud/storage/list.js +14 -1
- package/dist/cmd/cloud/storage/list.js.map +1 -1
- package/dist/cmd/cloud/stream/list.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/list.js +10 -0
- package/dist/cmd/cloud/stream/list.js.map +1 -1
- package/dist/cmd/cloud/thread/list.d.ts.map +1 -1
- package/dist/cmd/cloud/thread/list.js +10 -0
- package/dist/cmd/cloud/thread/list.js.map +1 -1
- package/dist/cmd/dev/download.d.ts.map +1 -1
- package/dist/cmd/dev/download.js +63 -53
- package/dist/cmd/dev/download.js.map +1 -1
- package/dist/cmd/project/domain/check.d.ts +2 -0
- package/dist/cmd/project/domain/check.d.ts.map +1 -0
- package/dist/cmd/project/domain/check.js +131 -0
- package/dist/cmd/project/domain/check.js.map +1 -0
- package/dist/cmd/project/domain/index.d.ts +2 -0
- package/dist/cmd/project/domain/index.d.ts.map +1 -0
- package/dist/cmd/project/domain/index.js +20 -0
- package/dist/cmd/project/domain/index.js.map +1 -0
- package/dist/cmd/project/hostname/get.d.ts +2 -0
- package/dist/cmd/project/hostname/get.d.ts.map +1 -0
- package/dist/cmd/project/hostname/get.js +50 -0
- package/dist/cmd/project/hostname/get.js.map +1 -0
- package/dist/cmd/project/hostname/index.d.ts +2 -0
- package/dist/cmd/project/hostname/index.d.ts.map +1 -0
- package/dist/cmd/project/hostname/index.js +18 -0
- package/dist/cmd/project/hostname/index.js.map +1 -0
- package/dist/cmd/project/hostname/set.d.ts +2 -0
- package/dist/cmd/project/hostname/set.d.ts.map +1 -0
- package/dist/cmd/project/hostname/set.js +100 -0
- package/dist/cmd/project/hostname/set.js.map +1 -0
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/index.js +12 -0
- package/dist/cmd/project/index.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/steps.d.ts +9 -0
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +131 -71
- package/dist/steps.js.map +1 -1
- package/dist/tui.d.ts +2 -2
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +6 -4
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +4 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +6 -7
- package/src/cmd/build/ast.ts +141 -5
- package/src/cmd/build/entry-generator.ts +1 -8
- package/src/cmd/build/vite/config-loader.ts +35 -0
- package/src/cmd/build/vite/index.ts +4 -0
- package/src/cmd/build/vite/metadata-generator.ts +5 -1
- package/src/cmd/build/vite/route-discovery.ts +34 -1
- package/src/cmd/build/vite/vite-asset-server-config.ts +22 -13
- package/src/cmd/build/vite/vite-builder.ts +20 -8
- package/src/cmd/build/vite-bundler.ts +4 -0
- package/src/cmd/cloud/db/list.ts +14 -1
- package/src/cmd/cloud/deploy.ts +46 -21
- package/src/cmd/cloud/queue/list.ts +10 -0
- package/src/cmd/cloud/sandbox/list.ts +10 -0
- package/src/cmd/cloud/sandbox/runtime/list.ts +10 -0
- package/src/cmd/cloud/sandbox/snapshot/list.ts +10 -0
- package/src/cmd/cloud/session/get.ts +12 -12
- package/src/cmd/cloud/session/list.ts +28 -18
- package/src/cmd/cloud/storage/list.ts +14 -1
- package/src/cmd/cloud/stream/list.ts +18 -8
- package/src/cmd/cloud/thread/list.ts +15 -5
- package/src/cmd/dev/download.ts +76 -78
- package/src/cmd/project/domain/check.ts +146 -0
- package/src/cmd/project/domain/index.ts +20 -0
- package/src/cmd/project/hostname/get.ts +54 -0
- package/src/cmd/project/hostname/index.ts +18 -0
- package/src/cmd/project/hostname/set.ts +123 -0
- package/src/cmd/project/index.ts +12 -0
- package/src/index.ts +1 -1
- package/src/steps.ts +139 -74
- package/src/tui.ts +6 -4
- package/src/types.ts +4 -2
|
@@ -71,3 +71,38 @@ export function getWorkbenchConfig(
|
|
|
71
71
|
headers: workbench.headers ?? {},
|
|
72
72
|
};
|
|
73
73
|
}
|
|
74
|
+
|
|
75
|
+
/**
|
|
76
|
+
* Known Vite framework plugin name prefixes.
|
|
77
|
+
* Each framework's Vite plugin registers one or more plugins whose names
|
|
78
|
+
* start with these prefixes. We match against these to detect whether the
|
|
79
|
+
* user has already configured a framework plugin in their agentuity.config.ts.
|
|
80
|
+
*/
|
|
81
|
+
const FRAMEWORK_PLUGIN_PREFIXES = [
|
|
82
|
+
'vite:react', // @vitejs/plugin-react (vite:react-babel, vite:react-refresh, …)
|
|
83
|
+
'vite:preact', // @preact/preset-vite
|
|
84
|
+
'vite-plugin-svelte', // @sveltejs/vite-plugin-svelte
|
|
85
|
+
'vite:vue', // @vitejs/plugin-vue (vite:vue, vite:vue-jsx)
|
|
86
|
+
'vite-plugin-solid', // vite-plugin-solid
|
|
87
|
+
'solid', // vite-plugin-solid also uses plain "solid"
|
|
88
|
+
];
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* Check if the user's plugins include any known UI-framework Vite plugin
|
|
92
|
+
* (React, Svelte, Vue, Solid, Preact, …).
|
|
93
|
+
*
|
|
94
|
+
* Detection is name-based: Vite plugins expose a `name` property and every
|
|
95
|
+
* major framework plugin uses a predictable prefix. This avoids dynamically
|
|
96
|
+
* importing every possible framework just to compare names.
|
|
97
|
+
*/
|
|
98
|
+
export function hasFrameworkPlugin(userPlugins: import('vite').PluginOption[]): boolean {
|
|
99
|
+
const flat = (userPlugins as unknown[]).flat(Infinity).filter(Boolean);
|
|
100
|
+
return flat.some(
|
|
101
|
+
(p: unknown) =>
|
|
102
|
+
p &&
|
|
103
|
+
typeof p === 'object' &&
|
|
104
|
+
'name' in p &&
|
|
105
|
+
typeof (p as { name: unknown }).name === 'string' &&
|
|
106
|
+
FRAMEWORK_PLUGIN_PREFIXES.some((prefix) => (p as { name: string }).name.startsWith(prefix))
|
|
107
|
+
);
|
|
108
|
+
}
|
|
@@ -23,6 +23,8 @@ export interface AgentuityPluginOptions {
|
|
|
23
23
|
deploymentId?: string;
|
|
24
24
|
logLevel?: LogLevel;
|
|
25
25
|
deploymentOptions?: DeployOptions;
|
|
26
|
+
/** Deployment config from agentuity.json (resources, mode, dependencies, domains) */
|
|
27
|
+
deploymentConfig?: Record<string, unknown>;
|
|
26
28
|
/** Optional config profile name (e.g., 'staging', 'test') for .env.{profile} files */
|
|
27
29
|
profile?: string;
|
|
28
30
|
}
|
|
@@ -48,6 +50,7 @@ export function agentuityPlugin(options: AgentuityPluginOptions): Plugin {
|
|
|
48
50
|
deploymentId = '',
|
|
49
51
|
logLevel = 'info',
|
|
50
52
|
deploymentOptions,
|
|
53
|
+
deploymentConfig,
|
|
51
54
|
profile,
|
|
52
55
|
} = options;
|
|
53
56
|
const logger = createLogger(logLevel);
|
|
@@ -173,6 +176,7 @@ export function agentuityPlugin(options: AgentuityPluginOptions): Plugin {
|
|
|
173
176
|
dev,
|
|
174
177
|
logger,
|
|
175
178
|
deploymentOptions,
|
|
179
|
+
deploymentConfig,
|
|
176
180
|
});
|
|
177
181
|
|
|
178
182
|
// Write metadata file
|
|
@@ -6,7 +6,8 @@
|
|
|
6
6
|
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { writeFileSync, mkdirSync, existsSync, readFileSync, statSync, readdirSync } from 'node:fs';
|
|
9
|
-
import type
|
|
9
|
+
import { type BuildMetadata, DeploymentConfig } from '@agentuity/server';
|
|
10
|
+
import type { z } from 'zod';
|
|
10
11
|
import type { AgentMetadata } from './agent-discovery';
|
|
11
12
|
import type { RouteMetadata } from './route-discovery';
|
|
12
13
|
import type { Logger, DeployOptions } from '../../../types';
|
|
@@ -164,6 +165,8 @@ export interface MetadataGeneratorOptions {
|
|
|
164
165
|
dev?: boolean;
|
|
165
166
|
logger: Logger;
|
|
166
167
|
deploymentOptions?: DeployOptions;
|
|
168
|
+
/** Deployment config from agentuity.json (resources, mode, dependencies, domains) */
|
|
169
|
+
deploymentConfig?: z.infer<typeof DeploymentConfig>;
|
|
167
170
|
}
|
|
168
171
|
|
|
169
172
|
/**
|
|
@@ -473,6 +476,7 @@ export async function generateMetadata(options: MetadataGeneratorOptions): Promi
|
|
|
473
476
|
orgId,
|
|
474
477
|
},
|
|
475
478
|
deployment: {
|
|
479
|
+
...options.deploymentConfig, // deployment config from agentuity.json (resources, mode, dependencies, domains)
|
|
476
480
|
id: options.deploymentId || '',
|
|
477
481
|
date: new Date().toISOString(),
|
|
478
482
|
build: {
|
|
@@ -85,6 +85,10 @@ export async function discoverRoutes(
|
|
|
85
85
|
|
|
86
86
|
const transpiler = new Bun.Transpiler({ loader: 'ts', target: 'bun' });
|
|
87
87
|
|
|
88
|
+
// Track files that are mounted as sub-routers via .route()
|
|
89
|
+
// These files will be parsed standalone AND via .route() — we need to deduplicate
|
|
90
|
+
const mountedSubrouters = new Set<string>();
|
|
91
|
+
|
|
88
92
|
// Scan all .ts files in api directory
|
|
89
93
|
const glob = new Bun.Glob('**/*.ts');
|
|
90
94
|
for await (const file of glob.scan(apiDir)) {
|
|
@@ -104,7 +108,14 @@ export async function discoverRoutes(
|
|
|
104
108
|
const relativeFilename = './' + relative(srcDir, filePath);
|
|
105
109
|
|
|
106
110
|
try {
|
|
107
|
-
const parsedRoutes = await parseRoute(
|
|
111
|
+
const parsedRoutes = await parseRoute(
|
|
112
|
+
rootDir,
|
|
113
|
+
filePath,
|
|
114
|
+
projectId,
|
|
115
|
+
deploymentId,
|
|
116
|
+
undefined,
|
|
117
|
+
mountedSubrouters
|
|
118
|
+
);
|
|
108
119
|
|
|
109
120
|
if (parsedRoutes.length > 0) {
|
|
110
121
|
logger.trace('Discovered %d route(s) in %s', parsedRoutes.length, relativeFilename);
|
|
@@ -165,6 +176,28 @@ export async function discoverRoutes(
|
|
|
165
176
|
}
|
|
166
177
|
}
|
|
167
178
|
|
|
179
|
+
// Filter out routes from standalone-parsed sub-router files
|
|
180
|
+
// When a file is mounted via .route(), its standalone routes have wrong prefixes
|
|
181
|
+
// Only the .route()-prefixed routes (attached to the parent file) are correct
|
|
182
|
+
if (mountedSubrouters.size > 0) {
|
|
183
|
+
const rootDir = join(srcDir, '..');
|
|
184
|
+
const subrouterRelPaths = new Set<string>();
|
|
185
|
+
for (const absPath of mountedSubrouters) {
|
|
186
|
+
subrouterRelPaths.add(relative(rootDir, absPath));
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Remove routes whose filename matches a sub-router file
|
|
190
|
+
// (these are the incorrectly-prefixed standalone routes)
|
|
191
|
+
const filteredRoutes = routes.filter((r) => !subrouterRelPaths.has(r.filename));
|
|
192
|
+
const filteredRouteInfoList = routeInfoList.filter((r) => !subrouterRelPaths.has(r.filename));
|
|
193
|
+
|
|
194
|
+
// Replace arrays in-place
|
|
195
|
+
routes.length = 0;
|
|
196
|
+
routes.push(...filteredRoutes);
|
|
197
|
+
routeInfoList.length = 0;
|
|
198
|
+
routeInfoList.push(...filteredRouteInfoList);
|
|
199
|
+
}
|
|
200
|
+
|
|
168
201
|
logger.debug('Discovered %d route(s)', routes.length);
|
|
169
202
|
|
|
170
203
|
// Check for route conflicts
|
|
@@ -128,24 +128,33 @@ export async function generateAssetServerConfig(
|
|
|
128
128
|
'process.env.NODE_ENV': JSON.stringify('development'),
|
|
129
129
|
},
|
|
130
130
|
|
|
131
|
-
// Plugins: User plugins first (
|
|
131
|
+
// Plugins: User plugins first (includes framework plugin like React/Svelte/Vue), then browser env
|
|
132
132
|
// Try project's node_modules first, fall back to CLI's bundled version
|
|
133
133
|
plugins: await (async () => {
|
|
134
|
-
const projectRequire = createRequire(join(rootDir, 'package.json'));
|
|
135
|
-
let reactPluginPath = '@vitejs/plugin-react';
|
|
136
|
-
try {
|
|
137
|
-
reactPluginPath = projectRequire.resolve('@vitejs/plugin-react');
|
|
138
|
-
} catch {
|
|
139
|
-
// Project doesn't have @vitejs/plugin-react, use CLI's bundled version
|
|
140
|
-
}
|
|
141
|
-
const reactPlugin = (await import(reactPluginPath)).default();
|
|
142
134
|
const { browserEnvPlugin } = await import('./browser-env-plugin');
|
|
143
135
|
const { publicAssetPathPlugin } = await import('./public-asset-path-plugin');
|
|
136
|
+
const { hasFrameworkPlugin } = await import('./config-loader');
|
|
137
|
+
|
|
138
|
+
// Auto-add React plugin if no framework plugin is present (backwards compatibility)
|
|
139
|
+
const resolvedUserPlugins = [...userPlugins];
|
|
140
|
+
if (resolvedUserPlugins.length === 0 || !hasFrameworkPlugin(resolvedUserPlugins)) {
|
|
141
|
+
logger.debug(
|
|
142
|
+
'No framework plugin found in agentuity.config.ts plugins, adding React automatically for dev server'
|
|
143
|
+
);
|
|
144
|
+
const projectRequire = createRequire(join(rootDir, 'package.json'));
|
|
145
|
+
let reactPluginPath = '@vitejs/plugin-react';
|
|
146
|
+
try {
|
|
147
|
+
reactPluginPath = projectRequire.resolve('@vitejs/plugin-react');
|
|
148
|
+
} catch {
|
|
149
|
+
// Project doesn't have @vitejs/plugin-react, use CLI's bundled version
|
|
150
|
+
}
|
|
151
|
+
const reactModule = await import(reactPluginPath);
|
|
152
|
+
resolvedUserPlugins.unshift(reactModule.default());
|
|
153
|
+
}
|
|
154
|
+
|
|
144
155
|
return [
|
|
145
|
-
// User-defined plugins from agentuity.config.ts (
|
|
146
|
-
...
|
|
147
|
-
// React plugin for JSX/TSX transformation and Fast Refresh
|
|
148
|
-
reactPlugin,
|
|
156
|
+
// User-defined plugins from agentuity.config.ts (framework plugin + extras)
|
|
157
|
+
...resolvedUserPlugins,
|
|
149
158
|
// Browser env plugin to map process.env to import.meta.env
|
|
150
159
|
browserEnvPlugin(),
|
|
151
160
|
// Warn about incorrect public asset paths in dev mode
|
|
@@ -61,6 +61,8 @@ export interface ViteBuildOptions {
|
|
|
61
61
|
analyticsEnabled?: boolean;
|
|
62
62
|
logger: Logger;
|
|
63
63
|
deploymentOptions?: DeployOptions;
|
|
64
|
+
/** Deployment config from agentuity.json (resources, mode, dependencies, domains) */
|
|
65
|
+
deploymentConfig?: Record<string, unknown>;
|
|
64
66
|
/** Optional collector for structured error reporting */
|
|
65
67
|
collector?: BuildReportCollector;
|
|
66
68
|
/** Optional config profile name (e.g., 'staging', 'test') for .env.{profile} files */
|
|
@@ -180,8 +182,24 @@ export async function runViteBuild(options: ViteBuildOptions): Promise<void> {
|
|
|
180
182
|
|
|
181
183
|
// Load custom user plugins from agentuity.config.ts if it exists
|
|
182
184
|
const clientOutDir = join(rootDir, '.agentuity/client');
|
|
185
|
+
const { loadAgentuityConfig, hasFrameworkPlugin } = await import('./config-loader');
|
|
186
|
+
const userConfig = await loadAgentuityConfig(rootDir, logger);
|
|
187
|
+
const userPlugins = userConfig?.plugins || [];
|
|
188
|
+
|
|
189
|
+
// Auto-add React plugin if no framework plugin is present (backwards compatibility)
|
|
190
|
+
if (userPlugins.length === 0 || !hasFrameworkPlugin(userPlugins)) {
|
|
191
|
+
logger.debug(
|
|
192
|
+
'No framework plugin found in agentuity.config.ts plugins, adding React automatically'
|
|
193
|
+
);
|
|
194
|
+
userPlugins.unshift(react());
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
if (userPlugins.length > 0) {
|
|
198
|
+
logger.debug('Loaded %d custom plugin(s) from agentuity.config.ts', userPlugins.length);
|
|
199
|
+
}
|
|
200
|
+
|
|
183
201
|
const plugins = [
|
|
184
|
-
|
|
202
|
+
...userPlugins,
|
|
185
203
|
browserEnvPlugin(),
|
|
186
204
|
// Fix incorrect public asset paths and rewrite to CDN URLs
|
|
187
205
|
publicAssetPathPlugin({ cdnBaseUrl }),
|
|
@@ -189,13 +207,6 @@ export async function runViteBuild(options: ViteBuildOptions): Promise<void> {
|
|
|
189
207
|
// Emit analytics beacon as hashed CDN asset (prod builds only)
|
|
190
208
|
beaconPlugin({ enabled: analyticsEnabled && !dev }),
|
|
191
209
|
];
|
|
192
|
-
const { loadAgentuityConfig } = await import('./config-loader');
|
|
193
|
-
const userConfig = await loadAgentuityConfig(rootDir, logger);
|
|
194
|
-
const userPlugins = userConfig?.plugins || [];
|
|
195
|
-
plugins.push(...userPlugins);
|
|
196
|
-
if (userPlugins.length > 0) {
|
|
197
|
-
logger.debug('Loaded %d custom plugin(s) from agentuity.config.ts', userPlugins.length);
|
|
198
|
-
}
|
|
199
210
|
|
|
200
211
|
// Merge custom define values from user config
|
|
201
212
|
const userDefine = userConfig?.define || {};
|
|
@@ -412,6 +423,7 @@ export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Pro
|
|
|
412
423
|
logger,
|
|
413
424
|
dev,
|
|
414
425
|
deploymentOptions: options.deploymentOptions,
|
|
426
|
+
deploymentConfig: options.deploymentConfig,
|
|
415
427
|
});
|
|
416
428
|
|
|
417
429
|
writeMetadataFile(rootDir, metadata, dev, logger);
|
|
@@ -27,6 +27,8 @@ export interface ViteBundleOptions {
|
|
|
27
27
|
port?: number;
|
|
28
28
|
logger: Logger;
|
|
29
29
|
deploymentOptions?: DeployOptions;
|
|
30
|
+
/** Deployment config from agentuity.json (resources, mode, dependencies, domains) */
|
|
31
|
+
deploymentConfig?: Record<string, unknown>;
|
|
30
32
|
/** Optional collector for structured error reporting */
|
|
31
33
|
collector?: BuildReportCollector;
|
|
32
34
|
}
|
|
@@ -44,6 +46,7 @@ export async function viteBundle(options: ViteBundleOptions): Promise<{ output:
|
|
|
44
46
|
port = 3500,
|
|
45
47
|
logger,
|
|
46
48
|
deploymentOptions,
|
|
49
|
+
deploymentConfig,
|
|
47
50
|
collector,
|
|
48
51
|
} = options;
|
|
49
52
|
|
|
@@ -100,6 +103,7 @@ export async function viteBundle(options: ViteBundleOptions): Promise<{ output:
|
|
|
100
103
|
deploymentId,
|
|
101
104
|
logger,
|
|
102
105
|
deploymentOptions,
|
|
106
|
+
deploymentConfig,
|
|
103
107
|
collector,
|
|
104
108
|
});
|
|
105
109
|
|
package/src/cmd/cloud/db/list.ts
CHANGED
|
@@ -46,6 +46,14 @@ export const listSubcommand = createSubcommand({
|
|
|
46
46
|
'Show credentials in plain text (default: masked in terminal, unmasked in JSON)'
|
|
47
47
|
),
|
|
48
48
|
nameOnly: z.boolean().optional().describe('Print the name only'),
|
|
49
|
+
sort: z
|
|
50
|
+
.enum(['name', 'created'])
|
|
51
|
+
.optional()
|
|
52
|
+
.describe('field to sort by (default: created)'),
|
|
53
|
+
direction: z
|
|
54
|
+
.enum(['asc', 'desc'])
|
|
55
|
+
.optional()
|
|
56
|
+
.describe('sort direction (default: desc)'),
|
|
49
57
|
}),
|
|
50
58
|
response: DBListResponseSchema,
|
|
51
59
|
},
|
|
@@ -60,7 +68,12 @@ export const listSubcommand = createSubcommand({
|
|
|
60
68
|
message: 'Fetching databases',
|
|
61
69
|
clearOnSuccess: true,
|
|
62
70
|
callback: async () => {
|
|
63
|
-
return listOrgResources(catalystClient, {
|
|
71
|
+
return listOrgResources(catalystClient, {
|
|
72
|
+
type: 'db',
|
|
73
|
+
orgId: opts?.orgId,
|
|
74
|
+
sort: opts?.sort,
|
|
75
|
+
direction: opts?.direction,
|
|
76
|
+
});
|
|
64
77
|
},
|
|
65
78
|
});
|
|
66
79
|
|
package/src/cmd/cloud/deploy.ts
CHANGED
|
@@ -22,6 +22,7 @@ import {
|
|
|
22
22
|
stepSkipped,
|
|
23
23
|
stepError,
|
|
24
24
|
pauseStepUI,
|
|
25
|
+
StepInterruptError,
|
|
25
26
|
type Step,
|
|
26
27
|
type StepContext,
|
|
27
28
|
} from '../../steps';
|
|
@@ -428,6 +429,13 @@ export const deploySubcommand = createSubcommand({
|
|
|
428
429
|
}
|
|
429
430
|
}
|
|
430
431
|
|
|
432
|
+
// Create a unified abort controller for the entire deploy flow
|
|
433
|
+
const deployAbortController = new AbortController();
|
|
434
|
+
const deployAbortHandler = () => {
|
|
435
|
+
deployAbortController.abort();
|
|
436
|
+
};
|
|
437
|
+
process.on('SIGINT', deployAbortHandler);
|
|
438
|
+
|
|
431
439
|
// Start malware check async (runs in parallel with build)
|
|
432
440
|
if (deployment) {
|
|
433
441
|
malwareCheckPromise = (async () => {
|
|
@@ -444,7 +452,8 @@ export const deploySubcommand = createSubcommand({
|
|
|
444
452
|
const result = await projectDeploymentMalwareCheck(
|
|
445
453
|
catalystClient,
|
|
446
454
|
deployment!.id,
|
|
447
|
-
packages
|
|
455
|
+
packages,
|
|
456
|
+
deployAbortController.signal
|
|
448
457
|
);
|
|
449
458
|
logger.debug(
|
|
450
459
|
'Malware check complete: action=%s, flagged=%d',
|
|
@@ -599,7 +608,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
599
608
|
|
|
600
609
|
{
|
|
601
610
|
label: 'Build, Verify and Package',
|
|
602
|
-
run: async () => {
|
|
611
|
+
run: async (stepCtx: StepContext) => {
|
|
603
612
|
if (!deployment) {
|
|
604
613
|
return stepError('deployment was null');
|
|
605
614
|
}
|
|
@@ -636,6 +645,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
636
645
|
region: project.region,
|
|
637
646
|
logger: ctx.logger,
|
|
638
647
|
deploymentOptions: opts,
|
|
648
|
+
deploymentConfig: project.deployment,
|
|
639
649
|
collector,
|
|
640
650
|
});
|
|
641
651
|
capturedOutput = [...capturedOutput, ...bundleResult.output];
|
|
@@ -643,7 +653,8 @@ export const deploySubcommand = createSubcommand({
|
|
|
643
653
|
instructions = await projectDeploymentUpdate(
|
|
644
654
|
apiClient,
|
|
645
655
|
deployment.id,
|
|
646
|
-
build
|
|
656
|
+
build,
|
|
657
|
+
stepCtx.signal
|
|
647
658
|
);
|
|
648
659
|
return stepSuccess(capturedOutput.length > 0 ? capturedOutput : undefined);
|
|
649
660
|
} catch (ex) {
|
|
@@ -789,6 +800,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
789
800
|
'Content-Type': 'application/zip',
|
|
790
801
|
},
|
|
791
802
|
body: zipfile,
|
|
803
|
+
signal: stepCtx.signal,
|
|
792
804
|
});
|
|
793
805
|
ctx.logger.trace(`Upload response: ${resp.status}`);
|
|
794
806
|
if (!resp.ok) {
|
|
@@ -876,6 +888,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
876
888
|
duplex: 'half',
|
|
877
889
|
headers,
|
|
878
890
|
body,
|
|
891
|
+
signal: stepCtx.signal,
|
|
879
892
|
})
|
|
880
893
|
);
|
|
881
894
|
}
|
|
@@ -910,11 +923,15 @@ export const deploySubcommand = createSubcommand({
|
|
|
910
923
|
},
|
|
911
924
|
{
|
|
912
925
|
label: 'Provision Deployment',
|
|
913
|
-
run: async () => {
|
|
926
|
+
run: async (stepCtx: StepContext) => {
|
|
914
927
|
if (!deployment) {
|
|
915
928
|
return stepError('deployment was null');
|
|
916
929
|
}
|
|
917
|
-
complete = await projectDeploymentComplete(
|
|
930
|
+
complete = await projectDeploymentComplete(
|
|
931
|
+
apiClient,
|
|
932
|
+
deployment.id,
|
|
933
|
+
stepCtx.signal
|
|
934
|
+
);
|
|
918
935
|
return stepSuccess();
|
|
919
936
|
},
|
|
920
937
|
},
|
|
@@ -945,12 +962,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
945
962
|
const maxAttempts = 600;
|
|
946
963
|
let attempts = 0;
|
|
947
964
|
|
|
948
|
-
//
|
|
949
|
-
const pollAbortController = new AbortController();
|
|
950
|
-
const sigintHandler = () => {
|
|
951
|
-
pollAbortController.abort();
|
|
952
|
-
};
|
|
953
|
-
process.on('SIGINT', sigintHandler);
|
|
965
|
+
// Reuse the deploy abort controller for polling (already aborted on Ctrl+C)
|
|
954
966
|
|
|
955
967
|
try {
|
|
956
968
|
if (streamId) {
|
|
@@ -1014,7 +1026,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
1014
1026
|
// Poll for deployment status
|
|
1015
1027
|
while (attempts < maxAttempts) {
|
|
1016
1028
|
// Check if user pressed Ctrl+C
|
|
1017
|
-
if (
|
|
1029
|
+
if (deployAbortController.signal.aborted) {
|
|
1018
1030
|
logStreamController.abort();
|
|
1019
1031
|
throw new DeploymentCancelledError();
|
|
1020
1032
|
}
|
|
@@ -1023,7 +1035,8 @@ export const deploySubcommand = createSubcommand({
|
|
|
1023
1035
|
try {
|
|
1024
1036
|
statusResult = await projectDeploymentStatus(
|
|
1025
1037
|
apiClient,
|
|
1026
|
-
deployment?.id ?? ''
|
|
1038
|
+
deployment?.id ?? '',
|
|
1039
|
+
deployAbortController.signal
|
|
1027
1040
|
);
|
|
1028
1041
|
|
|
1029
1042
|
logger.trace('status result: %s', statusResult);
|
|
@@ -1115,14 +1128,15 @@ export const deploySubcommand = createSubcommand({
|
|
|
1115
1128
|
callback: async () => {
|
|
1116
1129
|
while (attempts < maxAttempts) {
|
|
1117
1130
|
// Check if user pressed Ctrl+C
|
|
1118
|
-
if (
|
|
1131
|
+
if (deployAbortController.signal.aborted) {
|
|
1119
1132
|
throw new DeploymentCancelledError();
|
|
1120
1133
|
}
|
|
1121
1134
|
|
|
1122
1135
|
attempts++;
|
|
1123
1136
|
statusResult = await projectDeploymentStatus(
|
|
1124
1137
|
apiClient,
|
|
1125
|
-
deployment?.id ?? ''
|
|
1138
|
+
deployment?.id ?? '',
|
|
1139
|
+
deployAbortController.signal
|
|
1126
1140
|
);
|
|
1127
1141
|
|
|
1128
1142
|
if (statusResult.state === 'completed') {
|
|
@@ -1172,7 +1186,7 @@ export const deploySubcommand = createSubcommand({
|
|
|
1172
1186
|
tui.fatal('Deployment failed', ErrorCode.BUILD_FAILED);
|
|
1173
1187
|
} finally {
|
|
1174
1188
|
// Clean up signal handler
|
|
1175
|
-
process.off('SIGINT',
|
|
1189
|
+
process.off('SIGINT', deployAbortHandler);
|
|
1176
1190
|
}
|
|
1177
1191
|
|
|
1178
1192
|
// Show deployment URLs
|
|
@@ -1185,15 +1199,18 @@ export const deploySubcommand = createSubcommand({
|
|
|
1185
1199
|
);
|
|
1186
1200
|
}
|
|
1187
1201
|
} else {
|
|
1202
|
+
// Prefer vanity URLs, fall back to hash-based
|
|
1203
|
+
const deploymentUrl =
|
|
1204
|
+
complete.publicUrls.vanityDeployment ?? complete.publicUrls.deployment;
|
|
1205
|
+
const latestUrl = complete.publicUrls.vanityProject ?? complete.publicUrls.latest;
|
|
1188
1206
|
lines.push(
|
|
1189
1207
|
`${tui.ICONS.arrow} ${
|
|
1190
|
-
tui.bold(tui.padRight('Deployment:', 12)) +
|
|
1191
|
-
tui.link(complete.publicUrls.deployment)
|
|
1208
|
+
tui.bold(tui.padRight('Deployment:', 12)) + tui.link(deploymentUrl)
|
|
1192
1209
|
}`
|
|
1193
1210
|
);
|
|
1194
1211
|
lines.push(
|
|
1195
1212
|
`${tui.ICONS.arrow} ${
|
|
1196
|
-
tui.bold(tui.padRight('Project:', 12)) + tui.link(
|
|
1213
|
+
tui.bold(tui.padRight('Project:', 12)) + tui.link(latestUrl)
|
|
1197
1214
|
}`
|
|
1198
1215
|
);
|
|
1199
1216
|
}
|
|
@@ -1222,20 +1239,28 @@ export const deploySubcommand = createSubcommand({
|
|
|
1222
1239
|
logs,
|
|
1223
1240
|
urls: complete?.publicUrls
|
|
1224
1241
|
? {
|
|
1225
|
-
deployment:
|
|
1226
|
-
|
|
1242
|
+
deployment:
|
|
1243
|
+
complete.publicUrls.vanityDeployment ?? complete.publicUrls.deployment,
|
|
1244
|
+
latest: complete.publicUrls.vanityProject ?? complete.publicUrls.latest,
|
|
1227
1245
|
custom: complete.publicUrls.custom,
|
|
1228
1246
|
dashboard,
|
|
1229
1247
|
}
|
|
1230
1248
|
: undefined,
|
|
1231
1249
|
};
|
|
1232
1250
|
} catch (ex) {
|
|
1251
|
+
// Handle step interruption (Ctrl+C during build steps)
|
|
1252
|
+
if (ex instanceof StepInterruptError) {
|
|
1253
|
+
tui.warning('Deployment cancelled');
|
|
1254
|
+
process.exit(ex.exitCode);
|
|
1255
|
+
}
|
|
1233
1256
|
collector.addGeneralError('deploy', String(ex), 'DEPLOY004');
|
|
1234
1257
|
if (opts.reportFile) {
|
|
1235
1258
|
await collector.forceWrite();
|
|
1236
1259
|
}
|
|
1237
1260
|
clearGlobalCollector();
|
|
1238
1261
|
tui.fatal(`unexpected error trying to deploy project. ${ex}`);
|
|
1262
|
+
} finally {
|
|
1263
|
+
process.off('SIGINT', deployAbortHandler);
|
|
1239
1264
|
}
|
|
1240
1265
|
},
|
|
1241
1266
|
});
|
|
@@ -34,6 +34,14 @@ export const listSubcommand = createCommand({
|
|
|
34
34
|
orgId: z.string().optional().describe('filter by organization id'),
|
|
35
35
|
limit: z.coerce.number().optional().describe('Maximum number of queues to return'),
|
|
36
36
|
offset: z.coerce.number().optional().describe('Offset for pagination'),
|
|
37
|
+
sort: z
|
|
38
|
+
.enum(['name', 'created', 'updated'])
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('field to sort by (default: created)'),
|
|
41
|
+
direction: z
|
|
42
|
+
.enum(['asc', 'desc'])
|
|
43
|
+
.optional()
|
|
44
|
+
.describe('sort direction (default: desc)'),
|
|
37
45
|
}),
|
|
38
46
|
response: QueueListResponseSchema,
|
|
39
47
|
},
|
|
@@ -48,6 +56,8 @@ export const listSubcommand = createCommand({
|
|
|
48
56
|
{
|
|
49
57
|
limit: opts.limit,
|
|
50
58
|
offset: opts.offset,
|
|
59
|
+
sort: opts.sort,
|
|
60
|
+
direction: opts.direction,
|
|
51
61
|
},
|
|
52
62
|
queueOptions
|
|
53
63
|
);
|
|
@@ -75,6 +75,14 @@ export const listSubcommand = createCommand({
|
|
|
75
75
|
all: z.boolean().optional().describe('List all sandboxes regardless of project context'),
|
|
76
76
|
limit: z.number().optional().describe('Maximum number of results (default: 50, max: 100)'),
|
|
77
77
|
offset: z.number().optional().describe('Pagination offset'),
|
|
78
|
+
sort: z
|
|
79
|
+
.enum(['name', 'created', 'updated', 'status'])
|
|
80
|
+
.optional()
|
|
81
|
+
.describe('field to sort by (default: created)'),
|
|
82
|
+
direction: z
|
|
83
|
+
.enum(['asc', 'desc'])
|
|
84
|
+
.optional()
|
|
85
|
+
.describe('sort direction (default: desc)'),
|
|
78
86
|
}),
|
|
79
87
|
response: SandboxListResponseSchema,
|
|
80
88
|
},
|
|
@@ -94,6 +102,8 @@ export const listSubcommand = createCommand({
|
|
|
94
102
|
status: opts.status,
|
|
95
103
|
limit: opts.limit,
|
|
96
104
|
offset: opts.offset,
|
|
105
|
+
sort: opts.sort,
|
|
106
|
+
direction: opts.direction,
|
|
97
107
|
});
|
|
98
108
|
|
|
99
109
|
// Check if results span multiple orgs
|
|
@@ -34,6 +34,14 @@ export const listSubcommand = createCommand({
|
|
|
34
34
|
limit: z.number().optional().describe('Maximum number of results'),
|
|
35
35
|
offset: z.number().optional().describe('Offset for pagination'),
|
|
36
36
|
orgId: z.string().optional().describe('filter by organization id'),
|
|
37
|
+
sort: z
|
|
38
|
+
.enum(['name', 'created'])
|
|
39
|
+
.optional()
|
|
40
|
+
.describe('field to sort by (default: created)'),
|
|
41
|
+
direction: z
|
|
42
|
+
.enum(['asc', 'desc'])
|
|
43
|
+
.optional()
|
|
44
|
+
.describe('sort direction (default: desc)'),
|
|
37
45
|
}),
|
|
38
46
|
response: RuntimeListResponseSchema,
|
|
39
47
|
},
|
|
@@ -47,6 +55,8 @@ export const listSubcommand = createCommand({
|
|
|
47
55
|
orgId: effectiveOrgId,
|
|
48
56
|
limit: opts.limit,
|
|
49
57
|
offset: opts.offset,
|
|
58
|
+
sort: opts.sort,
|
|
59
|
+
direction: opts.direction,
|
|
50
60
|
});
|
|
51
61
|
|
|
52
62
|
if (!options.json) {
|
|
@@ -47,6 +47,14 @@ export const listSubcommand = createCommand({
|
|
|
47
47
|
limit: z.number().optional().describe('Maximum number of results'),
|
|
48
48
|
offset: z.number().optional().describe('Offset for pagination'),
|
|
49
49
|
orgId: z.string().optional().describe('filter by organization id'),
|
|
50
|
+
sort: z
|
|
51
|
+
.enum(['name', 'created', 'size'])
|
|
52
|
+
.optional()
|
|
53
|
+
.describe('field to sort by (default: created)'),
|
|
54
|
+
direction: z
|
|
55
|
+
.enum(['asc', 'desc'])
|
|
56
|
+
.optional()
|
|
57
|
+
.describe('sort direction (default: desc)'),
|
|
50
58
|
}),
|
|
51
59
|
response: SnapshotListResponseSchema,
|
|
52
60
|
},
|
|
@@ -61,6 +69,8 @@ export const listSubcommand = createCommand({
|
|
|
61
69
|
limit: opts.limit,
|
|
62
70
|
offset: opts.offset,
|
|
63
71
|
orgId: effectiveOrgId,
|
|
72
|
+
sort: opts.sort,
|
|
73
|
+
direction: opts.direction,
|
|
64
74
|
});
|
|
65
75
|
|
|
66
76
|
if (!options.json) {
|
|
@@ -46,10 +46,10 @@ const SessionGetResponseSchema = z.object({
|
|
|
46
46
|
pending: z.boolean().describe('Pending'),
|
|
47
47
|
success: z.boolean().describe('Success'),
|
|
48
48
|
error: z.string().nullable().describe('Error message'),
|
|
49
|
-
method: z.string().describe('HTTP method'),
|
|
50
|
-
url: z.string().describe('Request URL'),
|
|
51
|
-
route_id: z.string().describe('Route ID'),
|
|
52
|
-
thread_id: z.string().describe('Thread ID'),
|
|
49
|
+
method: z.string().nullable().describe('HTTP method'),
|
|
50
|
+
url: z.string().nullable().describe('Request URL'),
|
|
51
|
+
route_id: z.string().nullable().describe('Route ID'),
|
|
52
|
+
thread_id: z.string().nullable().describe('Thread ID'),
|
|
53
53
|
agents: z
|
|
54
54
|
.array(
|
|
55
55
|
z.object({
|
|
@@ -148,10 +148,10 @@ export const getSubcommand = createSubcommand({
|
|
|
148
148
|
pending: session.pending,
|
|
149
149
|
success: session.success,
|
|
150
150
|
error: session.error,
|
|
151
|
-
method: session.method,
|
|
152
|
-
url: session.url,
|
|
153
|
-
route_id: session.route_id,
|
|
154
|
-
thread_id: session.thread_id,
|
|
151
|
+
method: session.method ?? null,
|
|
152
|
+
url: session.url ?? null,
|
|
153
|
+
route_id: session.route_id ?? null,
|
|
154
|
+
thread_id: session.thread_id ?? null,
|
|
155
155
|
agents: enriched.agents,
|
|
156
156
|
eval_runs: enriched.evalRuns.map((run: EvalRun) => ({
|
|
157
157
|
id: run.id,
|
|
@@ -183,8 +183,8 @@ export const getSubcommand = createSubcommand({
|
|
|
183
183
|
if (session.duration != null && session.end_time != null) {
|
|
184
184
|
tableData['Duration'] = `${(session.duration / 1_000_000).toFixed(0)}ms`;
|
|
185
185
|
}
|
|
186
|
-
tableData['Method'] = session.method;
|
|
187
|
-
tableData['URL'] = tui.link(session.url, session.url);
|
|
186
|
+
tableData['Method'] = session.method ?? '-';
|
|
187
|
+
tableData['URL'] = session.url ? tui.link(session.url, session.url) : '-';
|
|
188
188
|
tableData['Trigger'] = session.trigger;
|
|
189
189
|
if (session.env !== 'production') {
|
|
190
190
|
tableData['Environment'] = session.env;
|
|
@@ -204,9 +204,9 @@ export const getSubcommand = createSubcommand({
|
|
|
204
204
|
tableData['Route'] =
|
|
205
205
|
`${enriched.route.method.toUpperCase()} ${enriched.route.path} ${tui.muted(`(${enriched.route.id})`)}`;
|
|
206
206
|
} else {
|
|
207
|
-
tableData['Route ID'] = session.route_id;
|
|
207
|
+
tableData['Route ID'] = session.route_id ?? '-';
|
|
208
208
|
}
|
|
209
|
-
tableData['Thread ID'] = session.thread_id;
|
|
209
|
+
tableData['Thread ID'] = session.thread_id ?? '-';
|
|
210
210
|
|
|
211
211
|
tui.table([tableData], Object.keys(tableData), { layout: 'vertical', padStart: ' ' });
|
|
212
212
|
|