@agentuity/cli 0.0.101 → 0.0.103
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 +21 -14
- 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/entry-generator.d.ts.map +1 -1
- package/dist/cmd/build/entry-generator.js +40 -5
- package/dist/cmd/build/entry-generator.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 +30 -26
- package/dist/cmd/build/vite/bun-dev-server.js.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +58 -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.map +1 -1
- package/dist/cmd/build/vite/registry-generator.js +28 -11
- package/dist/cmd/build/vite/registry-generator.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 +45 -16
- 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.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +99 -87
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/cloud/deploy.d.ts.map +1 -1
- package/dist/cmd/cloud/deploy.js +80 -27
- 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 +90 -31
- 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 +244 -64
- 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.js +7 -7
- 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/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/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 +4 -4
- 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/entry-generator.ts +43 -7
- package/src/cmd/build/vite/bun-dev-server.ts +31 -28
- package/src/cmd/build/vite/metadata-generator.ts +73 -7
- package/src/cmd/build/vite/prompt-generator.ts +169 -0
- package/src/cmd/build/vite/registry-generator.ts +33 -10
- package/src/cmd/build/vite/server-bundler.ts +53 -22
- package/src/cmd/build/vite/vite-asset-server-config.ts +5 -0
- package/src/cmd/build/vite/vite-builder.ts +107 -87
- package/src/cmd/cloud/deploy.ts +103 -31
- 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 +101 -32
- package/src/cmd/dev/index.ts +343 -115
- package/src/cmd/dev/skills.ts +82 -0
- package/src/cmd/dev/sync.ts +7 -7
- 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/domain.ts +273 -0
- 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/src/cmd/cloud/domain.ts +0 -100
|
@@ -23,45 +23,48 @@ export interface BunDevServerResult {
|
|
|
23
23
|
|
|
24
24
|
/**
|
|
25
25
|
* Start Bun dev server (Vite asset server must already be running)
|
|
26
|
-
*
|
|
26
|
+
*
|
|
27
|
+
* IMPORTANT: This function assumes that the dev bundle has already been built:
|
|
28
|
+
* - Entry file generated at src/generated/app.ts (with workbench config if enabled)
|
|
29
|
+
* - Bundled to .agentuity/app.js with LLM patches applied
|
|
30
|
+
*
|
|
31
|
+
* The bundle is loaded here to ensure AI Gateway routing patches are active.
|
|
32
|
+
* Vite port is read from process.env.VITE_PORT at runtime.
|
|
27
33
|
*/
|
|
28
34
|
export async function startBunDevServer(options: BunDevServerOptions): Promise<BunDevServerResult> {
|
|
29
|
-
const { rootDir, port = 3500,
|
|
35
|
+
const { rootDir, port = 3500, logger, vitePort } = options;
|
|
30
36
|
|
|
31
37
|
logger.debug('Starting Bun dev server (Vite already running on port %d)...', vitePort);
|
|
32
38
|
|
|
33
|
-
//
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
39
|
+
// Load the bundled app - this will start Bun.serve() internally
|
|
40
|
+
// IMPORTANT: We must import the bundled .agentuity/app.js (NOT src/generated/app.ts)
|
|
41
|
+
// because the bundled version has LLM provider patches applied that enable AI Gateway routing.
|
|
42
|
+
// Importing the source file directly would bypass these patches.
|
|
43
|
+
logger.debug('📦 Loading bundled app (Bun server will start)...');
|
|
44
|
+
const appPath = `${rootDir}/.agentuity/app.js`;
|
|
37
45
|
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
46
|
+
// Verify bundle exists before attempting to load
|
|
47
|
+
const appFile = Bun.file(appPath);
|
|
48
|
+
if (!(await appFile.exists())) {
|
|
49
|
+
throw new Error(
|
|
50
|
+
`Dev bundle not found at ${appPath}. The bundle must be generated before starting the dev server.`
|
|
51
|
+
);
|
|
42
52
|
}
|
|
43
53
|
|
|
44
|
-
// Step 2: Generate entry file with Vite port for asset proxying
|
|
45
|
-
logger.debug('📝 Generating entry file with asset proxy configuration...');
|
|
46
|
-
const { generateEntryFile } = await import('../entry-generator');
|
|
47
|
-
await generateEntryFile({
|
|
48
|
-
rootDir,
|
|
49
|
-
projectId: projectId || '',
|
|
50
|
-
deploymentId: deploymentId || '',
|
|
51
|
-
logger,
|
|
52
|
-
mode: 'dev',
|
|
53
|
-
workbench: workbenchConfig.enabled ? workbenchConfig : undefined,
|
|
54
|
-
vitePort, // Pass Vite port for proxy routes
|
|
55
|
-
});
|
|
56
|
-
|
|
57
|
-
// Step 3: Load the generated app - this will start Bun.serve() internally
|
|
58
|
-
logger.debug('📦 Loading generated app (Bun server will start)...');
|
|
59
|
-
const appPath = `${rootDir}/src/generated/app.ts`;
|
|
60
|
-
|
|
61
54
|
// Set PORT env var so the generated app uses the correct port
|
|
62
55
|
process.env.PORT = String(port);
|
|
63
56
|
|
|
64
|
-
|
|
57
|
+
// Import the generated app with cache-busting query parameter.
|
|
58
|
+
// Bun's module cache is keyed by the full specifier including query string,
|
|
59
|
+
// so adding a unique timestamp forces a fresh import on each reload.
|
|
60
|
+
const cacheBuster = `?t=${Date.now()}`;
|
|
61
|
+
try {
|
|
62
|
+
await import(appPath + cacheBuster);
|
|
63
|
+
} catch (err) {
|
|
64
|
+
const errorMessage = err instanceof Error ? err.message : String(err);
|
|
65
|
+
logger.error('Failed to import generated app from %s: %s', appPath, errorMessage);
|
|
66
|
+
throw new Error(`Failed to load generated app: ${errorMessage}`);
|
|
67
|
+
}
|
|
65
68
|
|
|
66
69
|
// Wait for server to actually start listening
|
|
67
70
|
// The generated app sets (globalThis as any).__AGENTUITY_SERVER__ when server starts
|
|
@@ -25,6 +25,7 @@ interface AssetInfo {
|
|
|
25
25
|
kind: string;
|
|
26
26
|
contentType: string;
|
|
27
27
|
size: number;
|
|
28
|
+
contentEncoding?: string;
|
|
28
29
|
}
|
|
29
30
|
|
|
30
31
|
function getContentType(filename: string): string {
|
|
@@ -65,6 +66,59 @@ function getContentType(filename: string): string {
|
|
|
65
66
|
}
|
|
66
67
|
}
|
|
67
68
|
|
|
69
|
+
/**
|
|
70
|
+
* Determine if an asset should be compressed with gzip.
|
|
71
|
+
* The result is included in asset metadata so the API can generate
|
|
72
|
+
* presigned URLs with matching Content-Encoding.
|
|
73
|
+
*/
|
|
74
|
+
function shouldCompressAsset(asset: {
|
|
75
|
+
filename: string;
|
|
76
|
+
contentType: string;
|
|
77
|
+
kind: string;
|
|
78
|
+
}): boolean {
|
|
79
|
+
const ct = asset.contentType.toLowerCase();
|
|
80
|
+
const filename = asset.filename.toLowerCase();
|
|
81
|
+
|
|
82
|
+
if (ct.startsWith('image/') && ct !== 'image/svg+xml') {
|
|
83
|
+
return false;
|
|
84
|
+
}
|
|
85
|
+
if (ct.startsWith('video/') || ct.startsWith('audio/')) {
|
|
86
|
+
return false;
|
|
87
|
+
}
|
|
88
|
+
if (ct === 'font/woff' || ct === 'font/woff2') {
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
if (/\.(zip|gz|tgz|tar|bz2|br)$/.test(filename)) {
|
|
92
|
+
return false;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
if (
|
|
96
|
+
ct.startsWith('text/') ||
|
|
97
|
+
ct === 'application/javascript' ||
|
|
98
|
+
ct === 'application/json' ||
|
|
99
|
+
ct === 'application/xml' ||
|
|
100
|
+
ct === 'application/xhtml+xml' ||
|
|
101
|
+
ct === 'image/svg+xml'
|
|
102
|
+
) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
if (ct === 'font/ttf' || ct === 'application/vnd.ms-fontobject') {
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
if (
|
|
111
|
+
asset.kind === 'entry-point' ||
|
|
112
|
+
asset.kind === 'script' ||
|
|
113
|
+
asset.kind === 'stylesheet' ||
|
|
114
|
+
asset.kind === 'sourcemap'
|
|
115
|
+
) {
|
|
116
|
+
return true;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
return false;
|
|
120
|
+
}
|
|
121
|
+
|
|
68
122
|
function getAssetKind(filename: string, isEntry: boolean = false): string {
|
|
69
123
|
const ext = filename.split('.').pop()?.toLowerCase();
|
|
70
124
|
|
|
@@ -220,12 +274,18 @@ export async function generateMetadata(options: MetadataGeneratorOptions): Promi
|
|
|
220
274
|
}
|
|
221
275
|
|
|
222
276
|
seenAssets.add(assetPath);
|
|
223
|
-
|
|
277
|
+
const kind = getAssetKind(relativePath, isEntry);
|
|
278
|
+
const contentType = getContentType(relativePath);
|
|
279
|
+
const assetInfo: AssetInfo = {
|
|
224
280
|
filename: assetPath,
|
|
225
|
-
kind
|
|
226
|
-
contentType
|
|
281
|
+
kind,
|
|
282
|
+
contentType,
|
|
227
283
|
size: stats.size,
|
|
228
|
-
}
|
|
284
|
+
};
|
|
285
|
+
if (shouldCompressAsset(assetInfo)) {
|
|
286
|
+
assetInfo.contentEncoding = 'gzip';
|
|
287
|
+
}
|
|
288
|
+
assets.push(assetInfo);
|
|
229
289
|
}
|
|
230
290
|
};
|
|
231
291
|
|
|
@@ -328,12 +388,17 @@ export async function generateMetadata(options: MetadataGeneratorOptions): Promi
|
|
|
328
388
|
const assetPath = `public/${relativePath}`;
|
|
329
389
|
if (!seenAssets.has(assetPath)) {
|
|
330
390
|
seenAssets.add(assetPath);
|
|
331
|
-
|
|
391
|
+
const contentType = getContentType(entry.name);
|
|
392
|
+
const assetInfo: AssetInfo = {
|
|
332
393
|
filename: assetPath,
|
|
333
394
|
kind: 'static',
|
|
334
|
-
contentType
|
|
395
|
+
contentType,
|
|
335
396
|
size: stats.size,
|
|
336
|
-
}
|
|
397
|
+
};
|
|
398
|
+
if (shouldCompressAsset(assetInfo)) {
|
|
399
|
+
assetInfo.contentEncoding = 'gzip';
|
|
400
|
+
}
|
|
401
|
+
assets.push(assetInfo);
|
|
337
402
|
}
|
|
338
403
|
}
|
|
339
404
|
}
|
|
@@ -668,6 +733,7 @@ function generateAgentsMd(metadata: BuildMetadata): string {
|
|
|
668
733
|
lines.push('- Home directory: `/home/agentuity`');
|
|
669
734
|
lines.push('- Working directory: `/home/agentuity/app` (application code deployed here)');
|
|
670
735
|
lines.push('- Logs directory: `/home/agentuity/logs`');
|
|
736
|
+
lines.push('- Temp directory: `/home/agentuity/tmp`');
|
|
671
737
|
lines.push('');
|
|
672
738
|
lines.push('**Pre-installed Tools:**');
|
|
673
739
|
lines.push('- **Runtimes:** Node.js 24, Bun 1.x');
|
|
@@ -0,0 +1,169 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Prompt Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates AGENTS.md prompt files in .agents/agentuity/sdk/[type]/ directories.
|
|
5
|
+
* Also creates reference files in src/[type]/AGENTS.md (write-once, only if missing).
|
|
6
|
+
*
|
|
7
|
+
* Uses hash tracking to detect template changes in .agents/ folder.
|
|
8
|
+
* Reference files in src/ are never overwritten once created.
|
|
9
|
+
*
|
|
10
|
+
* Only runs in dev mode.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { join, dirname } from 'node:path';
|
|
14
|
+
import { mkdir } from 'node:fs/promises';
|
|
15
|
+
import type { Logger } from '../../../types';
|
|
16
|
+
import { needsUpdate } from '../../ai/prompt/version';
|
|
17
|
+
import {
|
|
18
|
+
generateLLMPrompt as generateAgentPrompt,
|
|
19
|
+
getPromptContent as getAgentContent,
|
|
20
|
+
} from '../../ai/prompt/agent';
|
|
21
|
+
import {
|
|
22
|
+
generateLLMPrompt as generateApiPrompt,
|
|
23
|
+
getPromptContent as getApiContent,
|
|
24
|
+
} from '../../ai/prompt/api';
|
|
25
|
+
import {
|
|
26
|
+
generateLLMPrompt as generateWebPrompt,
|
|
27
|
+
getPromptContent as getWebContent,
|
|
28
|
+
} from '../../ai/prompt/web';
|
|
29
|
+
|
|
30
|
+
interface PromptConfig {
|
|
31
|
+
name: string;
|
|
32
|
+
srcFolder: string;
|
|
33
|
+
generate: () => string;
|
|
34
|
+
getContent: () => string;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
const PROMPTS: PromptConfig[] = [
|
|
38
|
+
{
|
|
39
|
+
name: 'agent',
|
|
40
|
+
srcFolder: 'agent',
|
|
41
|
+
generate: generateAgentPrompt,
|
|
42
|
+
getContent: getAgentContent,
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
name: 'api',
|
|
46
|
+
srcFolder: 'api',
|
|
47
|
+
generate: generateApiPrompt,
|
|
48
|
+
getContent: getApiContent,
|
|
49
|
+
},
|
|
50
|
+
{
|
|
51
|
+
name: 'web',
|
|
52
|
+
srcFolder: 'web',
|
|
53
|
+
generate: generateWebPrompt,
|
|
54
|
+
getContent: getWebContent,
|
|
55
|
+
},
|
|
56
|
+
];
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Generate the reference file content that points to .agents/
|
|
60
|
+
*/
|
|
61
|
+
function generateReferenceContent(name: string): string {
|
|
62
|
+
return `See [.agents/agentuity/sdk/${name}/AGENTS.md](../../.agents/agentuity/sdk/${name}/AGENTS.md) for Agentuity ${name} development guidelines.
|
|
63
|
+
`;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Generate or update prompt files.
|
|
68
|
+
*
|
|
69
|
+
* - .agents/agentuity/sdk/[type]/AGENTS.md: Full content, updated when hash differs
|
|
70
|
+
* - src/[type]/AGENTS.md: Reference file, only created if missing
|
|
71
|
+
*
|
|
72
|
+
* @param srcDir - The src/ directory path
|
|
73
|
+
* @param logger - Logger for output
|
|
74
|
+
*/
|
|
75
|
+
export async function generatePromptFiles(srcDir: string, logger: Logger): Promise<void> {
|
|
76
|
+
const projectRoot = dirname(srcDir);
|
|
77
|
+
|
|
78
|
+
for (const prompt of PROMPTS) {
|
|
79
|
+
await generatePromptFile(projectRoot, srcDir, prompt, logger);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async function generatePromptFile(
|
|
84
|
+
projectRoot: string,
|
|
85
|
+
srcDir: string,
|
|
86
|
+
config: PromptConfig,
|
|
87
|
+
logger: Logger
|
|
88
|
+
): Promise<void> {
|
|
89
|
+
const srcFolderPath = join(srcDir, config.srcFolder);
|
|
90
|
+
|
|
91
|
+
// Check if the src folder exists (e.g., src/agent/)
|
|
92
|
+
try {
|
|
93
|
+
const stat = await Bun.$`test -d ${srcFolderPath}`.nothrow();
|
|
94
|
+
if (stat.exitCode !== 0) {
|
|
95
|
+
logger.trace(`Skipping ${config.name} prompt - src/${config.srcFolder}/ does not exist`);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
} catch {
|
|
99
|
+
logger.trace(`Skipping ${config.name} prompt - src/${config.srcFolder}/ does not exist`);
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
// Generate files
|
|
104
|
+
await generateAgentsFile(projectRoot, config, logger);
|
|
105
|
+
await generateReferenceFile(srcFolderPath, config, logger);
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Generate/update the .agents/agentuity/sdk/[type]/AGENTS.md file.
|
|
110
|
+
* Overwrites if hash differs from source template.
|
|
111
|
+
*/
|
|
112
|
+
async function generateAgentsFile(
|
|
113
|
+
projectRoot: string,
|
|
114
|
+
config: PromptConfig,
|
|
115
|
+
logger: Logger
|
|
116
|
+
): Promise<void> {
|
|
117
|
+
const agentsDir = join(projectRoot, '.agents', 'agentuity', 'sdk', config.name);
|
|
118
|
+
const filePath = join(agentsDir, 'AGENTS.md');
|
|
119
|
+
|
|
120
|
+
const file = Bun.file(filePath);
|
|
121
|
+
const fileExists = await file.exists();
|
|
122
|
+
|
|
123
|
+
if (!fileExists) {
|
|
124
|
+
// File doesn't exist - create it
|
|
125
|
+
await mkdir(agentsDir, { recursive: true });
|
|
126
|
+
const content = config.generate();
|
|
127
|
+
await Bun.write(filePath, content);
|
|
128
|
+
logger.debug(`Generated .agents/agentuity/sdk/${config.name}/AGENTS.md`);
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// File exists - check if it needs to be updated
|
|
133
|
+
const existingContent = await file.text();
|
|
134
|
+
const sourceContent = config.getContent();
|
|
135
|
+
|
|
136
|
+
if (needsUpdate(existingContent, sourceContent)) {
|
|
137
|
+
const content = config.generate();
|
|
138
|
+
await Bun.write(filePath, content);
|
|
139
|
+
logger.debug(`Updated .agents/agentuity/sdk/${config.name}/AGENTS.md`);
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
logger.trace(`Skipping ${config.name} prompt - already up to date`);
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Generate the src/[type]/AGENTS.md reference file.
|
|
148
|
+
* Only creates if missing (write-once).
|
|
149
|
+
*/
|
|
150
|
+
async function generateReferenceFile(
|
|
151
|
+
srcFolderPath: string,
|
|
152
|
+
config: PromptConfig,
|
|
153
|
+
logger: Logger
|
|
154
|
+
): Promise<void> {
|
|
155
|
+
const filePath = join(srcFolderPath, 'AGENTS.md');
|
|
156
|
+
|
|
157
|
+
const file = Bun.file(filePath);
|
|
158
|
+
const fileExists = await file.exists();
|
|
159
|
+
|
|
160
|
+
if (fileExists) {
|
|
161
|
+
logger.trace(`Skipping src/${config.srcFolder}/AGENTS.md - already exists`);
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Create the reference file
|
|
166
|
+
const content = generateReferenceContent(config.name);
|
|
167
|
+
await Bun.write(filePath, content);
|
|
168
|
+
logger.debug(`Generated src/${config.srcFolder}/AGENTS.md (reference)`);
|
|
169
|
+
}
|
|
@@ -13,6 +13,22 @@ import type { RouteInfo } from './route-discovery';
|
|
|
13
13
|
|
|
14
14
|
const AgentIdentifierCollisionError = StructuredError('AgentIdentifierCollisionError');
|
|
15
15
|
|
|
16
|
+
/**
|
|
17
|
+
* Regex to strip route parameter characters that produce invalid TypeScript property names:
|
|
18
|
+
* - Leading : (path parameters, e.g., :id)
|
|
19
|
+
* - Leading * (wildcard routes, e.g., *path)
|
|
20
|
+
* - Trailing ?, +, * (optional/one-or-more/wildcard modifiers, e.g., :userId?)
|
|
21
|
+
*/
|
|
22
|
+
const ROUTE_PARAM_CHARS = /^[:*]|[?+*]$/g;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Sanitize a route path segment for use as a TypeScript property name.
|
|
26
|
+
* Strips route parameter characters and converts to camelCase.
|
|
27
|
+
*/
|
|
28
|
+
function sanitizePathSegment(segment: string): string {
|
|
29
|
+
return toCamelCase(segment.replace(ROUTE_PARAM_CHARS, ''));
|
|
30
|
+
}
|
|
31
|
+
|
|
16
32
|
/**
|
|
17
33
|
* Generate src/generated/registry.ts with agent registry and types
|
|
18
34
|
*/
|
|
@@ -244,9 +260,9 @@ function generateRPCRegistryType(
|
|
|
244
260
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
245
261
|
let current: any = tree;
|
|
246
262
|
|
|
247
|
-
// Add path segments
|
|
263
|
+
// Add path segments - sanitize for valid TypeScript property names
|
|
248
264
|
for (let i = 0; i < pathParts.length; i++) {
|
|
249
|
-
const part =
|
|
265
|
+
const part = sanitizePathSegment(pathParts[i]);
|
|
250
266
|
if (!current[part]) {
|
|
251
267
|
current[part] = {};
|
|
252
268
|
}
|
|
@@ -382,11 +398,11 @@ function generateRPCRuntimeMetadata(
|
|
|
382
398
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
383
399
|
let current: any = tree;
|
|
384
400
|
|
|
385
|
-
//
|
|
401
|
+
// Sanitize path segments for valid property names (must match type generation)
|
|
386
402
|
for (const part of pathParts) {
|
|
387
|
-
const
|
|
388
|
-
if (!current[
|
|
389
|
-
current = current[
|
|
403
|
+
const sanitized = sanitizePathSegment(part);
|
|
404
|
+
if (!current[sanitized]) current[sanitized] = {};
|
|
405
|
+
current = current[sanitized];
|
|
390
406
|
}
|
|
391
407
|
|
|
392
408
|
// Use terminal method name based on route type
|
|
@@ -478,7 +494,7 @@ export function generateRouteRegistry(
|
|
|
478
494
|
// Collect agent and schema imports from routes with validators or exported schemas
|
|
479
495
|
allRoutes.forEach((route) => {
|
|
480
496
|
const hasSchemaVars = !!route.inputSchemaVariable || !!route.outputSchemaVariable;
|
|
481
|
-
if (!route.hasValidator && !hasSchemaVars) return;
|
|
497
|
+
if (!route.hasValidator && !hasSchemaVars && !route.agentVariable) return;
|
|
482
498
|
|
|
483
499
|
// Collect agent imports (when using agent.validator())
|
|
484
500
|
if (
|
|
@@ -592,7 +608,7 @@ export function generateRouteRegistry(
|
|
|
592
608
|
|
|
593
609
|
// Add InferInput/InferOutput imports if we have any routes with schemas
|
|
594
610
|
const hasSchemas = allRoutes.some(
|
|
595
|
-
(r) => r.hasValidator || r.inputSchemaVariable || r.outputSchemaVariable
|
|
611
|
+
(r) => r.hasValidator || r.inputSchemaVariable || r.outputSchemaVariable || r.agentVariable
|
|
596
612
|
);
|
|
597
613
|
const typeImports = hasSchemas
|
|
598
614
|
? `import type { InferInput, InferOutput } from '@agentuity/core';\n`
|
|
@@ -600,7 +616,9 @@ export function generateRouteRegistry(
|
|
|
600
616
|
|
|
601
617
|
// Generate individual route schema types
|
|
602
618
|
const routeSchemaTypes = allRoutes
|
|
603
|
-
.filter(
|
|
619
|
+
.filter(
|
|
620
|
+
(r) => r.hasValidator || r.inputSchemaVariable || r.outputSchemaVariable || r.agentVariable
|
|
621
|
+
)
|
|
604
622
|
.map((route) => {
|
|
605
623
|
const routeKey = route.method ? `${route.method.toUpperCase()} ${route.path}` : route.path;
|
|
606
624
|
const safeName = routeKey
|
|
@@ -707,7 +725,12 @@ export function generateRouteRegistry(
|
|
|
707
725
|
.replace(/_+/g, '_');
|
|
708
726
|
const pascalName = toPascalCase(safeName);
|
|
709
727
|
|
|
710
|
-
if (
|
|
728
|
+
if (
|
|
729
|
+
!route.hasValidator &&
|
|
730
|
+
!route.inputSchemaVariable &&
|
|
731
|
+
!route.outputSchemaVariable &&
|
|
732
|
+
!route.agentVariable
|
|
733
|
+
) {
|
|
711
734
|
const streamValue = route.stream === true ? 'true' : 'false';
|
|
712
735
|
return `\t'${routeKey}': {
|
|
713
736
|
\t\tinputSchema: never;
|
|
@@ -9,6 +9,37 @@ import type { Logger } from '../../../types';
|
|
|
9
9
|
import type { BunPlugin } from 'bun';
|
|
10
10
|
import { generatePatches, applyPatch } from '../patch';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* Format a Bun build log (BuildMessage or ResolveMessage) into a readable string
|
|
14
|
+
*/
|
|
15
|
+
export function formatBuildLog(log: BuildMessage | ResolveMessage): string {
|
|
16
|
+
const parts: string[] = [];
|
|
17
|
+
|
|
18
|
+
// For ResolveMessage, format with specifier info
|
|
19
|
+
if (log.name === 'ResolveMessage') {
|
|
20
|
+
const resolveLog = log as ResolveMessage;
|
|
21
|
+
if (resolveLog.specifier) {
|
|
22
|
+
parts.push(`Could not resolve "${resolveLog.specifier}"`);
|
|
23
|
+
// Use referrer if available, otherwise fall back to position.file
|
|
24
|
+
const referrer = resolveLog.referrer || resolveLog.position?.file;
|
|
25
|
+
if (referrer) {
|
|
26
|
+
parts.push(` imported from: ${referrer}`);
|
|
27
|
+
}
|
|
28
|
+
} else if (resolveLog.message) {
|
|
29
|
+
parts.push(resolveLog.message);
|
|
30
|
+
}
|
|
31
|
+
} else if (log.message) {
|
|
32
|
+
parts.push(log.message);
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// Add position info if available (only if we haven't already shown referrer from position)
|
|
36
|
+
if (log.position && log.name !== 'ResolveMessage') {
|
|
37
|
+
parts.push(` at ${log.position.file}:${log.position.line}:${log.position.column}`);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
return parts.join('\n');
|
|
41
|
+
}
|
|
42
|
+
|
|
12
43
|
export interface ServerBundleOptions {
|
|
13
44
|
rootDir: string;
|
|
14
45
|
dev: boolean;
|
|
@@ -282,19 +313,29 @@ export async function installExternalsAndBuild(options: ServerBundleOptions): Pr
|
|
|
282
313
|
if (originalNodeEnv !== undefined) {
|
|
283
314
|
process.env.NODE_ENV = originalNodeEnv;
|
|
284
315
|
}
|
|
285
|
-
logger.error('Bun.build threw an exception');
|
|
286
316
|
|
|
287
317
|
// Handle AggregateError with build/resolve messages
|
|
288
318
|
if (error instanceof AggregateError && error.errors) {
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
319
|
+
const formattedErrors = error.errors
|
|
320
|
+
.map((err) => {
|
|
321
|
+
// Try to use formatBuildLog if it looks like a BuildMessage/ResolveMessage
|
|
322
|
+
if (err && typeof err === 'object' && 'name' in err) {
|
|
323
|
+
const formatted = formatBuildLog(err as BuildMessage | ResolveMessage);
|
|
324
|
+
if (formatted) return formatted;
|
|
325
|
+
}
|
|
326
|
+
// Fallback for other error types
|
|
327
|
+
const parts = [err.message || err.text || 'Unknown error'];
|
|
328
|
+
if (err.position) {
|
|
329
|
+
parts.push(
|
|
330
|
+
` at ${err.position.file}:${err.position.line}:${err.position.column}`
|
|
331
|
+
);
|
|
332
|
+
}
|
|
333
|
+
return parts.join('\n');
|
|
334
|
+
})
|
|
335
|
+
.filter(Boolean)
|
|
336
|
+
.join('\n');
|
|
337
|
+
|
|
338
|
+
throw new Error(formattedErrors || 'Build failed');
|
|
298
339
|
}
|
|
299
340
|
|
|
300
341
|
throw error;
|
|
@@ -306,19 +347,9 @@ export async function installExternalsAndBuild(options: ServerBundleOptions): Pr
|
|
|
306
347
|
}
|
|
307
348
|
|
|
308
349
|
if (!result.success) {
|
|
309
|
-
logger.error('Bun.build failed for server');
|
|
310
|
-
logger.error(
|
|
311
|
-
`Build result: success=${result.success}, outputs=${result.outputs.length}, logs=${result.logs.length}`
|
|
312
|
-
);
|
|
313
|
-
|
|
314
350
|
const errorMessages = result.logs
|
|
315
|
-
.map((log) =>
|
|
316
|
-
|
|
317
|
-
if (log.position) {
|
|
318
|
-
parts.push(` at ${log.position.file}:${log.position.line}:${log.position.column}`);
|
|
319
|
-
}
|
|
320
|
-
return parts.join('\n');
|
|
321
|
-
})
|
|
351
|
+
.map((log) => formatBuildLog(log))
|
|
352
|
+
.filter(Boolean)
|
|
322
353
|
.join('\n');
|
|
323
354
|
|
|
324
355
|
throw new Error(errorMessages || 'Build failed with no error messages');
|
|
@@ -69,6 +69,11 @@ export async function generateAssetServerConfig(
|
|
|
69
69
|
dedupe: ['react', 'react-dom', 'react/jsx-runtime', 'react/jsx-dev-runtime'],
|
|
70
70
|
},
|
|
71
71
|
|
|
72
|
+
// Pre-bundle @agentuity/workbench to avoid React preamble issues with pre-built JSX
|
|
73
|
+
optimizeDeps: {
|
|
74
|
+
include: ['@agentuity/workbench', '@agentuity/core', '@agentuity/react'],
|
|
75
|
+
},
|
|
76
|
+
|
|
72
77
|
// Only allow frontend env vars (server uses process.env)
|
|
73
78
|
envPrefix: ['VITE_', 'AGENTUITY_PUBLIC_', 'PUBLIC_'],
|
|
74
79
|
|