@agentuity/cli 0.0.100 → 0.0.102
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +19 -188
- package/bin/cli.ts +13 -6
- 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/cli.d.ts.map +1 -1
- package/dist/cli.js +41 -12
- package/dist/cli.js.map +1 -1
- package/dist/cmd/ai/index.d.ts.map +1 -1
- package/dist/cmd/ai/index.js +6 -1
- package/dist/cmd/ai/index.js.map +1 -1
- package/dist/cmd/ai/prompt/agent.d.ts +7 -0
- package/dist/cmd/ai/prompt/agent.d.ts.map +1 -1
- package/dist/cmd/ai/prompt/agent.js +12 -323
- package/dist/cmd/ai/prompt/agent.js.map +1 -1
- package/dist/cmd/ai/prompt/api.d.ts +7 -0
- package/dist/cmd/ai/prompt/api.d.ts.map +1 -1
- package/dist/cmd/ai/prompt/api.js +12 -260
- package/dist/cmd/ai/prompt/api.js.map +1 -1
- package/dist/cmd/ai/prompt/version.d.ts +35 -0
- package/dist/cmd/ai/prompt/version.d.ts.map +1 -0
- package/dist/cmd/ai/prompt/version.js +55 -0
- package/dist/cmd/ai/prompt/version.js.map +1 -0
- package/dist/cmd/ai/prompt/web.d.ts +7 -0
- package/dist/cmd/ai/prompt/web.d.ts.map +1 -1
- package/dist/cmd/ai/prompt/web.js +12 -283
- package/dist/cmd/ai/prompt/web.js.map +1 -1
- package/dist/cmd/ai/skills/generate.d.ts +3 -0
- package/dist/cmd/ai/skills/generate.d.ts.map +1 -0
- package/dist/cmd/ai/skills/generate.js +65 -0
- package/dist/cmd/ai/skills/generate.js.map +1 -0
- package/dist/cmd/ai/skills/generator.d.ts +4 -0
- package/dist/cmd/ai/skills/generator.d.ts.map +1 -0
- package/dist/cmd/ai/skills/generator.js +402 -0
- package/dist/cmd/ai/skills/generator.js.map +1 -0
- package/dist/cmd/ai/skills/index.d.ts +4 -0
- package/dist/cmd/ai/skills/index.d.ts.map +1 -0
- package/dist/cmd/ai/skills/index.js +21 -0
- package/dist/cmd/ai/skills/index.js.map +1 -0
- package/dist/cmd/auth/signup.d.ts.map +1 -1
- package/dist/cmd/auth/signup.js +1 -0
- package/dist/cmd/auth/signup.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 +255 -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.d.ts +7 -1
- package/dist/cmd/build/vite/bun-dev-server.d.ts.map +1 -1
- package/dist/cmd/build/vite/bun-dev-server.js +52 -26
- 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 -3
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +9 -7
- 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 +203 -7
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/prompt-generator.d.ts +23 -0
- package/dist/cmd/build/vite/prompt-generator.d.ts.map +1 -0
- package/dist/cmd/build/vite/prompt-generator.js +123 -0
- package/dist/cmd/build/vite/prompt-generator.js.map +1 -0
- 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 +644 -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 +4 -0
- package/dist/cmd/build/vite/server-bundler.d.ts.map +1 -1
- package/dist/cmd/build/vite/server-bundler.js +63 -17
- package/dist/cmd/build/vite/server-bundler.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 +4 -0
- package/dist/cmd/build/vite/vite-asset-server-config.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 +118 -96
- 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 +89 -32
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/create-namespace.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/create-namespace.js +3 -1
- package/dist/cmd/cloud/keyvalue/create-namespace.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/delete-namespace.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/delete-namespace.js +3 -1
- package/dist/cmd/cloud/keyvalue/delete-namespace.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/delete.js +3 -1
- package/dist/cmd/cloud/keyvalue/delete.js.map +1 -1
- package/dist/cmd/cloud/keyvalue/set.d.ts.map +1 -1
- package/dist/cmd/cloud/keyvalue/set.js +4 -2
- package/dist/cmd/cloud/keyvalue/set.js.map +1 -1
- package/dist/cmd/cloud/stream/get.d.ts.map +1 -1
- package/dist/cmd/cloud/stream/get.js +2 -13
- package/dist/cmd/cloud/stream/get.js.map +1 -1
- package/dist/cmd/cloud/vector/delete-namespace.d.ts +3 -0
- package/dist/cmd/cloud/vector/delete-namespace.d.ts.map +1 -0
- package/dist/cmd/cloud/vector/delete-namespace.js +77 -0
- package/dist/cmd/cloud/vector/delete-namespace.js.map +1 -0
- package/dist/cmd/cloud/vector/index.d.ts.map +1 -1
- package/dist/cmd/cloud/vector/index.js +21 -4
- package/dist/cmd/cloud/vector/index.js.map +1 -1
- package/dist/cmd/cloud/vector/list-namespaces.d.ts +3 -0
- package/dist/cmd/cloud/vector/list-namespaces.d.ts.map +1 -0
- package/dist/cmd/cloud/vector/list-namespaces.js +42 -0
- package/dist/cmd/cloud/vector/list-namespaces.js.map +1 -0
- package/dist/cmd/cloud/vector/stats.d.ts +3 -0
- package/dist/cmd/cloud/vector/stats.d.ts.map +1 -0
- package/dist/cmd/cloud/vector/stats.js +142 -0
- package/dist/cmd/cloud/vector/stats.js.map +1 -0
- package/dist/cmd/cloud/vector/upsert.d.ts +3 -0
- package/dist/cmd/cloud/vector/upsert.d.ts.map +1 -0
- package/dist/cmd/cloud/vector/upsert.js +192 -0
- package/dist/cmd/cloud/vector/upsert.js.map +1 -0
- package/dist/cmd/dev/file-watcher.d.ts.map +1 -1
- package/dist/cmd/dev/file-watcher.js +94 -33
- 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 +298 -61
- package/dist/cmd/dev/index.js.map +1 -1
- package/dist/cmd/dev/skills.d.ts +10 -0
- package/dist/cmd/dev/skills.d.ts.map +1 -0
- package/dist/cmd/dev/skills.js +57 -0
- package/dist/cmd/dev/skills.js.map +1 -0
- 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/index.d.ts.map +1 -1
- package/dist/cmd/index.js +1 -0
- package/dist/cmd/index.js.map +1 -1
- package/dist/cmd/project/create.d.ts.map +1 -1
- package/dist/cmd/project/create.js +3 -0
- package/dist/cmd/project/create.js.map +1 -1
- package/dist/cmd/project/template-flow.d.ts +1 -0
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +30 -5
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/dist/cmd/setup/index.d.ts.map +1 -1
- package/dist/cmd/setup/index.js +1 -0
- package/dist/cmd/setup/index.js.map +1 -1
- package/dist/cmd/upgrade/index.d.ts +15 -0
- package/dist/cmd/upgrade/index.d.ts.map +1 -1
- package/dist/cmd/upgrade/index.js +59 -4
- package/dist/cmd/upgrade/index.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/domain.d.ts +45 -0
- package/dist/domain.d.ts.map +1 -0
- package/dist/domain.js +200 -0
- package/dist/domain.js.map +1 -0
- 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/dist/schema-generator.d.ts +2 -0
- package/dist/schema-generator.d.ts.map +1 -1
- package/dist/schema-generator.js +18 -0
- package/dist/schema-generator.js.map +1 -1
- package/dist/steps.d.ts +1 -1
- package/dist/steps.d.ts.map +1 -1
- package/dist/steps.js +16 -5
- package/dist/steps.js.map +1 -1
- package/dist/tui/prompt.d.ts +1 -2
- package/dist/tui/prompt.d.ts.map +1 -1
- package/dist/tui/prompt.js +8 -4
- package/dist/tui/prompt.js.map +1 -1
- package/dist/tui.d.ts +16 -0
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +23 -2
- package/dist/tui.js.map +1 -1
- package/dist/types.d.ts +9 -2
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +3 -3
- package/dist/types.js.map +1 -1
- package/package.json +5 -8
- package/src/api.ts +1 -1
- package/src/cli.ts +47 -12
- package/src/cmd/ai/index.ts +6 -1
- package/src/cmd/ai/prompt/agent.md +306 -0
- package/src/cmd/ai/prompt/agent.ts +12 -322
- package/src/cmd/ai/prompt/api.md +360 -0
- package/src/cmd/ai/prompt/api.ts +13 -260
- package/src/cmd/ai/prompt/version.ts +61 -0
- package/src/cmd/ai/prompt/web.md +509 -0
- package/src/cmd/ai/prompt/web.ts +12 -282
- package/src/cmd/ai/skills/generate.ts +75 -0
- package/src/cmd/ai/skills/generator.ts +519 -0
- package/src/cmd/ai/skills/index.ts +23 -0
- package/src/cmd/auth/signup.ts +1 -0
- package/src/cmd/build/ast.ts +161 -48
- package/src/cmd/build/entry-generator.ts +258 -187
- package/src/cmd/build/vite/agent-discovery.ts +151 -58
- package/src/cmd/build/vite/bun-dev-server.ts +57 -27
- package/src/cmd/build/vite/docs-generator.ts +87 -0
- package/src/cmd/build/vite/index.ts +9 -7
- package/src/cmd/build/vite/lifecycle-generator.ts +19 -5
- package/src/cmd/build/vite/metadata-generator.ts +251 -7
- package/src/cmd/build/vite/prompt-generator.ts +169 -0
- package/src/cmd/build/vite/registry-generator.ts +750 -108
- package/src/cmd/build/vite/route-discovery.ts +4 -0
- package/src/cmd/build/vite/server-bundler.ts +73 -23
- package/src/cmd/build/vite/vite-asset-server-config.ts +5 -0
- package/src/cmd/build/vite/vite-builder.ts +134 -100
- package/src/cmd/build/vite-bundler.ts +6 -6
- package/src/cmd/cloud/deploy.ts +114 -36
- package/src/cmd/cloud/keyvalue/create-namespace.ts +3 -1
- package/src/cmd/cloud/keyvalue/delete-namespace.ts +3 -1
- package/src/cmd/cloud/keyvalue/delete.ts +3 -1
- package/src/cmd/cloud/keyvalue/set.ts +4 -2
- package/src/cmd/cloud/stream/get.ts +2 -9
- package/src/cmd/cloud/vector/delete-namespace.ts +89 -0
- package/src/cmd/cloud/vector/index.ts +21 -4
- package/src/cmd/cloud/vector/list-namespaces.ts +46 -0
- package/src/cmd/cloud/vector/stats.ts +160 -0
- package/src/cmd/cloud/vector/upsert.ts +216 -0
- package/src/cmd/dev/file-watcher.ts +109 -34
- package/src/cmd/dev/index.ts +364 -60
- package/src/cmd/dev/skills.ts +82 -0
- package/src/cmd/dev/sync.ts +41 -6
- package/src/cmd/index.ts +1 -0
- package/src/cmd/project/create.ts +3 -0
- package/src/cmd/project/template-flow.ts +37 -5
- package/src/cmd/setup/index.ts +1 -0
- package/src/cmd/upgrade/index.ts +68 -4
- package/src/config.ts +9 -0
- package/src/domain.ts +273 -0
- package/src/index.ts +0 -5
- package/src/runtime-bootstrap.md +1 -1
- package/src/schema-generator.ts +23 -0
- package/src/steps.ts +16 -5
- package/src/tui/prompt.ts +11 -5
- package/src/tui.ts +21 -2
- package/src/types/md.d.ts +8 -0
- package/src/types.ts +12 -3
- package/dist/cmd/cloud/domain.d.ts +0 -17
- package/dist/cmd/cloud/domain.d.ts.map +0 -1
- package/dist/cmd/cloud/domain.js +0 -79
- package/dist/cmd/cloud/domain.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/cloud/domain.ts +0 -100
- package/src/runtime-bootstrap.ts +0 -131
|
@@ -22,13 +22,12 @@ interface GenerateEntryOptions {
|
|
|
22
22
|
*/
|
|
23
23
|
export async function generateEntryFile(options: GenerateEntryOptions): Promise<void> {
|
|
24
24
|
const { rootDir, projectId, deploymentId, logger, mode, workbench, vitePort } = options;
|
|
25
|
-
const isDev = mode === 'dev';
|
|
26
25
|
|
|
27
26
|
const srcDir = join(rootDir, 'src');
|
|
28
|
-
const
|
|
29
|
-
const entryPath = join(
|
|
27
|
+
const generatedDir = join(srcDir, 'generated');
|
|
28
|
+
const entryPath = join(generatedDir, 'app.ts');
|
|
30
29
|
|
|
31
|
-
logger.trace(`Generating
|
|
30
|
+
logger.trace(`Generating unified entry file (supports both dev and prod modes)...`);
|
|
32
31
|
|
|
33
32
|
// Discover routes to determine which files need to be imported
|
|
34
33
|
const { routeInfoList } = await discoverRoutes(srcDir, projectId, deploymentId, logger);
|
|
@@ -54,6 +53,7 @@ export async function generateEntryFile(options: GenerateEntryOptions): Promise<
|
|
|
54
53
|
` createCorsMiddleware,`,
|
|
55
54
|
` createOtelMiddleware,`,
|
|
56
55
|
` createAgentMiddleware,`,
|
|
56
|
+
` createCompressionMiddleware,`,
|
|
57
57
|
` getAppState,`,
|
|
58
58
|
` getAppConfig,`,
|
|
59
59
|
` register,`,
|
|
@@ -77,12 +77,14 @@ export async function generateEntryFile(options: GenerateEntryOptions): Promise<
|
|
|
77
77
|
...runtimeImports,
|
|
78
78
|
`} from '@agentuity/runtime';`,
|
|
79
79
|
`import type { Context } from 'hono';`,
|
|
80
|
-
`import { websocket } from 'hono/bun';`,
|
|
81
|
-
|
|
80
|
+
`import { websocket } from 'hono/bun';`,
|
|
81
|
+
// Conditionally import serveStatic and readFileSync for web frontend or workbench support
|
|
82
|
+
hasWebFrontend || hasWorkbench ? `import { serveStatic } from 'hono/bun';` : '',
|
|
83
|
+
hasWebFrontend || hasWorkbench ? `import { readFileSync, existsSync } from 'node:fs';` : '',
|
|
82
84
|
].filter(Boolean);
|
|
83
85
|
|
|
84
86
|
imports.push(`import { type LogLevel } from '@agentuity/core';`);
|
|
85
|
-
imports.push(`import { bootstrapRuntimeEnv } from '@agentuity/
|
|
87
|
+
imports.push(`import { bootstrapRuntimeEnv } from '@agentuity/runtime';`);
|
|
86
88
|
|
|
87
89
|
// Generate route mounting code for all discovered routes
|
|
88
90
|
const routeImportsAndMounts: string[] = [];
|
|
@@ -107,7 +109,7 @@ export async function generateEntryFile(options: GenerateEntryOptions): Promise<
|
|
|
107
109
|
|
|
108
110
|
const importName = `router_${routeIndex++}`;
|
|
109
111
|
routeImportsAndMounts.push(
|
|
110
|
-
`const { default: ${importName} } = await import('../
|
|
112
|
+
`const { default: ${importName} } = await import('../api/${relativePath}.js');`
|
|
111
113
|
);
|
|
112
114
|
routeImportsAndMounts.push(`app.route('${mountPath}', ${importName});`);
|
|
113
115
|
}
|
|
@@ -129,185 +131,202 @@ app.route('/', workbenchRouter);
|
|
|
129
131
|
`
|
|
130
132
|
: '';
|
|
131
133
|
|
|
132
|
-
// Asset proxy routes
|
|
134
|
+
// Asset proxy routes - generated for dev mode, reads VITE_PORT from env at runtime
|
|
133
135
|
const assetProxyRoutes =
|
|
134
|
-
|
|
136
|
+
mode === 'dev'
|
|
135
137
|
? `
|
|
136
|
-
// Asset proxy routes -
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
const
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
138
|
+
// Asset proxy routes - Development mode only (proxies to Vite asset server)
|
|
139
|
+
if (isDevelopment() && process.env.VITE_PORT) {
|
|
140
|
+
const VITE_ASSET_PORT = parseInt(process.env.VITE_PORT, 10);
|
|
141
|
+
|
|
142
|
+
const proxyToVite = async (c: Context) => {
|
|
143
|
+
const viteUrl = \`http://127.0.0.1:\${VITE_ASSET_PORT}\${c.req.path}\`;
|
|
144
|
+
const controller = new AbortController();
|
|
145
|
+
const timeout = setTimeout(() => controller.abort(), 10000); // 10s timeout
|
|
146
|
+
try {
|
|
147
|
+
otel.logger.debug(\`[Proxy] \${c.req.method} \${c.req.path} -> Vite:\${VITE_ASSET_PORT}\`);
|
|
148
|
+
const res = await fetch(viteUrl, { signal: controller.signal });
|
|
149
|
+
clearTimeout(timeout);
|
|
150
|
+
otel.logger.debug(\`[Proxy] \${c.req.path} -> \${res.status} (\${res.headers.get('content-type')})\`);
|
|
151
|
+
return new Response(res.body, {
|
|
152
|
+
status: res.status,
|
|
153
|
+
headers: res.headers,
|
|
154
|
+
});
|
|
155
|
+
} catch (err) {
|
|
156
|
+
clearTimeout(timeout);
|
|
157
|
+
if (err instanceof Error && err.name === 'AbortError') {
|
|
158
|
+
otel.logger.error(\`Vite proxy timeout: \${c.req.path}\`);
|
|
159
|
+
return c.text('Vite asset server timeout', 504);
|
|
160
|
+
}
|
|
161
|
+
otel.logger.error(\`Failed to proxy to Vite: \${c.req.path} - \${err instanceof Error ? err.message : String(err)}\`);
|
|
162
|
+
return c.text('Vite asset server error', 500);
|
|
157
163
|
}
|
|
158
|
-
|
|
159
|
-
return c.text('Vite asset server error', 500);
|
|
160
|
-
}
|
|
161
|
-
};
|
|
164
|
+
};
|
|
162
165
|
|
|
163
|
-
// Vite client scripts and HMR
|
|
164
|
-
app.get('/@vite/*', proxyToVite);
|
|
165
|
-
app.get('/@react-refresh', proxyToVite);
|
|
166
|
+
// Vite client scripts and HMR
|
|
167
|
+
app.get('/@vite/*', proxyToVite);
|
|
168
|
+
app.get('/@react-refresh', proxyToVite);
|
|
166
169
|
|
|
167
|
-
// Source files for HMR
|
|
168
|
-
app.get('/src/web/*', proxyToVite);
|
|
169
|
-
app.get('/src/*', proxyToVite); // Catch-all for other source files
|
|
170
|
+
// Source files for HMR
|
|
171
|
+
app.get('/src/web/*', proxyToVite);
|
|
172
|
+
app.get('/src/*', proxyToVite); // Catch-all for other source files
|
|
170
173
|
|
|
171
|
-
// Workbench source files (in .agentuity/workbench-src/)
|
|
172
|
-
app.get('/.agentuity/workbench-src/*', proxyToVite);
|
|
174
|
+
// Workbench source files (in .agentuity/workbench-src/)
|
|
175
|
+
app.get('/.agentuity/workbench-src/*', proxyToVite);
|
|
173
176
|
|
|
174
|
-
// Node modules (Vite transforms these)
|
|
175
|
-
app.get('/node_modules/*', proxyToVite);
|
|
177
|
+
// Node modules (Vite transforms these)
|
|
178
|
+
app.get('/node_modules/*', proxyToVite);
|
|
176
179
|
|
|
177
|
-
// Scoped packages (e.g., @agentuity/*, @types/*)
|
|
178
|
-
app.get('/@*', proxyToVite);
|
|
180
|
+
// Scoped packages (e.g., @agentuity/*, @types/*)
|
|
181
|
+
app.get('/@*', proxyToVite);
|
|
179
182
|
|
|
180
|
-
// File system access (for Vite's @fs protocol)
|
|
181
|
-
app.get('/@fs/*', proxyToVite);
|
|
183
|
+
// File system access (for Vite's @fs protocol)
|
|
184
|
+
app.get('/@fs/*', proxyToVite);
|
|
182
185
|
|
|
183
|
-
// Module resolution (for Vite's @id protocol)
|
|
184
|
-
app.get('/@id/*', proxyToVite);
|
|
186
|
+
// Module resolution (for Vite's @id protocol)
|
|
187
|
+
app.get('/@id/*', proxyToVite);
|
|
185
188
|
|
|
186
|
-
// Any .js, .jsx, .ts, .tsx files (catch remaining modules)
|
|
187
|
-
app.get('/*.js', proxyToVite);
|
|
188
|
-
app.get('/*.jsx', proxyToVite);
|
|
189
|
-
app.get('/*.ts', proxyToVite);
|
|
190
|
-
app.get('/*.tsx', proxyToVite);
|
|
191
|
-
app.get('/*.css', proxyToVite);
|
|
189
|
+
// Any .js, .jsx, .ts, .tsx files (catch remaining modules)
|
|
190
|
+
app.get('/*.js', proxyToVite);
|
|
191
|
+
app.get('/*.jsx', proxyToVite);
|
|
192
|
+
app.get('/*.ts', proxyToVite);
|
|
193
|
+
app.get('/*.tsx', proxyToVite);
|
|
194
|
+
app.get('/*.css', proxyToVite);
|
|
195
|
+
}
|
|
192
196
|
`
|
|
193
197
|
: '';
|
|
194
198
|
|
|
195
|
-
//
|
|
199
|
+
// Runtime mode detection helper (defined at top level for reuse)
|
|
200
|
+
// Dynamic property access prevents Bun.build from inlining NODE_ENV at build time
|
|
201
|
+
const modeDetection = `
|
|
202
|
+
// Runtime mode detection helper
|
|
203
|
+
// Dynamic string concatenation prevents Bun.build from inlining NODE_ENV at build time
|
|
204
|
+
// See: https://github.com/oven-sh/bun/issues/20183
|
|
205
|
+
const getEnv = (key: string) => process.env[key];
|
|
206
|
+
const isDevelopment = () => getEnv('NODE' + '_' + 'ENV') !== 'production';
|
|
207
|
+
`;
|
|
208
|
+
|
|
209
|
+
// Web routes (runtime mode detection)
|
|
196
210
|
let webRoutes = '';
|
|
197
211
|
if (hasWebFrontend) {
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
// Proxy HTML from Vite to
|
|
202
|
-
const
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
.
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
app.
|
|
228
|
-
|
|
229
|
-
//
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
app.
|
|
233
|
-
|
|
234
|
-
//
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
return
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
//
|
|
245
|
-
|
|
246
|
-
const indexHtml =
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
// Serve static public assets (favicon.ico, robots.txt, etc. from Vite's public folder)
|
|
254
|
-
app.use('/*', serveStatic({ root: import.meta.dir + '/client', rewriteRequestPath: (path) => path }));
|
|
255
|
-
|
|
256
|
-
// 404 for unmatched API/system routes (IMPORTANT: comes before SPA fallback)
|
|
257
|
-
app.all('/_agentuity/*', (c: Context) => c.notFound());
|
|
258
|
-
app.all('/api/*', (c: Context) => c.notFound());
|
|
259
|
-
${hasWorkbench ? '' : `app.all('/workbench/*', (c: Context) => c.notFound());`}
|
|
260
|
-
|
|
261
|
-
// SPA fallback with asset protection
|
|
262
|
-
// In production, we need to distinguish between:
|
|
263
|
-
// - SPA routes like /dashboard, /users/123 (should return HTML)
|
|
264
|
-
// - Missing assets like /foo.js, /bar.css (should return 404)
|
|
265
|
-
// We check for file extensions to detect asset requests
|
|
266
|
-
app.get('*', (c: Context) => {
|
|
267
|
-
const path = c.req.path;
|
|
268
|
-
// If path has a file extension, it's likely an asset request
|
|
269
|
-
// Return 404 instead of serving HTML
|
|
270
|
-
if (/\\.[a-zA-Z0-9]+$/.test(path)) {
|
|
271
|
-
return c.notFound();
|
|
212
|
+
webRoutes = `
|
|
213
|
+
// Web routes - Runtime mode detection (dev proxies to Vite, prod serves static)
|
|
214
|
+
if (isDevelopment()) {
|
|
215
|
+
// Development mode: Proxy HTML from Vite to enable React Fast Refresh
|
|
216
|
+
const VITE_ASSET_PORT = parseInt(process.env.VITE_PORT || '${vitePort || 5173}', 10);
|
|
217
|
+
|
|
218
|
+
const devHtmlHandler = async (c: Context) => {
|
|
219
|
+
const viteUrl = \`http://127.0.0.1:\${VITE_ASSET_PORT}/src/web/index.html\`;
|
|
220
|
+
|
|
221
|
+
try {
|
|
222
|
+
otel.logger.debug('[Proxy] GET /src/web/index.html -> Vite:%d', VITE_ASSET_PORT);
|
|
223
|
+
const res = await fetch(viteUrl, { signal: AbortSignal.timeout(10000) });
|
|
224
|
+
|
|
225
|
+
// Get HTML text and transform relative paths to absolute
|
|
226
|
+
const html = await res.text();
|
|
227
|
+
const transformedHtml = html
|
|
228
|
+
.replace(/src="\\.\\//g, 'src="/src/web/')
|
|
229
|
+
.replace(/href="\\.\\//g, 'href="/src/web/');
|
|
230
|
+
|
|
231
|
+
return new Response(transformedHtml, {
|
|
232
|
+
status: res.status,
|
|
233
|
+
headers: res.headers,
|
|
234
|
+
});
|
|
235
|
+
} catch (err) {
|
|
236
|
+
otel.logger.error('Failed to proxy HTML to Vite: %s', err instanceof Error ? err.message : String(err));
|
|
237
|
+
return c.text('Vite asset server error (HTML)', 500);
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
app.get('/', devHtmlHandler);
|
|
242
|
+
|
|
243
|
+
// 404 for unmatched API/system routes
|
|
244
|
+
app.all('/_agentuity/*', (c: Context) => c.notFound());
|
|
245
|
+
app.all('/api/*', (c: Context) => c.notFound());
|
|
246
|
+
${hasWorkbench ? '' : `app.all('/workbench/*', (c: Context) => c.notFound());`}
|
|
247
|
+
|
|
248
|
+
// SPA fallback - serve index.html for client-side routing
|
|
249
|
+
app.get('*', (c: Context) => {
|
|
250
|
+
const path = c.req.path;
|
|
251
|
+
// If path has a file extension, return 404 (prevents serving HTML for missing assets)
|
|
252
|
+
if (/\\.[a-zA-Z0-9]+$/.test(path)) {
|
|
253
|
+
return c.notFound();
|
|
254
|
+
}
|
|
255
|
+
return devHtmlHandler(c);
|
|
256
|
+
});
|
|
257
|
+
} else {
|
|
258
|
+
// Production mode: Serve static files from bundled output
|
|
259
|
+
const indexHtmlPath = import.meta.dir + '/client/index.html';
|
|
260
|
+
const indexHtml = existsSync(indexHtmlPath)
|
|
261
|
+
? readFileSync(indexHtmlPath, 'utf-8')
|
|
262
|
+
: '';
|
|
263
|
+
|
|
264
|
+
if (!indexHtml) {
|
|
265
|
+
otel.logger.warn('Production HTML not found at %s', indexHtmlPath);
|
|
272
266
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
267
|
+
|
|
268
|
+
app.get('/', (c: Context) => indexHtml ? c.html(indexHtml) : c.text('Production build incomplete', 500));
|
|
269
|
+
|
|
270
|
+
// Serve static assets from /assets/* (Vite bundled output)
|
|
271
|
+
app.use('/assets/*', serveStatic({ root: import.meta.dir + '/client' }));
|
|
272
|
+
|
|
273
|
+
// Serve static public assets (favicon.ico, robots.txt, etc.)
|
|
274
|
+
app.use('/*', serveStatic({ root: import.meta.dir + '/client', rewriteRequestPath: (path) => path }));
|
|
275
|
+
|
|
276
|
+
// 404 for unmatched API/system routes (IMPORTANT: comes before SPA fallback)
|
|
277
|
+
app.all('/_agentuity/*', (c: Context) => c.notFound());
|
|
278
|
+
app.all('/api/*', (c: Context) => c.notFound());
|
|
279
|
+
${hasWorkbench ? '' : `app.all('/workbench/*', (c: Context) => c.notFound());`}
|
|
280
|
+
|
|
281
|
+
// SPA fallback with asset protection
|
|
282
|
+
app.get('*', (c: Context) => {
|
|
283
|
+
const path = c.req.path;
|
|
284
|
+
// If path has a file extension, it's likely an asset request - return 404
|
|
285
|
+
if (/\\.[a-zA-Z0-9]+$/.test(path)) {
|
|
286
|
+
return c.notFound();
|
|
276
287
|
}
|
|
288
|
+
return c.html(indexHtml);
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
`;
|
|
277
292
|
}
|
|
278
293
|
|
|
279
|
-
// Workbench routes (if enabled)
|
|
294
|
+
// Workbench routes (if enabled) - runtime mode detection
|
|
280
295
|
const workbenchRoute = workbench?.route ?? '/workbench';
|
|
281
|
-
const workbenchSrcDir = join(agentuityDir, 'workbench-src');
|
|
282
296
|
const workbenchRoutes = hasWorkbench
|
|
283
|
-
?
|
|
284
|
-
|
|
285
|
-
//
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
// Rewrite script/css paths to use Vite's @fs protocol
|
|
289
|
-
const withVite = html
|
|
290
|
-
.replace('src="./main.tsx"', 'src="/@fs${workbenchSrcDir}/main.tsx"')
|
|
291
|
-
.replace('href="./styles.css"', 'href="/@fs${workbenchSrcDir}/styles.css"');
|
|
292
|
-
return c.html(withVite);
|
|
293
|
-
});
|
|
294
|
-
`
|
|
295
|
-
: `
|
|
296
|
-
// Workbench routes (production - serve pre-built assets)
|
|
297
|
-
// Use import.meta.dir for absolute paths (app.js runs from .agentuity/)
|
|
298
|
-
import { readFileSync, existsSync } from 'node:fs';
|
|
297
|
+
? `
|
|
298
|
+
// Workbench routes - Runtime mode detection
|
|
299
|
+
// Both dev and prod run from .agentuity/app.js (dev bundles before running)
|
|
300
|
+
// So workbench-src is always in the same directory
|
|
301
|
+
const workbenchSrcDir = import.meta.dir + '/workbench-src';
|
|
299
302
|
const workbenchIndexPath = import.meta.dir + '/workbench/index.html';
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
303
|
+
const workbenchIndex = existsSync(workbenchIndexPath)
|
|
304
|
+
? readFileSync(workbenchIndexPath, 'utf-8')
|
|
305
|
+
: '';
|
|
306
|
+
|
|
307
|
+
if (isDevelopment()) {
|
|
308
|
+
// Development mode: Let Vite serve source files with HMR
|
|
309
|
+
app.get('${workbenchRoute}', async (c: Context) => {
|
|
310
|
+
const html = await Bun.file(workbenchSrcDir + '/index.html').text();
|
|
311
|
+
// Rewrite script/css paths to use Vite's @fs protocol
|
|
312
|
+
const withVite = html
|
|
313
|
+
.replace('src="./main.tsx"', \`src="/@fs\${workbenchSrcDir}/main.tsx"\`)
|
|
314
|
+
.replace('href="./styles.css"', \`href="/@fs\${workbenchSrcDir}/styles.css"\`);
|
|
315
|
+
return c.html(withVite);
|
|
316
|
+
});
|
|
317
|
+
} else {
|
|
318
|
+
// Production mode: Serve pre-built assets
|
|
319
|
+
if (workbenchIndex) {
|
|
320
|
+
app.get('${workbenchRoute}', (c: Context) => c.html(workbenchIndex));
|
|
321
|
+
app.get('${workbenchRoute}/*', serveStatic({ root: import.meta.dir + '/workbench' }));
|
|
322
|
+
}
|
|
304
323
|
}
|
|
305
324
|
`
|
|
306
325
|
: '';
|
|
307
326
|
|
|
308
327
|
// Server startup (same for dev and prod - Bun.serve with native WebSocket)
|
|
309
328
|
const serverStartup = `
|
|
310
|
-
// Start Bun server
|
|
329
|
+
// Start Bun server
|
|
311
330
|
if (typeof Bun !== 'undefined') {
|
|
312
331
|
// Enable process exit protection now that we're starting the server
|
|
313
332
|
enableProcessExitProtection();
|
|
@@ -323,20 +342,86 @@ if (typeof Bun !== 'undefined') {
|
|
|
323
342
|
// Make server available globally for health checks
|
|
324
343
|
(globalThis as any).__AGENTUITY_SERVER__ = server;
|
|
325
344
|
|
|
326
|
-
otel.logger.info(\`Server listening on http://127.0.0.1:\${port}\`)
|
|
345
|
+
otel.logger.info(\`Server listening on http://127.0.0.1:\${port}\`);
|
|
346
|
+
if (isDevelopment() && process.env.VITE_PORT) {
|
|
347
|
+
otel.logger.debug(\`Proxying Vite assets from port \${process.env.VITE_PORT}\`);
|
|
348
|
+
}
|
|
327
349
|
}
|
|
350
|
+
|
|
351
|
+
// FOUND AN ERROR IN THIS FILE?
|
|
352
|
+
// Please file an issue at https://github.com/agentuity/sdk/issues
|
|
353
|
+
// or if you know the fix please submit a PR!
|
|
328
354
|
`;
|
|
329
355
|
|
|
330
|
-
const
|
|
356
|
+
const healthRoutes = `
|
|
357
|
+
// Health check routes (production only)
|
|
358
|
+
if (!isDevelopment()) {
|
|
359
|
+
const healthHandler = (c: Context) => {
|
|
360
|
+
return c.text('OK', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
361
|
+
};
|
|
362
|
+
const idleHandler = (c: Context) => {
|
|
363
|
+
// Check if server is idle (no pending requests/connections)
|
|
364
|
+
const server = (globalThis as any).__AGENTUITY_SERVER__;
|
|
365
|
+
if (!server) return c.text('NO', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
366
|
+
|
|
367
|
+
// Check for pending background tasks
|
|
368
|
+
if (hasWaitUntilPending()) return c.text('NO', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
369
|
+
|
|
370
|
+
if (server.pendingRequests > 1) return c.text('NO', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
371
|
+
if (server.pendingWebSockets > 0) return c.text('NO', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
372
|
+
|
|
373
|
+
return c.text('OK', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
374
|
+
};
|
|
375
|
+
app.get('/_agentuity/health', healthHandler);
|
|
376
|
+
app.get('/_health', healthHandler);
|
|
377
|
+
app.get('/_agentuity/idle', idleHandler);
|
|
378
|
+
app.get('/_idle', idleHandler);
|
|
379
|
+
}
|
|
380
|
+
|
|
381
|
+
// Dev readiness check - verifies Vite asset server is ready to serve frontend
|
|
382
|
+
if (isDevelopment()) {
|
|
383
|
+
app.get('/_agentuity/ready', async (c: Context) => {
|
|
384
|
+
const vitePort = process.env.VITE_PORT;
|
|
385
|
+
if (!vitePort) {
|
|
386
|
+
// No Vite port means we're not using Vite proxy
|
|
387
|
+
return c.text('OK', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
try {
|
|
391
|
+
// Probe Vite to check if it can serve the main entry point
|
|
392
|
+
// Use @vite/client as a lightweight check - it's always available
|
|
393
|
+
const viteUrl = \`http://127.0.0.1:\${vitePort}/@vite/client\`;
|
|
394
|
+
const res = await fetch(viteUrl, {
|
|
395
|
+
signal: AbortSignal.timeout(5000),
|
|
396
|
+
method: 'HEAD'
|
|
397
|
+
});
|
|
398
|
+
|
|
399
|
+
if (res.ok) {
|
|
400
|
+
return c.text('OK', 200, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
401
|
+
}
|
|
402
|
+
return c.text('VITE_NOT_READY', 503, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
403
|
+
} catch (err) {
|
|
404
|
+
otel.logger.debug('Vite readiness check failed: %s', err instanceof Error ? err.message : String(err));
|
|
405
|
+
return c.text('VITE_NOT_READY', 503, { 'Content-Type': 'text/plain; charset=utf-8' });
|
|
406
|
+
}
|
|
407
|
+
});
|
|
408
|
+
}
|
|
409
|
+
`;
|
|
410
|
+
|
|
411
|
+
const code = `// @generated
|
|
412
|
+
// Auto-generated by Agentuity
|
|
331
413
|
// DO NOT EDIT - This file is regenerated on every build
|
|
414
|
+
// Supports both development and production modes via runtime detection
|
|
332
415
|
${imports.join('\n')}
|
|
333
416
|
|
|
417
|
+
${modeDetection}
|
|
418
|
+
|
|
334
419
|
// Step 0: Bootstrap runtime environment (load profile-specific .env files)
|
|
335
420
|
// Only in development - production env vars are injected by platform
|
|
336
421
|
// This must happen BEFORE any imports that depend on environment variables
|
|
337
|
-
if (
|
|
338
|
-
// Pass project directory (
|
|
339
|
-
await bootstrapRuntimeEnv({ projectDir: import.meta.dir + '
|
|
422
|
+
if (isDevelopment()) {
|
|
423
|
+
// Pass project directory (two levels up from src/generated/) so .env files are loaded correctly
|
|
424
|
+
await bootstrapRuntimeEnv({ projectDir: import.meta.dir + '/../..' });
|
|
340
425
|
}
|
|
341
426
|
|
|
342
427
|
// Step 1: Initialize telemetry and services
|
|
@@ -358,6 +443,9 @@ const app = createRouter();
|
|
|
358
443
|
setGlobalRouter(app);
|
|
359
444
|
|
|
360
445
|
// Step 3: Apply middleware in correct order (BEFORE mounting routes)
|
|
446
|
+
// Compression runs first (outermost) so it can compress the final response
|
|
447
|
+
app.use('*', createCompressionMiddleware());
|
|
448
|
+
|
|
361
449
|
app.use('*', createBaseMiddleware({
|
|
362
450
|
logger: otel.logger,
|
|
363
451
|
tracer: otel.tracer,
|
|
@@ -375,7 +463,7 @@ app.use('/api/*', createOtelMiddleware());
|
|
|
375
463
|
app.use('/api/*', createAgentMiddleware(''));
|
|
376
464
|
|
|
377
465
|
// Step 4: Import user's app.ts (runs createApp, gets state/config)
|
|
378
|
-
await import('
|
|
466
|
+
await import('../../app.js');
|
|
379
467
|
|
|
380
468
|
// Step 5: Initialize providers
|
|
381
469
|
const threadProvider = getThreadProvider();
|
|
@@ -386,27 +474,7 @@ await sessionProvider.initialize(appState);
|
|
|
386
474
|
|
|
387
475
|
// Step 6: Mount routes (AFTER middleware is applied)
|
|
388
476
|
|
|
389
|
-
|
|
390
|
-
const healthHandler = (c: Context) => c.text('OK');
|
|
391
|
-
const idleHandler = (c: Context) => {
|
|
392
|
-
// Check if server is idle (no pending requests/connections)
|
|
393
|
-
const server = (globalThis as any).__AGENTUITY_SERVER__;
|
|
394
|
-
if (!server) return c.text('NO', { status: 200 });
|
|
395
|
-
|
|
396
|
-
// Check for pending background tasks
|
|
397
|
-
if (hasWaitUntilPending()) return c.text('NO', { status: 200 });
|
|
398
|
-
|
|
399
|
-
if (server.pendingRequests > 1) return c.text('NO', { status: 200 });
|
|
400
|
-
if (server.pendingWebSockets > 0) return c.text('NO', { status: 200 });
|
|
401
|
-
|
|
402
|
-
return c.text('OK', { status: 200 });
|
|
403
|
-
};
|
|
404
|
-
|
|
405
|
-
app.get('/_agentuity/health', healthHandler);
|
|
406
|
-
app.get('/_health', healthHandler);
|
|
407
|
-
app.get('/_agentuity/idle', idleHandler);
|
|
408
|
-
app.get('/_idle', idleHandler);
|
|
409
|
-
|
|
477
|
+
${healthRoutes}
|
|
410
478
|
${assetProxyRoutes}
|
|
411
479
|
${apiMount}
|
|
412
480
|
${workbenchApiMount}
|
|
@@ -419,6 +487,9 @@ await runAgentSetups(appState);
|
|
|
419
487
|
${serverStartup}
|
|
420
488
|
`;
|
|
421
489
|
|
|
422
|
-
|
|
423
|
-
|
|
490
|
+
// Collapse 2+ consecutive empty lines into 1 empty line (3+ \n becomes 2 \n)
|
|
491
|
+
const cleanedCode = code.replace(/\n{3,}/g, '\n\n');
|
|
492
|
+
|
|
493
|
+
await Bun.write(entryPath, cleanedCode);
|
|
494
|
+
logger.trace(`Generated unified entry file at %s (mode: ${mode})`, entryPath);
|
|
424
495
|
}
|