@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
|
@@ -306,7 +306,8 @@ function extractAgentMetadata(
|
|
|
306
306
|
}
|
|
307
307
|
|
|
308
308
|
/**
|
|
309
|
-
* Extract evals from
|
|
309
|
+
* Extract evals from a file (READ-ONLY)
|
|
310
|
+
* Finds createEval calls regardless of whether they're exported or not
|
|
310
311
|
*/
|
|
311
312
|
async function extractEvalMetadata(
|
|
312
313
|
evalsPath: string,
|
|
@@ -322,72 +323,135 @@ async function extractEvalMetadata(
|
|
|
322
323
|
|
|
323
324
|
try {
|
|
324
325
|
const evalsSource = await evalsFile.text();
|
|
326
|
+
return extractEvalsFromSource(
|
|
327
|
+
evalsSource,
|
|
328
|
+
evalsPath,
|
|
329
|
+
agentId,
|
|
330
|
+
projectId,
|
|
331
|
+
deploymentId,
|
|
332
|
+
logger
|
|
333
|
+
);
|
|
334
|
+
} catch (error) {
|
|
335
|
+
logger.warn(`Failed to parse evals from ${evalsPath}: ${error}`);
|
|
336
|
+
return [];
|
|
337
|
+
}
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
/**
|
|
341
|
+
* Extract evals from source code (READ-ONLY)
|
|
342
|
+
* Finds all createEval calls in the source, exported or not
|
|
343
|
+
*/
|
|
344
|
+
function extractEvalsFromSource(
|
|
345
|
+
source: string,
|
|
346
|
+
filename: string,
|
|
347
|
+
agentId: string,
|
|
348
|
+
projectId: string,
|
|
349
|
+
deploymentId: string,
|
|
350
|
+
logger: Logger
|
|
351
|
+
): EvalMetadata[] {
|
|
352
|
+
// Quick check - skip if no createEval in source
|
|
353
|
+
if (!source.includes('createEval')) {
|
|
354
|
+
return [];
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
try {
|
|
325
358
|
const transpiler = new Bun.Transpiler({ loader: 'ts', target: 'bun' });
|
|
326
|
-
const
|
|
327
|
-
const version = hash(
|
|
359
|
+
const contents = transpiler.transformSync(source);
|
|
360
|
+
const version = hash(contents);
|
|
328
361
|
|
|
329
|
-
const ast = acornLoose.parse(
|
|
362
|
+
const ast = acornLoose.parse(contents, { ecmaVersion: 'latest', sourceType: 'module' });
|
|
330
363
|
const evals: EvalMetadata[] = [];
|
|
331
364
|
|
|
332
|
-
//
|
|
333
|
-
|
|
334
|
-
if (node
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
365
|
+
// Recursively find all createEval calls in the AST
|
|
366
|
+
function findCreateEvalCalls(node: unknown): void {
|
|
367
|
+
if (!node || typeof node !== 'object') return;
|
|
368
|
+
|
|
369
|
+
const n = node as Record<string, unknown>;
|
|
370
|
+
|
|
371
|
+
// Check if this is a createEval call (either direct or method call)
|
|
372
|
+
// Direct: createEval('name', {...})
|
|
373
|
+
// Method: agent.createEval('name', {...})
|
|
374
|
+
let isCreateEvalCall = false;
|
|
375
|
+
|
|
376
|
+
if (n.type === 'CallExpression' && n.callee && typeof n.callee === 'object') {
|
|
377
|
+
const callee = n.callee as ASTNode & { property?: ASTNodeIdentifier };
|
|
378
|
+
|
|
379
|
+
// Direct function call: createEval(...)
|
|
380
|
+
if (
|
|
381
|
+
callee.type === 'Identifier' &&
|
|
382
|
+
(callee as ASTNodeIdentifier).name === 'createEval'
|
|
383
|
+
) {
|
|
384
|
+
isCreateEvalCall = true;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
// Method call: someAgent.createEval(...)
|
|
388
|
+
if (
|
|
389
|
+
callee.type === 'MemberExpression' &&
|
|
390
|
+
callee.property &&
|
|
391
|
+
callee.property.type === 'Identifier' &&
|
|
392
|
+
callee.property.name === 'createEval'
|
|
393
|
+
) {
|
|
394
|
+
isCreateEvalCall = true;
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
if (isCreateEvalCall) {
|
|
399
|
+
const callExpr = n as unknown as ASTCallExpression;
|
|
400
|
+
if (callExpr.arguments.length >= 2) {
|
|
401
|
+
const nameArg = callExpr.arguments[0] as ASTLiteral;
|
|
402
|
+
const evalName = String(nameArg.value);
|
|
367
403
|
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
projectId,
|
|
380
|
-
});
|
|
404
|
+
const callargexp = callExpr.arguments[1] as ASTObjectExpression;
|
|
405
|
+
let description: string | undefined;
|
|
406
|
+
|
|
407
|
+
if (callargexp.properties) {
|
|
408
|
+
for (const prop of callargexp.properties) {
|
|
409
|
+
if (prop.key.name === 'metadata' && prop.value.type === 'ObjectExpression') {
|
|
410
|
+
const metadataMap = parseObjectExpressionToMap(
|
|
411
|
+
prop.value as ASTObjectExpression
|
|
412
|
+
);
|
|
413
|
+
description = metadataMap.get('description');
|
|
414
|
+
break;
|
|
381
415
|
}
|
|
382
416
|
}
|
|
383
417
|
}
|
|
418
|
+
|
|
419
|
+
const id = getEvalId(projectId, deploymentId, filename, evalName, version);
|
|
420
|
+
const evalId = generateStableEvalId(projectId, agentId, evalName);
|
|
421
|
+
|
|
422
|
+
logger.trace(`Found eval '${evalName}' in ${filename} (evalId: ${evalId})`);
|
|
423
|
+
|
|
424
|
+
evals.push({
|
|
425
|
+
id,
|
|
426
|
+
evalId,
|
|
427
|
+
name: evalName,
|
|
428
|
+
filename,
|
|
429
|
+
version,
|
|
430
|
+
description,
|
|
431
|
+
agentIdentifier: agentId,
|
|
432
|
+
projectId,
|
|
433
|
+
});
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
|
|
437
|
+
// Recursively search child nodes
|
|
438
|
+
for (const key of Object.keys(n)) {
|
|
439
|
+
const value = n[key];
|
|
440
|
+
if (Array.isArray(value)) {
|
|
441
|
+
for (const item of value) {
|
|
442
|
+
findCreateEvalCalls(item);
|
|
443
|
+
}
|
|
444
|
+
} else if (value && typeof value === 'object') {
|
|
445
|
+
findCreateEvalCalls(value);
|
|
384
446
|
}
|
|
385
447
|
}
|
|
386
448
|
}
|
|
387
449
|
|
|
450
|
+
findCreateEvalCalls(ast);
|
|
451
|
+
|
|
388
452
|
return evals;
|
|
389
453
|
} catch (error) {
|
|
390
|
-
logger.warn(`Failed to parse evals from ${
|
|
454
|
+
logger.warn(`Failed to parse evals from ${filename}: ${error}`);
|
|
391
455
|
return [];
|
|
392
456
|
}
|
|
393
457
|
}
|
|
@@ -439,20 +503,49 @@ export async function discoverAgents(
|
|
|
439
503
|
if (agentMetadata) {
|
|
440
504
|
logger.trace('Discovered agent: %s at %s', agentMetadata.name, relativeFilename);
|
|
441
505
|
|
|
442
|
-
//
|
|
506
|
+
// Collect evals from multiple sources
|
|
507
|
+
const allEvals: EvalMetadata[] = [];
|
|
508
|
+
|
|
509
|
+
// 1. Extract evals from the agent file itself (agent.createEval() pattern)
|
|
510
|
+
const evalsInAgentFile = extractEvalsFromSource(
|
|
511
|
+
source,
|
|
512
|
+
relativeFilename,
|
|
513
|
+
agentMetadata.agentId,
|
|
514
|
+
projectId,
|
|
515
|
+
deploymentId,
|
|
516
|
+
logger
|
|
517
|
+
);
|
|
518
|
+
if (evalsInAgentFile.length > 0) {
|
|
519
|
+
logger.trace(
|
|
520
|
+
'Found %d eval(s) in agent file for %s',
|
|
521
|
+
evalsInAgentFile.length,
|
|
522
|
+
agentMetadata.name
|
|
523
|
+
);
|
|
524
|
+
allEvals.push(...evalsInAgentFile);
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// 2. Check for evals in separate eval.ts file in same directory
|
|
443
528
|
const agentDir = dirname(filePath);
|
|
444
529
|
const evalsPath = join(agentDir, 'eval.ts');
|
|
445
|
-
const
|
|
530
|
+
const evalsInSeparateFile = await extractEvalMetadata(
|
|
446
531
|
evalsPath,
|
|
447
532
|
agentMetadata.agentId,
|
|
448
533
|
projectId,
|
|
449
534
|
deploymentId,
|
|
450
535
|
logger
|
|
451
536
|
);
|
|
537
|
+
if (evalsInSeparateFile.length > 0) {
|
|
538
|
+
logger.trace(
|
|
539
|
+
'Found %d eval(s) in eval.ts for agent %s',
|
|
540
|
+
evalsInSeparateFile.length,
|
|
541
|
+
agentMetadata.name
|
|
542
|
+
);
|
|
543
|
+
allEvals.push(...evalsInSeparateFile);
|
|
544
|
+
}
|
|
452
545
|
|
|
453
|
-
if (
|
|
454
|
-
agentMetadata.evals =
|
|
455
|
-
logger.trace('
|
|
546
|
+
if (allEvals.length > 0) {
|
|
547
|
+
agentMetadata.evals = allEvals;
|
|
548
|
+
logger.trace('Total %d eval(s) for agent %s', allEvals.length, agentMetadata.name);
|
|
456
549
|
}
|
|
457
550
|
|
|
458
551
|
agents.push(agentMetadata);
|
|
@@ -56,7 +56,7 @@ export async function startBunDevServer(options: BunDevServerOptions): Promise<B
|
|
|
56
56
|
|
|
57
57
|
// Step 3: Load the generated app - this will start Bun.serve() internally
|
|
58
58
|
logger.debug('📦 Loading generated app (Bun server will start)...');
|
|
59
|
-
const appPath = `${rootDir}
|
|
59
|
+
const appPath = `${rootDir}/src/generated/app.ts`;
|
|
60
60
|
|
|
61
61
|
// Set PORT env var so the generated app uses the correct port
|
|
62
62
|
process.env.PORT = String(port);
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Documentation Generator
|
|
3
|
+
*
|
|
4
|
+
* Generates README.md and AGENTS.md in src/generated/ directory
|
|
5
|
+
* Only writes files if they don't already exist (preserves user modifications)
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { join } from 'node:path';
|
|
9
|
+
import { mkdir } from 'node:fs/promises';
|
|
10
|
+
import type { Logger } from '../../../types';
|
|
11
|
+
|
|
12
|
+
const README_CONTENT = `# Generated Files - DO NOT EDIT
|
|
13
|
+
|
|
14
|
+
This directory contains auto-generated TypeScript files created by the Agentuity build system.
|
|
15
|
+
|
|
16
|
+
**These files are regenerated on every build.** Any manual changes will be overwritten.
|
|
17
|
+
|
|
18
|
+
## Generated Files
|
|
19
|
+
|
|
20
|
+
- \`registry.ts\` - Agent registry from \`src/agent/**\`
|
|
21
|
+
- \`routes.ts\` - Route registry from \`src/api/**\`
|
|
22
|
+
- \`app.ts\` - Application entry point
|
|
23
|
+
- \`state.ts\` - App state types (when setup() exists)
|
|
24
|
+
- \`router.ts\` - Runtime wrapper (when setup() exists)
|
|
25
|
+
|
|
26
|
+
## For Developers
|
|
27
|
+
|
|
28
|
+
Do not modify these files. Instead:
|
|
29
|
+
- Add/modify agents in \`src/agent/\`
|
|
30
|
+
- Add/modify routes in \`src/api/\`
|
|
31
|
+
- Configure app in \`app.ts\`
|
|
32
|
+
|
|
33
|
+
These files ARE version controlled to enable better tooling and type checking.
|
|
34
|
+
`;
|
|
35
|
+
|
|
36
|
+
const AGENTS_MD_CONTENT = `# AI Agent Instructions
|
|
37
|
+
|
|
38
|
+
**CRITICAL:** Files in this directory are AUTO-GENERATED by the Agentuity build system.
|
|
39
|
+
|
|
40
|
+
## Rules for AI Agents
|
|
41
|
+
|
|
42
|
+
1. ❌ NEVER edit files in \`src/generated/\`
|
|
43
|
+
2. ❌ NEVER include \`src/generated/\` files in context when analyzing code
|
|
44
|
+
3. ❌ NEVER suggest changes to generated files
|
|
45
|
+
4. ✅ Ignore this directory when searching for user code
|
|
46
|
+
5. ✅ Direct users to modify source files in \`src/agent/\`, \`src/api/\`, or \`app.ts\`
|
|
47
|
+
|
|
48
|
+
## What Gets Generated
|
|
49
|
+
|
|
50
|
+
- \`registry.ts\` - Built from agent discovery in \`src/agent/\`
|
|
51
|
+
- \`routes.ts\` - Built from route discovery in \`src/api/\`
|
|
52
|
+
- \`app.ts\` - Entry point assembled from project configuration
|
|
53
|
+
- \`state.ts\` - App state type from \`setup()\` return value
|
|
54
|
+
- \`router.ts\` - Runtime wrapper with type augmentation
|
|
55
|
+
|
|
56
|
+
These files are regenerated on every \`bun run build\` or \`bun run dev\`.
|
|
57
|
+
`;
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Generate documentation files in src/generated/ directory
|
|
61
|
+
* Only creates files if they don't already exist
|
|
62
|
+
*/
|
|
63
|
+
export async function generateDocumentation(srcDir: string, logger: Logger): Promise<void> {
|
|
64
|
+
const generatedDir = join(srcDir, 'generated');
|
|
65
|
+
|
|
66
|
+
// Ensure directory exists
|
|
67
|
+
await mkdir(generatedDir, { recursive: true });
|
|
68
|
+
|
|
69
|
+
const readmePath = join(generatedDir, 'README.md');
|
|
70
|
+
const agentsMdPath = join(generatedDir, 'AGENTS.md');
|
|
71
|
+
|
|
72
|
+
// Generate README.md if it doesn't exist
|
|
73
|
+
if (!(await Bun.file(readmePath).exists())) {
|
|
74
|
+
await Bun.write(readmePath, README_CONTENT);
|
|
75
|
+
logger.debug('Generated src/generated/README.md');
|
|
76
|
+
} else {
|
|
77
|
+
logger.trace('Skipping README.md - file already exists');
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
// Generate AGENTS.md if it doesn't exist
|
|
81
|
+
if (!(await Bun.file(agentsMdPath).exists())) {
|
|
82
|
+
await Bun.write(agentsMdPath, AGENTS_MD_CONTENT);
|
|
83
|
+
logger.debug('Generated src/generated/AGENTS.md');
|
|
84
|
+
} else {
|
|
85
|
+
logger.trace('Skipping AGENTS.md - file already exists');
|
|
86
|
+
}
|
|
87
|
+
}
|
|
@@ -11,7 +11,6 @@ import { generateEntryFile } from '../entry-generator';
|
|
|
11
11
|
import { loadAgentuityConfig, getWorkbenchConfig } from './config-loader';
|
|
12
12
|
|
|
13
13
|
// Re-export plugins
|
|
14
|
-
export { patchPlugin } from './patch-plugin';
|
|
15
14
|
export { browserEnvPlugin } from './browser-env-plugin';
|
|
16
15
|
|
|
17
16
|
export interface AgentuityPluginOptions {
|
|
@@ -29,9 +28,9 @@ export interface AgentuityPluginOptions {
|
|
|
29
28
|
* Responsibilities:
|
|
30
29
|
* - Agent discovery via READ-ONLY AST analysis
|
|
31
30
|
* - Route discovery via READ-ONLY AST analysis
|
|
32
|
-
* - Registry generation (
|
|
33
|
-
* - Lifecycle types generation (
|
|
34
|
-
* - Entry file generation (
|
|
31
|
+
* - Registry generation (src/generated/registry.ts)
|
|
32
|
+
* - Lifecycle types generation (src/generated/lifecycle.d.ts)
|
|
33
|
+
* - Entry file generation (src/generated/app.ts)
|
|
35
34
|
* - Virtual modules (virtual:agentuity/agents, virtual:agentuity/routes)
|
|
36
35
|
* - Metadata generation (agentuity.metadata.json)
|
|
37
36
|
*/
|
|
@@ -86,12 +85,14 @@ export function agentuityPlugin(options: AgentuityPluginOptions): Plugin {
|
|
|
86
85
|
}
|
|
87
86
|
|
|
88
87
|
if (routeInfoList.length > 0) {
|
|
89
|
-
generateRouteRegistry(srcDir, routeInfoList);
|
|
88
|
+
generateRouteRegistry(srcDir, routeInfoList, agents);
|
|
90
89
|
logger.trace('Generated route registry with %d route(s)', routeInfoList.length);
|
|
91
90
|
}
|
|
92
91
|
|
|
93
92
|
// Generate lifecycle types
|
|
94
|
-
|
|
93
|
+
logger.debug('[vite-plugin] About to call generateLifecycleTypes');
|
|
94
|
+
const lifecycleResult = await generateLifecycleTypes(rootDir, srcDir, logger);
|
|
95
|
+
logger.debug(`[vite-plugin] generateLifecycleTypes returned: ${lifecycleResult}`);
|
|
95
96
|
|
|
96
97
|
// Generate entry file (pass workbench config for route mounting)
|
|
97
98
|
await generateEntryFile({
|
|
@@ -127,11 +128,11 @@ export function agentuityPlugin(options: AgentuityPluginOptions): Plugin {
|
|
|
127
128
|
load(id) {
|
|
128
129
|
if (id === '\0virtual:agentuity/agents') {
|
|
129
130
|
// Re-export from generated registry
|
|
130
|
-
return `export { agentRegistry } from '
|
|
131
|
+
return `export { agentRegistry } from '../src/generated/registry.js';`;
|
|
131
132
|
}
|
|
132
133
|
if (id === '\0virtual:agentuity/routes') {
|
|
133
134
|
// Re-export from generated route registry
|
|
134
|
-
return `export { routeRegistry } from '
|
|
135
|
+
return `export { routeRegistry } from '../src/generated/routes.js';`;
|
|
135
136
|
}
|
|
136
137
|
return null;
|
|
137
138
|
},
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Lifecycle Types Generator
|
|
3
3
|
*
|
|
4
|
-
* Generates
|
|
4
|
+
* Generates src/generated/lifecycle.d.ts by analyzing app.ts for setup() function
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { join } from 'node:path';
|
|
@@ -16,7 +16,12 @@ export async function generateLifecycleTypes(
|
|
|
16
16
|
srcDir: string,
|
|
17
17
|
logger: Logger
|
|
18
18
|
): Promise<boolean> {
|
|
19
|
-
|
|
19
|
+
logger.debug('[lifecycle] Starting lifecycle type generation...');
|
|
20
|
+
logger.debug(`[lifecycle] rootDir: ${rootDir}`);
|
|
21
|
+
logger.debug(`[lifecycle] srcDir: ${srcDir}`);
|
|
22
|
+
|
|
23
|
+
const outDir = join(srcDir, 'generated');
|
|
24
|
+
logger.debug(`[lifecycle] outDir: ${outDir}`);
|
|
20
25
|
|
|
21
26
|
// Look for app.ts in both root and src directories
|
|
22
27
|
const rootAppFile = join(rootDir, 'app.ts');
|
|
@@ -25,19 +30,28 @@ export async function generateLifecycleTypes(
|
|
|
25
30
|
let appFile = '';
|
|
26
31
|
if (await Bun.file(rootAppFile).exists()) {
|
|
27
32
|
appFile = rootAppFile;
|
|
33
|
+
logger.debug(`[lifecycle] Found app.ts at root: ${rootAppFile}`);
|
|
28
34
|
} else if (await Bun.file(srcAppFile).exists()) {
|
|
29
35
|
appFile = srcAppFile;
|
|
36
|
+
logger.debug(`[lifecycle] Found app.ts in src: ${srcAppFile}`);
|
|
30
37
|
}
|
|
31
38
|
|
|
32
39
|
if (!appFile || !(await Bun.file(appFile).exists())) {
|
|
33
|
-
logger.
|
|
40
|
+
logger.debug('[lifecycle] No app.ts found for lifecycle types generation');
|
|
34
41
|
return false;
|
|
35
42
|
}
|
|
36
43
|
|
|
37
44
|
try {
|
|
38
|
-
|
|
45
|
+
logger.debug(`[lifecycle] Calling generateLifecycleTypesFromAST...`);
|
|
46
|
+
const result = await generateLifecycleTypesFromAST(rootDir, outDir, appFile);
|
|
47
|
+
if (result) {
|
|
48
|
+
logger.debug(`[lifecycle] Lifecycle types generated successfully in ${outDir}`);
|
|
49
|
+
} else {
|
|
50
|
+
logger.debug('[lifecycle] generateLifecycleTypesFromAST returned false (no setup found)');
|
|
51
|
+
}
|
|
52
|
+
return result;
|
|
39
53
|
} catch (error) {
|
|
40
|
-
logger.error('Failed to generate lifecycle types:', error);
|
|
54
|
+
logger.error('[lifecycle] Failed to generate lifecycle types:', error);
|
|
41
55
|
return false;
|
|
42
56
|
}
|
|
43
57
|
}
|
|
@@ -548,6 +548,175 @@ async function getGitInfo(
|
|
|
548
548
|
}
|
|
549
549
|
}
|
|
550
550
|
|
|
551
|
+
/**
|
|
552
|
+
* Generate AGENTS.md content for AI coding agents
|
|
553
|
+
*/
|
|
554
|
+
function generateAgentsMd(metadata: BuildMetadata): string {
|
|
555
|
+
const lines: string[] = [];
|
|
556
|
+
|
|
557
|
+
lines.push('# Compiled Agentuity Application');
|
|
558
|
+
lines.push('');
|
|
559
|
+
lines.push(
|
|
560
|
+
'This directory contains compiled and bundled source code from an Agentuity application.'
|
|
561
|
+
);
|
|
562
|
+
lines.push('');
|
|
563
|
+
|
|
564
|
+
// Add source repository info if available
|
|
565
|
+
if (metadata.deployment?.git?.repo) {
|
|
566
|
+
lines.push('## Source Repository');
|
|
567
|
+
lines.push('');
|
|
568
|
+
lines.push(`**Repository:** ${metadata.deployment.git.repo}`);
|
|
569
|
+
|
|
570
|
+
if (metadata.deployment.git.branch) {
|
|
571
|
+
lines.push(`**Branch:** ${metadata.deployment.git.branch}`);
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
if (metadata.deployment.git.commit) {
|
|
575
|
+
const shortCommit = metadata.deployment.git.commit.substring(0, 7);
|
|
576
|
+
const commitUrl = metadata.deployment.git.repo.endsWith('.git')
|
|
577
|
+
? metadata.deployment.git.repo.slice(0, -4)
|
|
578
|
+
: metadata.deployment.git.repo;
|
|
579
|
+
lines.push(
|
|
580
|
+
`**Commit:** [\`${shortCommit}\`](${commitUrl}/commit/${metadata.deployment.git.commit})`
|
|
581
|
+
);
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
if (metadata.deployment.git.message) {
|
|
585
|
+
lines.push(`**Message:** ${metadata.deployment.git.message}`);
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
lines.push('');
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Add build info
|
|
592
|
+
lines.push('## Build Information');
|
|
593
|
+
lines.push('');
|
|
594
|
+
if (metadata.project?.name) {
|
|
595
|
+
lines.push(
|
|
596
|
+
`**Project:** ${metadata.project.name}${metadata.project.version ? ` v${metadata.project.version}` : ''}`
|
|
597
|
+
);
|
|
598
|
+
}
|
|
599
|
+
if (metadata.project?.id) {
|
|
600
|
+
lines.push(`**Project ID:** ${metadata.project.id}`);
|
|
601
|
+
}
|
|
602
|
+
if (metadata.project?.orgId) {
|
|
603
|
+
lines.push(`**Org ID:** ${metadata.project.orgId}`);
|
|
604
|
+
}
|
|
605
|
+
if (metadata.deployment.id) {
|
|
606
|
+
lines.push(`**Deployment ID:** ${metadata.deployment.id}`);
|
|
607
|
+
}
|
|
608
|
+
if (metadata.deployment?.build) {
|
|
609
|
+
lines.push(
|
|
610
|
+
`**Built with:** Agentuity CLI v${metadata.deployment.build.agentuity}, Bun v${metadata.deployment.build.bun}`
|
|
611
|
+
);
|
|
612
|
+
lines.push(
|
|
613
|
+
`**Platform:** ${metadata.deployment.build.platform}-${metadata.deployment.build.arch}`
|
|
614
|
+
);
|
|
615
|
+
}
|
|
616
|
+
if (metadata.deployment?.date) {
|
|
617
|
+
lines.push(`**Build date:** ${metadata.deployment.date}`);
|
|
618
|
+
}
|
|
619
|
+
lines.push('');
|
|
620
|
+
|
|
621
|
+
// Add structure overview
|
|
622
|
+
lines.push('## Structure');
|
|
623
|
+
lines.push('');
|
|
624
|
+
lines.push('```');
|
|
625
|
+
lines.push('.agentuity/');
|
|
626
|
+
lines.push('├── app.js # Bundled server application');
|
|
627
|
+
lines.push('├── agentuity.metadata.json # Build metadata and schemas');
|
|
628
|
+
if (metadata.assets?.some((a) => a.filename.startsWith('client/'))) {
|
|
629
|
+
lines.push('├── client/ # Frontend assets (fallback, CDN by default)');
|
|
630
|
+
}
|
|
631
|
+
if (metadata.assets?.some((a) => a.filename.startsWith('public/'))) {
|
|
632
|
+
lines.push('├── public/ # Static assets');
|
|
633
|
+
}
|
|
634
|
+
lines.push('└── AGENTS.md # This file');
|
|
635
|
+
lines.push('```');
|
|
636
|
+
lines.push('');
|
|
637
|
+
|
|
638
|
+
// Add agent/route details
|
|
639
|
+
if (metadata.agents && metadata.agents.length > 0) {
|
|
640
|
+
lines.push('## Agents');
|
|
641
|
+
lines.push('');
|
|
642
|
+
lines.push(`This application defines ${metadata.agents.length} agent(s):`);
|
|
643
|
+
lines.push('');
|
|
644
|
+
for (const agent of metadata.agents) {
|
|
645
|
+
lines.push(`- **${agent.name}** (ID: \`${agent.id}\`)`);
|
|
646
|
+
}
|
|
647
|
+
lines.push('');
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
if (metadata.routes && metadata.routes.length > 0) {
|
|
651
|
+
lines.push('## Routes');
|
|
652
|
+
lines.push('');
|
|
653
|
+
lines.push(`This application defines ${metadata.routes.length} route(s):`);
|
|
654
|
+
lines.push('');
|
|
655
|
+
for (const route of metadata.routes) {
|
|
656
|
+
lines.push(`- \`${route.method.toUpperCase()} ${route.path}\` (${route.type})`);
|
|
657
|
+
}
|
|
658
|
+
lines.push('');
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
// Add runtime environment info
|
|
662
|
+
lines.push('## Runtime Environment');
|
|
663
|
+
lines.push('');
|
|
664
|
+
lines.push('When deployed, this application runs in a managed runtime environment with:');
|
|
665
|
+
lines.push('');
|
|
666
|
+
lines.push('**User & Permissions:**');
|
|
667
|
+
lines.push('- User: `agentuity` (UID: 1022, GID: 1777)');
|
|
668
|
+
lines.push('- Home directory: `/home/agentuity`');
|
|
669
|
+
lines.push('- Working directory: `/home/agentuity/app` (application code deployed here)');
|
|
670
|
+
lines.push('- Logs directory: `/home/agentuity/logs`');
|
|
671
|
+
lines.push('');
|
|
672
|
+
lines.push('**Pre-installed Tools:**');
|
|
673
|
+
lines.push('- **Runtimes:** Node.js 24, Bun 1.x');
|
|
674
|
+
lines.push('- **AI Tools:** Amp, Opencode AI, Claude Code');
|
|
675
|
+
lines.push('- **Version Control:** git, GitHub CLI (gh)');
|
|
676
|
+
lines.push('- **Browser Automation:** Chromium, ChromeDriver, Xvfb (headless display)');
|
|
677
|
+
lines.push('- **Media Processing:** ffmpeg');
|
|
678
|
+
lines.push('- **Network Tools:** curl, wget, netcat, dnsutils');
|
|
679
|
+
lines.push('- **Other:** openssh-client, openssh-sftp-server, strace, unzip, fuse');
|
|
680
|
+
lines.push('');
|
|
681
|
+
lines.push('**Environment Variables:**');
|
|
682
|
+
lines.push('- `AGENTUITY_DATA_DIR=/home/agentuity/data` - Persistent data storage');
|
|
683
|
+
lines.push('- `AGENTUITY_LOG_DIR=/home/agentuity/logs` - Application logs');
|
|
684
|
+
lines.push('- `CHROME_BIN=/usr/bin/chromium` - Chromium browser path');
|
|
685
|
+
lines.push('- `DISPLAY=:99` - X11 display for headless browser');
|
|
686
|
+
lines.push(
|
|
687
|
+
'- `PATH` includes `/home/agentuity/.local/bin` and `/home/agentuity/.agentuity/bin`'
|
|
688
|
+
);
|
|
689
|
+
lines.push('');
|
|
690
|
+
lines.push('**Ports:**');
|
|
691
|
+
lines.push(
|
|
692
|
+
'- `3000: This default port that the project is running. Use PORT environment if not available'
|
|
693
|
+
);
|
|
694
|
+
lines.push('');
|
|
695
|
+
|
|
696
|
+
// Add note about metadata
|
|
697
|
+
lines.push('## For AI Coding Agents');
|
|
698
|
+
lines.push('');
|
|
699
|
+
lines.push(
|
|
700
|
+
'This is production-ready compiled code. For development and source code modifications:'
|
|
701
|
+
);
|
|
702
|
+
lines.push('');
|
|
703
|
+
if (metadata.deployment?.git?.repo) {
|
|
704
|
+
lines.push(`1. Clone the source repository: ${metadata.deployment.git.repo}`);
|
|
705
|
+
lines.push('2. Make changes to source files in `src/`');
|
|
706
|
+
lines.push('3. Run `agentuity build` to rebuild this bundle');
|
|
707
|
+
} else {
|
|
708
|
+
lines.push('1. Locate the original source repository');
|
|
709
|
+
lines.push('2. Make changes to source files in `src/`');
|
|
710
|
+
lines.push('3. Run `agentuity build` to rebuild this bundle');
|
|
711
|
+
}
|
|
712
|
+
lines.push('');
|
|
713
|
+
lines.push(
|
|
714
|
+
'See `agentuity.metadata.json` for detailed information about agents, routes, and schemas.'
|
|
715
|
+
);
|
|
716
|
+
|
|
717
|
+
return lines.join('\n');
|
|
718
|
+
}
|
|
719
|
+
|
|
551
720
|
/**
|
|
552
721
|
* Write agentuity.metadata.json to .agentuity directory
|
|
553
722
|
*/
|
|
@@ -569,6 +738,15 @@ export function writeMetadataFile(
|
|
|
569
738
|
|
|
570
739
|
writeFileSync(metadataPath, metadataContent, 'utf-8');
|
|
571
740
|
logger.trace('Wrote agentuity.metadata.json');
|
|
741
|
+
|
|
742
|
+
// Write AGENTS.md for AI coding agents
|
|
743
|
+
if (!dev) {
|
|
744
|
+
const agentMdPath = join(agentuityDir, 'AGENTS.md');
|
|
745
|
+
const agentMdContent = generateAgentsMd(metadata);
|
|
746
|
+
|
|
747
|
+
writeFileSync(agentMdPath, agentMdContent, 'utf-8');
|
|
748
|
+
logger.trace('Wrote AGENTS.md');
|
|
749
|
+
}
|
|
572
750
|
}
|
|
573
751
|
|
|
574
752
|
/**
|