@agentuity/cli 0.0.99 → 0.0.101
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/AGENTS.md +1 -1
- package/dist/api.d.ts +1 -0
- package/dist/api.d.ts.map +1 -1
- package/dist/api.js +1 -1
- package/dist/api.js.map +1 -1
- package/dist/auth.d.ts.map +1 -1
- package/dist/auth.js +5 -0
- package/dist/auth.js.map +1 -1
- package/dist/cmd/build/ast.d.ts +2 -1
- package/dist/cmd/build/ast.d.ts.map +1 -1
- package/dist/cmd/build/ast.js +135 -47
- 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 +220 -188
- package/dist/cmd/build/entry-generator.js.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.js +103 -45
- package/dist/cmd/build/vite/agent-discovery.js.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/build/vite/docs-generator.d.ts +13 -0
- package/dist/cmd/build/vite/docs-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/docs-generator.js +81 -0
- package/dist/cmd/build/vite/docs-generator.js.map +1 -0
- package/dist/cmd/build/vite/index.d.ts +3 -4
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +9 -8
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/lifecycle-generator.d.ts +1 -1
- package/dist/cmd/build/vite/lifecycle-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/lifecycle-generator.js +19 -5
- package/dist/cmd/build/vite/lifecycle-generator.js.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +145 -0
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/registry-generator.d.ts +3 -3
- package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/registry-generator.js +627 -103
- package/dist/cmd/build/vite/registry-generator.js.map +1 -1
- package/dist/cmd/build/vite/route-discovery.d.ts +4 -0
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/route-discovery.js.map +1 -1
- package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -1
- package/dist/cmd/build/vite/server-bundler.js +48 -1
- package/dist/cmd/build/vite/server-bundler.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +30 -21
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite-bundler.js +6 -6
- package/dist/cmd/build/vite-bundler.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +11 -5
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/dev/file-watcher.d.ts.map +1 -1
- package/dist/cmd/dev/file-watcher.js +33 -1
- package/dist/cmd/dev/file-watcher.js.map +1 -1
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +102 -21
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/dev/sync.d.ts.map +1 -1
- package/dist/cmd/dev/sync.js +19 -3
- package/dist/cmd/dev/sync.js.map +1 -1
- package/dist/cmd/project/create.d.ts.map +1 -1
- package/dist/cmd/project/create.js +8 -2
- package/dist/cmd/project/create.js.map +1 -1
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +8 -0
- package/dist/config.js.map +1 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/index.js.map +1 -1
- package/package.json +5 -8
- package/src/api.ts +1 -1
- package/src/auth.ts +6 -0
- package/src/cmd/build/ast.ts +161 -48
- package/src/cmd/build/entry-generator.ts +225 -190
- package/src/cmd/build/vite/agent-discovery.ts +151 -58
- package/src/cmd/build/vite/bun-dev-server.ts +1 -1
- package/src/cmd/build/vite/docs-generator.ts +87 -0
- package/src/cmd/build/vite/index.ts +9 -8
- package/src/cmd/build/vite/lifecycle-generator.ts +19 -5
- package/src/cmd/build/vite/metadata-generator.ts +178 -0
- package/src/cmd/build/vite/registry-generator.ts +727 -108
- package/src/cmd/build/vite/route-discovery.ts +4 -0
- package/src/cmd/build/vite/server-bundler.ts +56 -1
- package/src/cmd/build/vite/vite-builder.ts +46 -33
- package/src/cmd/build/vite-bundler.ts +6 -6
- package/src/cmd/cloud/deploy.ts +15 -5
- package/src/cmd/dev/file-watcher.ts +37 -1
- package/src/cmd/dev/index.ts +141 -30
- package/src/cmd/dev/sync.ts +41 -6
- package/src/cmd/project/create.ts +13 -3
- package/src/config.ts +9 -0
- package/src/index.ts +0 -5
- package/src/runtime-bootstrap.md +1 -1
- package/dist/cmd/build/vite/patch-plugin.d.ts +0 -21
- package/dist/cmd/build/vite/patch-plugin.d.ts.map +0 -1
- package/dist/cmd/build/vite/patch-plugin.js +0 -70
- package/dist/cmd/build/vite/patch-plugin.js.map +0 -1
- package/dist/runtime-bootstrap.d.ts +0 -56
- package/dist/runtime-bootstrap.d.ts.map +0 -1
- package/dist/runtime-bootstrap.js +0 -95
- package/dist/runtime-bootstrap.js.map +0 -1
- package/src/cmd/build/vite/patch-plugin.ts +0 -88
- package/src/runtime-bootstrap.ts +0 -131
|
@@ -9,11 +9,10 @@ import { discoverRoutes } from './vite/route-discovery';
|
|
|
9
9
|
*/
|
|
10
10
|
export async function generateEntryFile(options) {
|
|
11
11
|
const { rootDir, projectId, deploymentId, logger, mode, workbench, vitePort } = options;
|
|
12
|
-
const isDev = mode === 'dev';
|
|
13
12
|
const srcDir = join(rootDir, 'src');
|
|
14
|
-
const
|
|
15
|
-
const entryPath = join(
|
|
16
|
-
logger.trace(`Generating
|
|
13
|
+
const generatedDir = join(srcDir, 'generated');
|
|
14
|
+
const entryPath = join(generatedDir, 'app.ts');
|
|
15
|
+
logger.trace(`Generating unified entry file (supports both dev and prod modes)...`);
|
|
17
16
|
// Discover routes to determine which files need to be imported
|
|
18
17
|
const { routeInfoList } = await discoverRoutes(srcDir, projectId, deploymentId, logger);
|
|
19
18
|
// Check for web and workbench
|
|
@@ -55,11 +54,13 @@ export async function generateEntryFile(options) {
|
|
|
55
54
|
...runtimeImports,
|
|
56
55
|
`} from '@agentuity/runtime';`,
|
|
57
56
|
`import type { Context } from 'hono';`,
|
|
58
|
-
`import { websocket } from 'hono/bun';`,
|
|
59
|
-
|
|
57
|
+
`import { websocket } from 'hono/bun';`,
|
|
58
|
+
// Conditionally import serveStatic and readFileSync for web frontend or workbench support
|
|
59
|
+
hasWebFrontend || hasWorkbench ? `import { serveStatic } from 'hono/bun';` : '',
|
|
60
|
+
hasWebFrontend || hasWorkbench ? `import { readFileSync, existsSync } from 'node:fs';` : '',
|
|
60
61
|
].filter(Boolean);
|
|
61
62
|
imports.push(`import { type LogLevel } from '@agentuity/core';`);
|
|
62
|
-
imports.push(`import { bootstrapRuntimeEnv } from '@agentuity/
|
|
63
|
+
imports.push(`import { bootstrapRuntimeEnv } from '@agentuity/runtime';`);
|
|
63
64
|
// Generate route mounting code for all discovered routes
|
|
64
65
|
const routeImportsAndMounts = [];
|
|
65
66
|
let routeIndex = 0;
|
|
@@ -79,7 +80,7 @@ export async function generateEntryFile(options) {
|
|
|
79
80
|
}
|
|
80
81
|
}
|
|
81
82
|
const importName = `router_${routeIndex++}`;
|
|
82
|
-
routeImportsAndMounts.push(`const { default: ${importName} } = await import('../
|
|
83
|
+
routeImportsAndMounts.push(`const { default: ${importName} } = await import('../api/${relativePath}.js');`);
|
|
83
84
|
routeImportsAndMounts.push(`app.route('${mountPath}', ${importName});`);
|
|
84
85
|
}
|
|
85
86
|
const apiMount = routeImportsAndMounts.length > 0
|
|
@@ -96,182 +97,195 @@ const workbenchRouter = createWorkbenchRouter();
|
|
|
96
97
|
app.route('/', workbenchRouter);
|
|
97
98
|
`
|
|
98
99
|
: '';
|
|
99
|
-
// Asset proxy routes
|
|
100
|
-
const assetProxyRoutes =
|
|
100
|
+
// Asset proxy routes - only generated in dev mode when vitePort is available
|
|
101
|
+
const assetProxyRoutes = vitePort
|
|
101
102
|
? `
|
|
102
|
-
// Asset proxy routes -
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
103
|
+
// Asset proxy routes - Development mode only (proxies to Vite asset server)
|
|
104
|
+
if (process.env.NODE_ENV !== 'production') {
|
|
105
|
+
const VITE_ASSET_PORT = parseInt(process.env.VITE_PORT || '${vitePort}', 10);
|
|
106
|
+
|
|
107
|
+
const proxyToVite = async (c: Context) => {
|
|
108
|
+
const viteUrl = \`http://127.0.0.1:\${VITE_ASSET_PORT}\${c.req.path}\`;
|
|
109
|
+
const controller = new AbortController();
|
|
110
|
+
const timeout = setTimeout(() => controller.abort(), 10000); // 10s timeout
|
|
111
|
+
try {
|
|
112
|
+
otel.logger.debug(\`[Proxy] \${c.req.method} \${c.req.path} -> Vite:\${VITE_ASSET_PORT}\`);
|
|
113
|
+
const res = await fetch(viteUrl, { signal: controller.signal });
|
|
114
|
+
clearTimeout(timeout);
|
|
115
|
+
otel.logger.debug(\`[Proxy] \${c.req.path} -> \${res.status} (\${res.headers.get('content-type')})\`);
|
|
116
|
+
return new Response(res.body, {
|
|
117
|
+
status: res.status,
|
|
118
|
+
headers: res.headers,
|
|
119
|
+
});
|
|
120
|
+
} catch (err) {
|
|
121
|
+
clearTimeout(timeout);
|
|
122
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
123
|
+
otel.logger.error(\`Vite proxy timeout: \${c.req.path}\`);
|
|
124
|
+
return c.text('Vite asset server timeout', 504);
|
|
125
|
+
}
|
|
126
|
+
otel.logger.error(\`Failed to proxy to Vite: \${c.req.path} - \${err instanceof Error ? err.message : String(err)}\`);
|
|
127
|
+
return c.text('Vite asset server error', 500);
|
|
123
128
|
}
|
|
124
|
-
|
|
125
|
-
return c.text('Vite asset server error', 500);
|
|
126
|
-
}
|
|
127
|
-
};
|
|
129
|
+
};
|
|
128
130
|
|
|
129
|
-
// Vite client scripts and HMR
|
|
130
|
-
app.get('/@vite/*', proxyToVite);
|
|
131
|
-
app.get('/@react-refresh', proxyToVite);
|
|
131
|
+
// Vite client scripts and HMR
|
|
132
|
+
app.get('/@vite/*', proxyToVite);
|
|
133
|
+
app.get('/@react-refresh', proxyToVite);
|
|
132
134
|
|
|
133
|
-
// Source files for HMR
|
|
134
|
-
app.get('/src/web/*', proxyToVite);
|
|
135
|
-
app.get('/src/*', proxyToVite); // Catch-all for other source files
|
|
135
|
+
// Source files for HMR
|
|
136
|
+
app.get('/src/web/*', proxyToVite);
|
|
137
|
+
app.get('/src/*', proxyToVite); // Catch-all for other source files
|
|
136
138
|
|
|
137
|
-
// Workbench source files (in .agentuity/workbench-src/)
|
|
138
|
-
app.get('/.agentuity/workbench-src/*', proxyToVite);
|
|
139
|
+
// Workbench source files (in .agentuity/workbench-src/)
|
|
140
|
+
app.get('/.agentuity/workbench-src/*', proxyToVite);
|
|
139
141
|
|
|
140
|
-
// Node modules (Vite transforms these)
|
|
141
|
-
app.get('/node_modules/*', proxyToVite);
|
|
142
|
+
// Node modules (Vite transforms these)
|
|
143
|
+
app.get('/node_modules/*', proxyToVite);
|
|
142
144
|
|
|
143
|
-
// Scoped packages (e.g., @agentuity/*, @types/*)
|
|
144
|
-
app.get('/@*', proxyToVite);
|
|
145
|
+
// Scoped packages (e.g., @agentuity/*, @types/*)
|
|
146
|
+
app.get('/@*', proxyToVite);
|
|
145
147
|
|
|
146
|
-
// File system access (for Vite's @fs protocol)
|
|
147
|
-
app.get('/@fs/*', proxyToVite);
|
|
148
|
+
// File system access (for Vite's @fs protocol)
|
|
149
|
+
app.get('/@fs/*', proxyToVite);
|
|
148
150
|
|
|
149
|
-
// Module resolution (for Vite's @id protocol)
|
|
150
|
-
app.get('/@id/*', proxyToVite);
|
|
151
|
+
// Module resolution (for Vite's @id protocol)
|
|
152
|
+
app.get('/@id/*', proxyToVite);
|
|
151
153
|
|
|
152
|
-
// Any .js, .jsx, .ts, .tsx files (catch remaining modules)
|
|
153
|
-
app.get('/*.js', proxyToVite);
|
|
154
|
-
app.get('/*.jsx', proxyToVite);
|
|
155
|
-
app.get('/*.ts', proxyToVite);
|
|
156
|
-
app.get('/*.tsx', proxyToVite);
|
|
157
|
-
app.get('/*.css', proxyToVite);
|
|
154
|
+
// Any .js, .jsx, .ts, .tsx files (catch remaining modules)
|
|
155
|
+
app.get('/*.js', proxyToVite);
|
|
156
|
+
app.get('/*.jsx', proxyToVite);
|
|
157
|
+
app.get('/*.ts', proxyToVite);
|
|
158
|
+
app.get('/*.tsx', proxyToVite);
|
|
159
|
+
app.get('/*.css', proxyToVite);
|
|
160
|
+
}
|
|
158
161
|
`
|
|
159
162
|
: '';
|
|
160
|
-
//
|
|
163
|
+
// Runtime mode detection helper (defined at top level for reuse)
|
|
164
|
+
// Dynamic property access prevents Bun.build from inlining NODE_ENV at build time
|
|
165
|
+
const modeDetection = `
|
|
166
|
+
// Runtime mode detection helper
|
|
167
|
+
// Dynamic string concatenation prevents Bun.build from inlining NODE_ENV at build time
|
|
168
|
+
// See: https://github.com/oven-sh/bun/issues/20183
|
|
169
|
+
const getEnv = (key: string) => process.env[key];
|
|
170
|
+
const isDevelopment = () => getEnv('NODE' + '_' + 'ENV') !== 'production';
|
|
171
|
+
`;
|
|
172
|
+
// Web routes (runtime mode detection)
|
|
161
173
|
let webRoutes = '';
|
|
162
174
|
if (hasWebFrontend) {
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
// Proxy HTML from Vite to
|
|
167
|
-
const
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
.
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
app.
|
|
193
|
-
|
|
194
|
-
//
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
app.
|
|
198
|
-
|
|
199
|
-
//
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
return
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
}
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
app.use('/assets/*', serveStatic({ root: import.meta.dir + '/client' }));
|
|
218
|
-
|
|
219
|
-
// Serve static public assets (favicon.ico, robots.txt, etc. from Vite's public folder)
|
|
220
|
-
app.use('/*', serveStatic({ root: import.meta.dir + '/client', rewriteRequestPath: (path) => path }));
|
|
221
|
-
|
|
222
|
-
// 404 for unmatched API/system routes (IMPORTANT: comes before SPA fallback)
|
|
223
|
-
app.all('/_agentuity/*', (c: Context) => c.notFound());
|
|
224
|
-
app.all('/api/*', (c: Context) => c.notFound());
|
|
225
|
-
${hasWorkbench ? '' : `app.all('/workbench/*', (c: Context) => c.notFound());`}
|
|
226
|
-
|
|
227
|
-
// SPA fallback with asset protection
|
|
228
|
-
// In production, we need to distinguish between:
|
|
229
|
-
// - SPA routes like /dashboard, /users/123 (should return HTML)
|
|
230
|
-
// - Missing assets like /foo.js, /bar.css (should return 404)
|
|
231
|
-
// We check for file extensions to detect asset requests
|
|
232
|
-
app.get('*', (c: Context) => {
|
|
233
|
-
const path = c.req.path;
|
|
234
|
-
// If path has a file extension, it's likely an asset request
|
|
235
|
-
// Return 404 instead of serving HTML
|
|
236
|
-
if (/\\.[a-zA-Z0-9]+$/.test(path)) {
|
|
237
|
-
return c.notFound();
|
|
175
|
+
webRoutes = `
|
|
176
|
+
// Web routes - Runtime mode detection (dev proxies to Vite, prod serves static)
|
|
177
|
+
if (isDevelopment()) {
|
|
178
|
+
// Development mode: Proxy HTML from Vite to enable React Fast Refresh
|
|
179
|
+
const VITE_ASSET_PORT = parseInt(process.env.VITE_PORT || '${vitePort || 5173}', 10);
|
|
180
|
+
|
|
181
|
+
const devHtmlHandler = async (c: Context) => {
|
|
182
|
+
const viteUrl = \`http://127.0.0.1:\${VITE_ASSET_PORT}/src/web/index.html\`;
|
|
183
|
+
|
|
184
|
+
try {
|
|
185
|
+
otel.logger.debug('[Proxy] GET /src/web/index.html -> Vite:%d', VITE_ASSET_PORT);
|
|
186
|
+
const res = await fetch(viteUrl, { signal: AbortSignal.timeout(10000) });
|
|
187
|
+
|
|
188
|
+
// Get HTML text and transform relative paths to absolute
|
|
189
|
+
const html = await res.text();
|
|
190
|
+
const transformedHtml = html
|
|
191
|
+
.replace(/src="\\.\\//g, 'src="/src/web/')
|
|
192
|
+
.replace(/href="\\.\\//g, 'href="/src/web/');
|
|
193
|
+
|
|
194
|
+
return new Response(transformedHtml, {
|
|
195
|
+
status: res.status,
|
|
196
|
+
headers: res.headers,
|
|
197
|
+
});
|
|
198
|
+
} catch (err) {
|
|
199
|
+
otel.logger.error('Failed to proxy HTML to Vite: %s', err instanceof Error ? err.message : String(err));
|
|
200
|
+
return c.text('Vite asset server error (HTML)', 500);
|
|
201
|
+
}
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
app.get('/', devHtmlHandler);
|
|
205
|
+
|
|
206
|
+
// 404 for unmatched API/system routes
|
|
207
|
+
app.all('/_agentuity/*', (c: Context) => c.notFound());
|
|
208
|
+
app.all('/api/*', (c: Context) => c.notFound());
|
|
209
|
+
${hasWorkbench ? '' : `app.all('/workbench/*', (c: Context) => c.notFound());`}
|
|
210
|
+
|
|
211
|
+
// SPA fallback - serve index.html for client-side routing
|
|
212
|
+
app.get('*', (c: Context) => {
|
|
213
|
+
const path = c.req.path;
|
|
214
|
+
// If path has a file extension, return 404 (prevents serving HTML for missing assets)
|
|
215
|
+
if (/\\.[a-zA-Z0-9]+$/.test(path)) {
|
|
216
|
+
return c.notFound();
|
|
217
|
+
}
|
|
218
|
+
return devHtmlHandler(c);
|
|
219
|
+
});
|
|
220
|
+
} else {
|
|
221
|
+
// Production mode: Serve static files from bundled output
|
|
222
|
+
const indexHtmlPath = import.meta.dir + '/client/index.html';
|
|
223
|
+
const indexHtml = existsSync(indexHtmlPath)
|
|
224
|
+
? readFileSync(indexHtmlPath, 'utf-8')
|
|
225
|
+
: '';
|
|
226
|
+
|
|
227
|
+
if (!indexHtml) {
|
|
228
|
+
otel.logger.warn('Production HTML not found at %s', indexHtmlPath);
|
|
238
229
|
}
|
|
239
|
-
|
|
240
|
-
|
|
230
|
+
|
|
231
|
+
app.get('/', (c: Context) => indexHtml ? c.html(indexHtml) : c.text('Production build incomplete', 500));
|
|
232
|
+
|
|
233
|
+
// Serve static assets from /assets/* (Vite bundled output)
|
|
234
|
+
app.use('/assets/*', serveStatic({ root: import.meta.dir + '/client' }));
|
|
235
|
+
|
|
236
|
+
// Serve static public assets (favicon.ico, robots.txt, etc.)
|
|
237
|
+
app.use('/*', serveStatic({ root: import.meta.dir + '/client', rewriteRequestPath: (path) => path }));
|
|
238
|
+
|
|
239
|
+
// 404 for unmatched API/system routes (IMPORTANT: comes before SPA fallback)
|
|
240
|
+
app.all('/_agentuity/*', (c: Context) => c.notFound());
|
|
241
|
+
app.all('/api/*', (c: Context) => c.notFound());
|
|
242
|
+
${hasWorkbench ? '' : `app.all('/workbench/*', (c: Context) => c.notFound());`}
|
|
243
|
+
|
|
244
|
+
// SPA fallback with asset protection
|
|
245
|
+
app.get('*', (c: Context) => {
|
|
246
|
+
const path = c.req.path;
|
|
247
|
+
// If path has a file extension, it's likely an asset request - return 404
|
|
248
|
+
if (/\\.[a-zA-Z0-9]+$/.test(path)) {
|
|
249
|
+
return c.notFound();
|
|
250
|
+
}
|
|
251
|
+
return c.html(indexHtml);
|
|
252
|
+
});
|
|
253
|
+
}
|
|
241
254
|
`;
|
|
242
|
-
}
|
|
243
255
|
}
|
|
244
|
-
// Workbench routes (if enabled)
|
|
256
|
+
// Workbench routes (if enabled) - runtime mode detection
|
|
245
257
|
const workbenchRoute = workbench?.route ?? '/workbench';
|
|
246
|
-
const workbenchSrcDir = join(agentuityDir, 'workbench-src');
|
|
247
258
|
const workbenchRoutes = hasWorkbench
|
|
248
|
-
?
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
app.get('${workbenchRoute}', async (c: Context) => {
|
|
252
|
-
const html = await Bun.file('${workbenchSrcDir}/index.html').text();
|
|
253
|
-
// Rewrite script/css paths to use Vite's @fs protocol
|
|
254
|
-
const withVite = html
|
|
255
|
-
.replace('src="./main.tsx"', 'src="/@fs${workbenchSrcDir}/main.tsx"')
|
|
256
|
-
.replace('href="./styles.css"', 'href="/@fs${workbenchSrcDir}/styles.css"');
|
|
257
|
-
return c.html(withVite);
|
|
258
|
-
});
|
|
259
|
-
`
|
|
260
|
-
: `
|
|
261
|
-
// Workbench routes (production - serve pre-built assets)
|
|
262
|
-
// Use import.meta.dir for absolute paths (app.js runs from .agentuity/)
|
|
263
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
259
|
+
? `
|
|
260
|
+
// Workbench routes - Runtime mode detection
|
|
261
|
+
const workbenchSrcDir = import.meta.dir + '/workbench-src';
|
|
264
262
|
const workbenchIndexPath = import.meta.dir + '/workbench/index.html';
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
263
|
+
const workbenchIndex = existsSync(workbenchIndexPath)
|
|
264
|
+
? readFileSync(workbenchIndexPath, 'utf-8')
|
|
265
|
+
: '';
|
|
266
|
+
|
|
267
|
+
if (isDevelopment()) {
|
|
268
|
+
// Development mode: Let Vite serve source files with HMR
|
|
269
|
+
app.get('${workbenchRoute}', async (c: Context) => {
|
|
270
|
+
const html = await Bun.file(workbenchSrcDir + '/index.html').text();
|
|
271
|
+
// Rewrite script/css paths to use Vite's @fs protocol
|
|
272
|
+
const withVite = html
|
|
273
|
+
.replace('src="./main.tsx"', \`src="/@fs\${workbenchSrcDir}/main.tsx"\`)
|
|
274
|
+
.replace('href="./styles.css"', \`href="/@fs\${workbenchSrcDir}/styles.css"\`);
|
|
275
|
+
return c.html(withVite);
|
|
276
|
+
});
|
|
277
|
+
} else {
|
|
278
|
+
// Production mode: Serve pre-built assets
|
|
279
|
+
if (workbenchIndex) {
|
|
280
|
+
app.get('${workbenchRoute}', (c: Context) => c.html(workbenchIndex));
|
|
281
|
+
app.get('${workbenchRoute}/*', serveStatic({ root: import.meta.dir + '/workbench' }));
|
|
282
|
+
}
|
|
269
283
|
}
|
|
270
284
|
`
|
|
271
285
|
: '';
|
|
272
286
|
// Server startup (same for dev and prod - Bun.serve with native WebSocket)
|
|
273
287
|
const serverStartup = `
|
|
274
|
-
// Start Bun server
|
|
288
|
+
// Start Bun server
|
|
275
289
|
if (typeof Bun !== 'undefined') {
|
|
276
290
|
// Enable process exit protection now that we're starting the server
|
|
277
291
|
enableProcessExitProtection();
|
|
@@ -287,19 +301,55 @@ if (typeof Bun !== 'undefined') {
|
|
|
287
301
|
// Make server available globally for health checks
|
|
288
302
|
(globalThis as any).__AGENTUITY_SERVER__ = server;
|
|
289
303
|
|
|
290
|
-
otel.logger.info(\`Server listening on http://127.0.0.1:\${port}\`)
|
|
304
|
+
otel.logger.info(\`Server listening on http://127.0.0.1:\${port}\`);
|
|
305
|
+
if (isDevelopment() && process.env.VITE_PORT) {
|
|
306
|
+
otel.logger.debug(\`Proxying Vite assets from port \${process.env.VITE_PORT}\`);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
// FOUND AN ERROR IN THIS FILE?
|
|
311
|
+
// Please file an issue at https://github.com/agentuity/sdk/issues
|
|
312
|
+
// or if you know the fix please submit a PR!
|
|
313
|
+
`;
|
|
314
|
+
const healthRoutes = `
|
|
315
|
+
// Health check routes (production only)
|
|
316
|
+
if (!isDevelopment()) {
|
|
317
|
+
const healthHandler = (c: Context) => {
|
|
318
|
+
return c.text('OK', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
319
|
+
};
|
|
320
|
+
const idleHandler = (c: Context) => {
|
|
321
|
+
// Check if server is idle (no pending requests/connections)
|
|
322
|
+
const server = (globalThis as any).__AGENTUITY_SERVER__;
|
|
323
|
+
if (!server) return c.text('NO', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
324
|
+
|
|
325
|
+
// Check for pending background tasks
|
|
326
|
+
if (hasWaitUntilPending()) return c.text('NO', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
327
|
+
|
|
328
|
+
if (server.pendingRequests > 1) return c.text('NO', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
329
|
+
if (server.pendingWebSockets > 0) return c.text('NO', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
330
|
+
|
|
331
|
+
return c.text('OK', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
332
|
+
};
|
|
333
|
+
app.get('/_agentuity/health', healthHandler);
|
|
334
|
+
app.get('/_health', healthHandler);
|
|
335
|
+
app.get('/_agentuity/idle', idleHandler);
|
|
336
|
+
app.get('/_idle', idleHandler);
|
|
291
337
|
}
|
|
292
338
|
`;
|
|
293
|
-
const code = `//
|
|
339
|
+
const code = `// @generated
|
|
340
|
+
// Auto-generated by Agentuity
|
|
294
341
|
// DO NOT EDIT - This file is regenerated on every build
|
|
342
|
+
// Supports both development and production modes via runtime detection
|
|
295
343
|
${imports.join('\n')}
|
|
296
344
|
|
|
345
|
+
${modeDetection}
|
|
346
|
+
|
|
297
347
|
// Step 0: Bootstrap runtime environment (load profile-specific .env files)
|
|
298
348
|
// Only in development - production env vars are injected by platform
|
|
299
349
|
// This must happen BEFORE any imports that depend on environment variables
|
|
300
|
-
if (
|
|
301
|
-
// Pass project directory (
|
|
302
|
-
await bootstrapRuntimeEnv({ projectDir: import.meta.dir + '
|
|
350
|
+
if (isDevelopment()) {
|
|
351
|
+
// Pass project directory (two levels up from src/generated/) so .env files are loaded correctly
|
|
352
|
+
await bootstrapRuntimeEnv({ projectDir: import.meta.dir + '/../..' });
|
|
303
353
|
}
|
|
304
354
|
|
|
305
355
|
// Step 1: Initialize telemetry and services
|
|
@@ -338,7 +388,7 @@ app.use('/api/*', createOtelMiddleware());
|
|
|
338
388
|
app.use('/api/*', createAgentMiddleware(''));
|
|
339
389
|
|
|
340
390
|
// Step 4: Import user's app.ts (runs createApp, gets state/config)
|
|
341
|
-
await import('
|
|
391
|
+
await import('../../app.js');
|
|
342
392
|
|
|
343
393
|
// Step 5: Initialize providers
|
|
344
394
|
const threadProvider = getThreadProvider();
|
|
@@ -349,27 +399,7 @@ await sessionProvider.initialize(appState);
|
|
|
349
399
|
|
|
350
400
|
// Step 6: Mount routes (AFTER middleware is applied)
|
|
351
401
|
|
|
352
|
-
|
|
353
|
-
const healthHandler = (c: Context) => c.text('OK');
|
|
354
|
-
const idleHandler = (c: Context) => {
|
|
355
|
-
// Check if server is idle (no pending requests/connections)
|
|
356
|
-
const server = (globalThis as any).__AGENTUITY_SERVER__;
|
|
357
|
-
if (!server) return c.text('NO', { status: 200 });
|
|
358
|
-
|
|
359
|
-
// Check for pending background tasks
|
|
360
|
-
if (hasWaitUntilPending()) return c.text('NO', { status: 200 });
|
|
361
|
-
|
|
362
|
-
if (server.pendingRequests > 1) return c.text('NO', { status: 200 });
|
|
363
|
-
if (server.pendingWebSockets > 0) return c.text('NO', { status: 200 });
|
|
364
|
-
|
|
365
|
-
return c.text('OK', { status: 200 });
|
|
366
|
-
};
|
|
367
|
-
|
|
368
|
-
app.get('/_agentuity/health', healthHandler);
|
|
369
|
-
app.get('/_health', healthHandler);
|
|
370
|
-
app.get('/_agentuity/idle', idleHandler);
|
|
371
|
-
app.get('/_idle', idleHandler);
|
|
372
|
-
|
|
402
|
+
${healthRoutes}
|
|
373
403
|
${assetProxyRoutes}
|
|
374
404
|
${apiMount}
|
|
375
405
|
${workbenchApiMount}
|
|
@@ -381,7 +411,9 @@ await runAgentSetups(appState);
|
|
|
381
411
|
|
|
382
412
|
${serverStartup}
|
|
383
413
|
`;
|
|
384
|
-
|
|
385
|
-
|
|
414
|
+
// Collapse 2+ consecutive empty lines into 1 empty line (3+ \n becomes 2 \n)
|
|
415
|
+
const cleanedCode = code.replace(/\n{3,}/g, '\n\n');
|
|
416
|
+
await Bun.write(entryPath, cleanedCode);
|
|
417
|
+
logger.trace(`Generated unified entry file at %s (mode: ${mode})`, entryPath);
|
|
386
418
|
}
|
|
387
419
|
//# sourceMappingURL=entry-generator.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entry-generator.js","sourceRoot":"","sources":["../../../src/cmd/build/entry-generator.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAYxD;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,OAA6B;IACpE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"entry-generator.js","sourceRoot":"","sources":["../../../src/cmd/build/entry-generator.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-discovery.d.ts","sourceRoot":"","sources":["../../../../src/cmd/build/vite/agent-discovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AA0C7C,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CAClB;
|
|
1
|
+
{"version":3,"file":"agent-discovery.d.ts","sourceRoot":"","sources":["../../../../src/cmd/build/vite/agent-discovery.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AA0C7C,MAAM,WAAW,aAAa;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,KAAK,CAAC,EAAE,YAAY,EAAE,CAAC;CACvB;AAED,MAAM,WAAW,YAAY;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,eAAe,EAAE,MAAM,CAAC;IACxB,SAAS,EAAE,MAAM,CAAC;CAClB;AAgYD;;GAEG;AACH,wBAAsB,cAAc,CACnC,MAAM,EAAE,MAAM,EACd,SAAS,EAAE,MAAM,EACjB,YAAY,EAAE,MAAM,EACpB,MAAM,EAAE,MAAM,GACZ,OAAO,CAAC,aAAa,EAAE,CAAC,CA6F1B"}
|