@agentuity/cli 0.0.109 → 0.0.111
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/build-report.d.ts +201 -0
- package/dist/build-report.d.ts.map +1 -0
- package/dist/build-report.js +335 -0
- package/dist/build-report.js.map +1 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +19 -4
- package/dist/cli.js.map +1 -1
- package/dist/cmd/build/entry-generator.d.ts.map +1 -1
- package/dist/cmd/build/entry-generator.js +3 -1
- package/dist/cmd/build/entry-generator.js.map +1 -1
- package/dist/cmd/build/index.d.ts.map +1 -1
- package/dist/cmd/build/index.js +44 -1
- package/dist/cmd/build/index.js.map +1 -1
- package/dist/cmd/build/typecheck.d.ts +7 -1
- package/dist/cmd/build/typecheck.d.ts.map +1 -1
- package/dist/cmd/build/typecheck.js +11 -1
- package/dist/cmd/build/typecheck.js.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.d.ts +1 -1
- package/dist/cmd/build/vite/agent-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/agent-discovery.js +3 -3
- package/dist/cmd/build/vite/agent-discovery.js.map +1 -1
- package/dist/cmd/build/vite/index.d.ts +2 -1
- package/dist/cmd/build/vite/index.d.ts.map +1 -1
- package/dist/cmd/build/vite/index.js +3 -2
- package/dist/cmd/build/vite/index.js.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/metadata-generator.js +3 -5
- package/dist/cmd/build/vite/metadata-generator.js.map +1 -1
- package/dist/cmd/build/vite/registry-generator.d.ts +1 -1
- package/dist/cmd/build/vite/registry-generator.d.ts.map +1 -1
- package/dist/cmd/build/vite/registry-generator.js +126 -41
- package/dist/cmd/build/vite/registry-generator.js.map +1 -1
- package/dist/cmd/build/vite/route-discovery.d.ts +6 -0
- package/dist/cmd/build/vite/route-discovery.d.ts.map +1 -1
- package/dist/cmd/build/vite/route-discovery.js +19 -0
- package/dist/cmd/build/vite/route-discovery.js.map +1 -1
- package/dist/cmd/build/vite/vite-builder.d.ts +3 -0
- package/dist/cmd/build/vite/vite-builder.d.ts.map +1 -1
- package/dist/cmd/build/vite/vite-builder.js +10 -2
- package/dist/cmd/build/vite/vite-builder.js.map +1 -1
- package/dist/cmd/build/vite-bundler.d.ts +3 -0
- package/dist/cmd/build/vite-bundler.d.ts.map +1 -1
- package/dist/cmd/build/vite-bundler.js +14 -5
- 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 +149 -10
- package/dist/cmd/cloud/deploy.js.map +1 -1
- package/dist/cmd/cloud/deployment/show.d.ts.map +1 -1
- package/dist/cmd/cloud/deployment/show.js +0 -1
- package/dist/cmd/cloud/deployment/show.js.map +1 -1
- package/dist/cmd/cloud/sandbox/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/create.js +18 -0
- package/dist/cmd/cloud/sandbox/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/delete.js +2 -6
- package/dist/cmd/cloud/sandbox/delete.js.map +1 -1
- package/dist/cmd/cloud/sandbox/download.d.ts +3 -0
- package/dist/cmd/cloud/sandbox/download.d.ts.map +1 -0
- package/dist/cmd/cloud/sandbox/download.js +89 -0
- package/dist/cmd/cloud/sandbox/download.js.map +1 -0
- package/dist/cmd/cloud/sandbox/env.d.ts +3 -0
- package/dist/cmd/cloud/sandbox/env.d.ts.map +1 -0
- package/dist/cmd/cloud/sandbox/env.js +90 -0
- package/dist/cmd/cloud/sandbox/env.js.map +1 -0
- package/dist/cmd/cloud/sandbox/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/get.js +5 -0
- package/dist/cmd/cloud/sandbox/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/index.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/index.js +14 -0
- package/dist/cmd/cloud/sandbox/index.js.map +1 -1
- package/dist/cmd/cloud/sandbox/ls.d.ts +3 -0
- package/dist/cmd/cloud/sandbox/ls.d.ts.map +1 -0
- package/dist/cmd/cloud/sandbox/ls.js +119 -0
- package/dist/cmd/cloud/sandbox/ls.js.map +1 -0
- package/dist/cmd/cloud/sandbox/mkdir.d.ts +3 -0
- package/dist/cmd/cloud/sandbox/mkdir.d.ts.map +1 -0
- package/dist/cmd/cloud/sandbox/mkdir.js +59 -0
- package/dist/cmd/cloud/sandbox/mkdir.js.map +1 -0
- package/dist/cmd/cloud/sandbox/rm.d.ts +3 -0
- package/dist/cmd/cloud/sandbox/rm.d.ts.map +1 -0
- package/dist/cmd/cloud/sandbox/rm.js +45 -0
- package/dist/cmd/cloud/sandbox/rm.js.map +1 -0
- package/dist/cmd/cloud/sandbox/rmdir.d.ts +3 -0
- package/dist/cmd/cloud/sandbox/rmdir.d.ts.map +1 -0
- package/dist/cmd/cloud/sandbox/rmdir.js +59 -0
- package/dist/cmd/cloud/sandbox/rmdir.js.map +1 -0
- package/dist/cmd/cloud/sandbox/snapshot/create.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/create.js +0 -2
- package/dist/cmd/cloud/sandbox/snapshot/create.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/get.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/get.js +0 -2
- package/dist/cmd/cloud/sandbox/snapshot/get.js.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.d.ts.map +1 -1
- package/dist/cmd/cloud/sandbox/snapshot/list.js +0 -3
- package/dist/cmd/cloud/sandbox/snapshot/list.js.map +1 -1
- package/dist/cmd/cloud/sandbox/upload.d.ts +3 -0
- package/dist/cmd/cloud/sandbox/upload.d.ts.map +1 -0
- package/dist/cmd/cloud/sandbox/upload.js +77 -0
- package/dist/cmd/cloud/sandbox/upload.js.map +1 -0
- package/dist/cmd/dev/index.d.ts.map +1 -1
- package/dist/cmd/dev/index.js +126 -23
- 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 +8 -14
- package/dist/cmd/dev/sync.js.map +1 -1
- package/dist/cmd/git/account/add.d.ts +17 -0
- package/dist/cmd/git/account/add.d.ts.map +1 -0
- package/dist/cmd/git/account/add.js +244 -0
- package/dist/cmd/git/account/add.js.map +1 -0
- package/dist/cmd/git/account/index.d.ts +3 -0
- package/dist/cmd/git/account/index.d.ts.map +1 -0
- package/dist/cmd/git/account/index.js +11 -0
- package/dist/cmd/git/account/index.js.map +1 -0
- package/dist/cmd/git/account/list.d.ts +2 -0
- package/dist/cmd/git/account/list.d.ts.map +1 -0
- package/dist/cmd/git/account/list.js +111 -0
- package/dist/cmd/git/account/list.js.map +1 -0
- package/dist/cmd/git/account/remove.d.ts +2 -0
- package/dist/cmd/git/account/remove.d.ts.map +1 -0
- package/dist/cmd/git/account/remove.js +171 -0
- package/dist/cmd/git/account/remove.js.map +1 -0
- package/dist/cmd/git/index.d.ts +3 -0
- package/dist/cmd/git/index.d.ts.map +1 -0
- package/dist/cmd/git/index.js +19 -0
- package/dist/cmd/git/index.js.map +1 -0
- package/dist/cmd/git/link.d.ts +32 -0
- package/dist/cmd/git/link.d.ts.map +1 -0
- package/dist/cmd/git/link.js +357 -0
- package/dist/cmd/git/link.js.map +1 -0
- package/dist/cmd/git/list.d.ts +2 -0
- package/dist/cmd/git/list.d.ts.map +1 -0
- package/dist/cmd/git/list.js +137 -0
- package/dist/cmd/git/list.js.map +1 -0
- package/dist/cmd/git/status.d.ts +2 -0
- package/dist/cmd/git/status.d.ts.map +1 -0
- package/dist/cmd/git/status.js +119 -0
- package/dist/cmd/git/status.js.map +1 -0
- package/dist/cmd/git/unlink.d.ts +2 -0
- package/dist/cmd/git/unlink.d.ts.map +1 -0
- package/dist/cmd/git/unlink.js +98 -0
- package/dist/cmd/git/unlink.js.map +1 -0
- package/dist/cmd/index.d.ts.map +1 -1
- package/dist/cmd/index.js +2 -0
- package/dist/cmd/index.js.map +1 -1
- package/dist/cmd/integration/api.d.ts +61 -0
- package/dist/cmd/integration/api.d.ts.map +1 -0
- package/dist/cmd/integration/api.js +176 -0
- package/dist/cmd/integration/api.js.map +1 -0
- package/dist/cmd/integration/github/connect.d.ts +2 -0
- package/dist/cmd/integration/github/connect.d.ts.map +1 -0
- package/dist/cmd/integration/github/connect.js +197 -0
- package/dist/cmd/integration/github/connect.js.map +1 -0
- package/dist/cmd/integration/github/disconnect.d.ts +2 -0
- package/dist/cmd/integration/github/disconnect.d.ts.map +1 -0
- package/dist/cmd/integration/github/disconnect.js +121 -0
- package/dist/cmd/integration/github/disconnect.js.map +1 -0
- package/dist/cmd/integration/github/index.d.ts +2 -0
- package/dist/cmd/integration/github/index.d.ts.map +1 -0
- package/dist/cmd/integration/github/index.js +21 -0
- package/dist/cmd/integration/github/index.js.map +1 -0
- package/dist/cmd/integration/index.d.ts +2 -0
- package/dist/cmd/integration/index.d.ts.map +1 -0
- package/dist/cmd/integration/index.js +16 -0
- package/dist/cmd/integration/index.js.map +1 -0
- package/dist/cmd/project/auth/generate.d.ts +5 -0
- package/dist/cmd/project/auth/generate.d.ts.map +1 -0
- package/dist/cmd/project/auth/generate.js +102 -0
- package/dist/cmd/project/auth/generate.js.map +1 -0
- package/dist/cmd/project/auth/index.d.ts +2 -0
- package/dist/cmd/project/auth/index.d.ts.map +1 -0
- package/dist/cmd/project/auth/index.js +21 -0
- package/dist/cmd/project/auth/index.js.map +1 -0
- package/dist/cmd/project/auth/init.d.ts +2 -0
- package/dist/cmd/project/auth/init.d.ts.map +1 -0
- package/dist/cmd/project/auth/init.js +220 -0
- package/dist/cmd/project/auth/init.js.map +1 -0
- package/dist/cmd/project/auth/shared.d.ts +88 -0
- package/dist/cmd/project/auth/shared.d.ts.map +1 -0
- package/dist/cmd/project/auth/shared.js +435 -0
- package/dist/cmd/project/auth/shared.js.map +1 -0
- package/dist/cmd/project/index.d.ts.map +1 -1
- package/dist/cmd/project/index.js +9 -1
- package/dist/cmd/project/index.js.map +1 -1
- package/dist/cmd/project/template-flow.d.ts.map +1 -1
- package/dist/cmd/project/template-flow.js +106 -0
- package/dist/cmd/project/template-flow.js.map +1 -1
- package/dist/config.d.ts +2 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +24 -0
- package/dist/config.js.map +1 -1
- package/dist/errors.d.ts +2 -1
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +5 -0
- package/dist/errors.js.map +1 -1
- package/dist/types.d.ts +3 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +5 -2
- package/dist/types.js.map +1 -1
- package/package.json +6 -5
- package/src/build-report.ts +457 -0
- package/src/cli.ts +20 -4
- package/src/cmd/build/entry-generator.ts +3 -1
- package/src/cmd/build/index.ts +51 -1
- package/src/cmd/build/typecheck.ts +19 -1
- package/src/cmd/build/vite/agent-discovery.ts +4 -4
- package/src/cmd/build/vite/index.ts +5 -2
- package/src/cmd/build/vite/metadata-generator.ts +5 -7
- package/src/cmd/build/vite/registry-generator.ts +136 -43
- package/src/cmd/build/vite/route-discovery.ts +20 -0
- package/src/cmd/build/vite/vite-builder.ts +13 -2
- package/src/cmd/build/vite-bundler.ts +17 -4
- package/src/cmd/cloud/deploy.ts +183 -12
- package/src/cmd/cloud/deployment/show.ts +0 -1
- package/src/cmd/cloud/sandbox/create.ts +22 -0
- package/src/cmd/cloud/sandbox/delete.ts +2 -6
- package/src/cmd/cloud/sandbox/download.ts +96 -0
- package/src/cmd/cloud/sandbox/env.ts +104 -0
- package/src/cmd/cloud/sandbox/get.ts +5 -0
- package/src/cmd/cloud/sandbox/index.ts +14 -0
- package/src/cmd/cloud/sandbox/ls.ts +126 -0
- package/src/cmd/cloud/sandbox/mkdir.ts +65 -0
- package/src/cmd/cloud/sandbox/rm.ts +51 -0
- package/src/cmd/cloud/sandbox/rmdir.ts +65 -0
- package/src/cmd/cloud/sandbox/snapshot/create.ts +0 -2
- package/src/cmd/cloud/sandbox/snapshot/get.ts +0 -2
- package/src/cmd/cloud/sandbox/snapshot/list.ts +0 -3
- package/src/cmd/cloud/sandbox/upload.ts +83 -0
- package/src/cmd/dev/index.ts +147 -33
- package/src/cmd/dev/sync.ts +26 -30
- package/src/cmd/git/account/add.ts +317 -0
- package/src/cmd/git/account/index.ts +12 -0
- package/src/cmd/git/account/list.ts +139 -0
- package/src/cmd/git/account/remove.ts +212 -0
- package/src/cmd/git/index.ts +20 -0
- package/src/cmd/git/link.ts +468 -0
- package/src/cmd/git/list.ts +161 -0
- package/src/cmd/git/status.ts +144 -0
- package/src/cmd/git/unlink.ts +117 -0
- package/src/cmd/index.ts +2 -0
- package/src/cmd/integration/api.ts +379 -0
- package/src/cmd/integration/github/connect.ts +242 -0
- package/src/cmd/integration/github/disconnect.ts +149 -0
- package/src/cmd/integration/github/index.ts +21 -0
- package/src/cmd/integration/index.ts +16 -0
- package/src/cmd/project/auth/generate.ts +116 -0
- package/src/cmd/project/auth/index.ts +21 -0
- package/src/cmd/project/auth/init.ts +263 -0
- package/src/cmd/project/auth/shared.ts +534 -0
- package/src/cmd/project/index.ts +9 -1
- package/src/cmd/project/template-flow.ts +125 -0
- package/src/config.ts +34 -0
- package/src/errors.ts +7 -0
- package/src/types.ts +5 -2
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { parse, type GrammarItem } from '../../tsc-output-parser';
|
|
2
2
|
import { formatTypeScriptErrors, hasErrors } from '../../typescript-errors';
|
|
3
|
+
import type { BuildReportCollector } from '../../build-report';
|
|
3
4
|
|
|
4
5
|
interface TypeError {
|
|
5
6
|
success: false;
|
|
@@ -18,13 +19,20 @@ interface TypeSuccess {
|
|
|
18
19
|
|
|
19
20
|
type TypeResult = TypeError | TypeSuccess | TypeUnknownError;
|
|
20
21
|
|
|
22
|
+
export interface TypecheckOptions {
|
|
23
|
+
/** Optional collector for structured error reporting */
|
|
24
|
+
collector?: BuildReportCollector;
|
|
25
|
+
}
|
|
26
|
+
|
|
21
27
|
/**
|
|
22
28
|
* run the typescript compiler and result formatted results
|
|
23
29
|
*
|
|
24
30
|
* @param dir the absolute path to the directory containing the project (must have tsconfig.json in this folder)
|
|
31
|
+
* @param options optional configuration including error collector
|
|
25
32
|
* @returns
|
|
26
33
|
*/
|
|
27
|
-
export async function typecheck(dir: string): Promise<TypeResult> {
|
|
34
|
+
export async function typecheck(dir: string, options?: TypecheckOptions): Promise<TypeResult> {
|
|
35
|
+
const { collector } = options ?? {};
|
|
28
36
|
const result = await Bun.$`bunx tsc --noEmit --skipLibCheck --pretty false`
|
|
29
37
|
.cwd(dir)
|
|
30
38
|
.quiet()
|
|
@@ -38,6 +46,11 @@ export async function typecheck(dir: string): Promise<TypeResult> {
|
|
|
38
46
|
success: true,
|
|
39
47
|
};
|
|
40
48
|
} else if (errors && hasErrors(errors)) {
|
|
49
|
+
// Add errors to collector if provided
|
|
50
|
+
if (collector) {
|
|
51
|
+
collector.addTypeScriptErrors(errors);
|
|
52
|
+
}
|
|
53
|
+
|
|
41
54
|
const formattedErrors = await formatTypeScriptErrors(errors, {
|
|
42
55
|
projectDir: dir,
|
|
43
56
|
});
|
|
@@ -47,6 +60,11 @@ export async function typecheck(dir: string): Promise<TypeResult> {
|
|
|
47
60
|
output: formattedErrors,
|
|
48
61
|
};
|
|
49
62
|
} else {
|
|
63
|
+
// Unknown error - add to collector as general error
|
|
64
|
+
if (collector) {
|
|
65
|
+
collector.addGeneralError('typescript', output || result.stderr.toString());
|
|
66
|
+
}
|
|
67
|
+
|
|
50
68
|
return {
|
|
51
69
|
success: false,
|
|
52
70
|
output: output || result.stderr.toString(),
|
|
@@ -65,7 +65,7 @@ export interface AgentMetadata {
|
|
|
65
65
|
|
|
66
66
|
export interface EvalMetadata {
|
|
67
67
|
id: string;
|
|
68
|
-
|
|
68
|
+
identifier: string;
|
|
69
69
|
name: string;
|
|
70
70
|
filename: string;
|
|
71
71
|
version: string;
|
|
@@ -459,13 +459,13 @@ function extractEvalsFromSource(
|
|
|
459
459
|
|
|
460
460
|
if (evalName) {
|
|
461
461
|
const id = getEvalId(projectId, deploymentId, filename, evalName, version);
|
|
462
|
-
const
|
|
462
|
+
const identifier = generateStableEvalId(projectId, agentId, evalName);
|
|
463
463
|
|
|
464
|
-
logger.trace(`Found eval '${evalName}' in ${filename} (
|
|
464
|
+
logger.trace(`Found eval '${evalName}' in ${filename} (identifier: ${identifier})`);
|
|
465
465
|
|
|
466
466
|
evals.push({
|
|
467
467
|
id,
|
|
468
|
-
|
|
468
|
+
identifier,
|
|
469
469
|
name: evalName,
|
|
470
470
|
filename,
|
|
471
471
|
version,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { createLogger } from '@agentuity/server';
|
|
4
|
-
import type { LogLevel } from '../../../types';
|
|
4
|
+
import type { LogLevel, DeployOptions } from '../../../types';
|
|
5
5
|
import { discoverAgents, type AgentMetadata } from './agent-discovery';
|
|
6
6
|
import { discoverRoutes, type RouteMetadata, type RouteInfo } from './route-discovery';
|
|
7
7
|
import { generateAgentRegistry, generateRouteRegistry } from './registry-generator';
|
|
@@ -20,6 +20,7 @@ export interface AgentuityPluginOptions {
|
|
|
20
20
|
orgId?: string;
|
|
21
21
|
deploymentId?: string;
|
|
22
22
|
logLevel?: LogLevel;
|
|
23
|
+
deploymentOptions?: DeployOptions;
|
|
23
24
|
}
|
|
24
25
|
|
|
25
26
|
/**
|
|
@@ -42,6 +43,7 @@ export function agentuityPlugin(options: AgentuityPluginOptions): Plugin {
|
|
|
42
43
|
orgId = '',
|
|
43
44
|
deploymentId = '',
|
|
44
45
|
logLevel = 'info',
|
|
46
|
+
deploymentOptions,
|
|
45
47
|
} = options;
|
|
46
48
|
const logger = createLogger(logLevel);
|
|
47
49
|
const srcDir = join(rootDir, 'src');
|
|
@@ -85,7 +87,7 @@ export function agentuityPlugin(options: AgentuityPluginOptions): Plugin {
|
|
|
85
87
|
}
|
|
86
88
|
|
|
87
89
|
if (routeInfoList.length > 0) {
|
|
88
|
-
generateRouteRegistry(srcDir, routeInfoList, agents);
|
|
90
|
+
await generateRouteRegistry(srcDir, routeInfoList, agents);
|
|
89
91
|
logger.trace('Generated route registry with %d route(s)', routeInfoList.length);
|
|
90
92
|
}
|
|
91
93
|
|
|
@@ -153,6 +155,7 @@ export function agentuityPlugin(options: AgentuityPluginOptions): Plugin {
|
|
|
153
155
|
routes,
|
|
154
156
|
dev,
|
|
155
157
|
logger,
|
|
158
|
+
deploymentOptions,
|
|
156
159
|
});
|
|
157
160
|
|
|
158
161
|
// Write metadata file
|
|
@@ -443,7 +443,7 @@ export async function generateMetadata(options: MetadataGeneratorOptions): Promi
|
|
|
443
443
|
evals: agent.evals?.map((evalItem) => ({
|
|
444
444
|
filename: evalItem.filename,
|
|
445
445
|
id: evalItem.id,
|
|
446
|
-
|
|
446
|
+
identifier: evalItem.identifier,
|
|
447
447
|
name: evalItem.name,
|
|
448
448
|
version: evalItem.version,
|
|
449
449
|
description: evalItem.description,
|
|
@@ -478,12 +478,10 @@ export async function generateMetadata(options: MetadataGeneratorOptions): Promi
|
|
|
478
478
|
if (options.deploymentOptions.pullRequestNumber) {
|
|
479
479
|
git.pull_request = {
|
|
480
480
|
number: options.deploymentOptions.pullRequestNumber,
|
|
481
|
-
|
|
482
|
-
url: options.deploymentOptions.pullRequestURL,
|
|
481
|
+
url: options.deploymentOptions.pullRequestUrl,
|
|
483
482
|
};
|
|
484
|
-
delete git.pullRequestCommentId;
|
|
485
483
|
delete git.pullRequestNumber;
|
|
486
|
-
delete git.
|
|
484
|
+
delete git.pullRequestUrl;
|
|
487
485
|
}
|
|
488
486
|
metadata.deployment.git = git;
|
|
489
487
|
}
|
|
@@ -706,10 +704,10 @@ function generateAgentsMd(metadata: BuildMetadata): string {
|
|
|
706
704
|
lines.push('.agentuity/');
|
|
707
705
|
lines.push('├── app.js # Bundled server application');
|
|
708
706
|
lines.push('├── agentuity.metadata.json # Build metadata and schemas');
|
|
709
|
-
if (metadata.assets?.some((a) => a.filename.startsWith('client/'))) {
|
|
707
|
+
if (metadata.assets?.some((a: { filename: string }) => a.filename.startsWith('client/'))) {
|
|
710
708
|
lines.push('├── client/ # Frontend assets (fallback, CDN by default)');
|
|
711
709
|
}
|
|
712
|
-
if (metadata.assets?.some((a) => a.filename.startsWith('public/'))) {
|
|
710
|
+
if (metadata.assets?.some((a: { filename: string }) => a.filename.startsWith('public/'))) {
|
|
713
711
|
lines.push('├── public/ # Static assets');
|
|
714
712
|
}
|
|
715
713
|
lines.push('└── AGENTS.md # This file');
|
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
|
|
7
7
|
import { join } from 'node:path';
|
|
8
8
|
import { writeFileSync, mkdirSync, existsSync, unlinkSync, readFileSync } from 'node:fs';
|
|
9
|
+
import { stat } from 'node:fs/promises';
|
|
9
10
|
import { StructuredError } from '@agentuity/core';
|
|
10
11
|
import { toCamelCase, toPascalCase } from '../../../utils/string';
|
|
11
12
|
import type { AgentMetadata } from './agent-discovery';
|
|
@@ -29,6 +30,28 @@ function sanitizePathSegment(segment: string): string {
|
|
|
29
30
|
return toCamelCase(segment.replace(ROUTE_PARAM_CHARS, ''));
|
|
30
31
|
}
|
|
31
32
|
|
|
33
|
+
/**
|
|
34
|
+
* Generate TypeScript type for path parameters.
|
|
35
|
+
* Returns 'never' if no path params, or '{ param1: string; param2: string }' format.
|
|
36
|
+
*/
|
|
37
|
+
function generatePathParamsType(pathParams?: string[]): string {
|
|
38
|
+
if (!pathParams || pathParams.length === 0) {
|
|
39
|
+
return 'never';
|
|
40
|
+
}
|
|
41
|
+
return `{ ${pathParams.map((p) => `${p}: string`).join('; ')} }`;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Generate TypeScript tuple type for path parameters (for positional args).
|
|
46
|
+
* Returns '[]' if no path params, or '[string, string]' format.
|
|
47
|
+
*/
|
|
48
|
+
function generatePathParamsTupleType(pathParams?: string[]): string {
|
|
49
|
+
if (!pathParams || pathParams.length === 0) {
|
|
50
|
+
return '[]';
|
|
51
|
+
}
|
|
52
|
+
return `[${pathParams.map(() => 'string').join(', ')}]`;
|
|
53
|
+
}
|
|
54
|
+
|
|
32
55
|
/**
|
|
33
56
|
* Generate src/generated/registry.ts with agent registry and types
|
|
34
57
|
*/
|
|
@@ -36,11 +59,14 @@ export function generateAgentRegistry(srcDir: string, agents: AgentMetadata[]):
|
|
|
36
59
|
const generatedDir = join(srcDir, 'generated');
|
|
37
60
|
const registryPath = join(generatedDir, 'registry.ts');
|
|
38
61
|
|
|
62
|
+
// Sort agents by name for deterministic output
|
|
63
|
+
const sortedAgents = [...agents].sort((a, b) => a.name.localeCompare(b.name));
|
|
64
|
+
|
|
39
65
|
// Detect naming collisions in generated identifiers
|
|
40
66
|
const generatedNames = new Set<string>();
|
|
41
67
|
const collisions: string[] = [];
|
|
42
68
|
|
|
43
|
-
for (const agent of
|
|
69
|
+
for (const agent of sortedAgents) {
|
|
44
70
|
const camelName = toCamelCase(agent.name);
|
|
45
71
|
|
|
46
72
|
if (generatedNames.has(camelName)) {
|
|
@@ -59,7 +85,7 @@ export function generateAgentRegistry(srcDir: string, agents: AgentMetadata[]):
|
|
|
59
85
|
}
|
|
60
86
|
|
|
61
87
|
// Generate imports for all agents
|
|
62
|
-
const imports =
|
|
88
|
+
const imports = sortedAgents
|
|
63
89
|
.map(({ name, filename }) => {
|
|
64
90
|
const camelName = toCamelCase(name);
|
|
65
91
|
// Handle both './agent/...' and 'src/agent/...' formats
|
|
@@ -80,7 +106,7 @@ export function generateAgentRegistry(srcDir: string, agents: AgentMetadata[]):
|
|
|
80
106
|
.join('\n');
|
|
81
107
|
|
|
82
108
|
// Generate schema type exports for all agents
|
|
83
|
-
const schemaTypeExports =
|
|
109
|
+
const schemaTypeExports = sortedAgents
|
|
84
110
|
.map(({ name, description }) => {
|
|
85
111
|
const camelName = toCamelCase(name);
|
|
86
112
|
const pascalName = toPascalCase(name);
|
|
@@ -122,7 +148,7 @@ export function generateAgentRegistry(srcDir: string, agents: AgentMetadata[]):
|
|
|
122
148
|
.join('\n');
|
|
123
149
|
|
|
124
150
|
// Generate flat registry structure with JSDoc
|
|
125
|
-
const registry =
|
|
151
|
+
const registry = sortedAgents
|
|
126
152
|
.map(({ name, description }) => {
|
|
127
153
|
const camelName = toCamelCase(name);
|
|
128
154
|
const pascalName = toPascalCase(name);
|
|
@@ -138,7 +164,7 @@ export function generateAgentRegistry(srcDir: string, agents: AgentMetadata[]):
|
|
|
138
164
|
|
|
139
165
|
// Generate flat agent type definitions for AgentRegistry interface augmentation
|
|
140
166
|
// Uses the exported Agent types defined above
|
|
141
|
-
const runtimeAgentTypes =
|
|
167
|
+
const runtimeAgentTypes = sortedAgents
|
|
142
168
|
.map(({ name }) => {
|
|
143
169
|
const camelName = toCamelCase(name);
|
|
144
170
|
const pascalName = toPascalCase(name);
|
|
@@ -231,7 +257,7 @@ function generateRPCRegistryType(
|
|
|
231
257
|
apiRoutes: RouteInfo[],
|
|
232
258
|
websocketRoutes: RouteInfo[],
|
|
233
259
|
sseRoutes: RouteInfo[],
|
|
234
|
-
|
|
260
|
+
agentImports: Map<string, string>,
|
|
235
261
|
_schemaImportAliases: Map<string, Map<string, string>>,
|
|
236
262
|
agentMetadataMap: Map<string, AgentMetadata>
|
|
237
263
|
): string {
|
|
@@ -263,6 +289,10 @@ function generateRPCRegistryType(
|
|
|
263
289
|
// Add path segments - sanitize for valid TypeScript property names
|
|
264
290
|
for (let i = 0; i < pathParts.length; i++) {
|
|
265
291
|
const part = sanitizePathSegment(pathParts[i]);
|
|
292
|
+
// Skip empty segments (e.g., wildcards like '*' that sanitize to '')
|
|
293
|
+
if (!part) {
|
|
294
|
+
continue;
|
|
295
|
+
}
|
|
266
296
|
if (!current[part]) {
|
|
267
297
|
current[part] = {};
|
|
268
298
|
}
|
|
@@ -292,8 +322,12 @@ function generateRPCRegistryType(
|
|
|
292
322
|
// Only reference type names if route has actual schemas extracted, otherwise use 'never'
|
|
293
323
|
// Note: hasValidator may be true (e.g., zValidator('query', ...)) but no schemas extracted
|
|
294
324
|
// because only 'json' validators extract input schemas
|
|
325
|
+
// Also check if agentVariable exists but import wasn't added (missing agentImportPath)
|
|
326
|
+
const hasValidAgentImport = route.agentVariable
|
|
327
|
+
? !!agentImports.get(route.agentVariable)
|
|
328
|
+
: false;
|
|
295
329
|
const hasSchemas =
|
|
296
|
-
route.inputSchemaVariable || route.outputSchemaVariable ||
|
|
330
|
+
route.inputSchemaVariable || route.outputSchemaVariable || hasValidAgentImport;
|
|
297
331
|
|
|
298
332
|
current[terminalMethod] = {
|
|
299
333
|
input: hasSchemas ? `${pascalName}Input` : 'never',
|
|
@@ -315,7 +349,9 @@ function generateRPCRegistryType(
|
|
|
315
349
|
function treeToTypeString(node: NestedNode, indent: string = '\t\t'): string {
|
|
316
350
|
const lines: string[] = [];
|
|
317
351
|
|
|
318
|
-
|
|
352
|
+
// Sort entries alphabetically for deterministic output
|
|
353
|
+
const sortedEntries = Object.entries(node).sort(([a], [b]) => a.localeCompare(b));
|
|
354
|
+
for (const [key, value] of sortedEntries) {
|
|
319
355
|
if (
|
|
320
356
|
value &&
|
|
321
357
|
typeof value === 'object' &&
|
|
@@ -349,8 +385,10 @@ function generateRPCRegistryType(
|
|
|
349
385
|
jsdoc.push(`${indent} */`);
|
|
350
386
|
lines.push(...jsdoc);
|
|
351
387
|
|
|
388
|
+
const pathParamsType = generatePathParamsType(routeInfo.pathParams);
|
|
389
|
+
const pathParamsTupleType = generatePathParamsTupleType(routeInfo.pathParams);
|
|
352
390
|
lines.push(
|
|
353
|
-
`${indent}${key}: { input: ${value.input}; output: ${value.output}; type: ${value.type} };`
|
|
391
|
+
`${indent}${key}: { input: ${value.input}; output: ${value.output}; type: ${value.type}; params: ${pathParamsType}; paramsTuple: ${pathParamsTupleType} };`
|
|
354
392
|
);
|
|
355
393
|
} else {
|
|
356
394
|
// Nested node
|
|
@@ -380,7 +418,7 @@ function generateRPCRuntimeMetadata(
|
|
|
380
418
|
sseRoutes: RouteInfo[]
|
|
381
419
|
): string {
|
|
382
420
|
interface MetadataNode {
|
|
383
|
-
[key: string]: MetadataNode | { type: string };
|
|
421
|
+
[key: string]: MetadataNode | { type: string; path: string; pathParams?: string[] };
|
|
384
422
|
}
|
|
385
423
|
|
|
386
424
|
const tree: MetadataNode = {};
|
|
@@ -400,6 +438,10 @@ function generateRPCRuntimeMetadata(
|
|
|
400
438
|
// Sanitize path segments for valid property names (must match type generation)
|
|
401
439
|
for (const part of pathParts) {
|
|
402
440
|
const sanitized = sanitizePathSegment(part);
|
|
441
|
+
// Skip empty segments (e.g., wildcards like '*' that sanitize to '')
|
|
442
|
+
if (!sanitized) {
|
|
443
|
+
continue;
|
|
444
|
+
}
|
|
403
445
|
if (!current[sanitized]) current[sanitized] = {};
|
|
404
446
|
current = current[sanitized];
|
|
405
447
|
}
|
|
@@ -414,14 +456,35 @@ function generateRPCRuntimeMetadata(
|
|
|
414
456
|
? 'stream'
|
|
415
457
|
: route.method.toLowerCase();
|
|
416
458
|
|
|
417
|
-
|
|
459
|
+
const metadata: { type: string; path: string; pathParams?: string[] } = {
|
|
460
|
+
type: routeType,
|
|
461
|
+
path: route.path,
|
|
462
|
+
};
|
|
463
|
+
if (route.pathParams && route.pathParams.length > 0) {
|
|
464
|
+
metadata.pathParams = route.pathParams;
|
|
465
|
+
}
|
|
466
|
+
current[terminalMethod] = metadata;
|
|
418
467
|
};
|
|
419
468
|
|
|
420
469
|
apiRoutes.forEach((r) => addRoute(r, r.routeType === 'stream' ? 'stream' : 'api'));
|
|
421
470
|
websocketRoutes.forEach((r) => addRoute(r, 'websocket'));
|
|
422
471
|
sseRoutes.forEach((r) => addRoute(r, 'sse'));
|
|
423
472
|
|
|
424
|
-
|
|
473
|
+
// Sort object keys recursively for deterministic output
|
|
474
|
+
const sortObject = (obj: MetadataNode): MetadataNode => {
|
|
475
|
+
const sorted: MetadataNode = {};
|
|
476
|
+
for (const key of Object.keys(obj).sort()) {
|
|
477
|
+
const value = obj[key];
|
|
478
|
+
if (value && typeof value === 'object' && !('type' in value)) {
|
|
479
|
+
sorted[key] = sortObject(value as MetadataNode);
|
|
480
|
+
} else {
|
|
481
|
+
sorted[key] = value;
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
return sorted;
|
|
485
|
+
};
|
|
486
|
+
|
|
487
|
+
return JSON.stringify(sortObject(tree), null, '\t\t');
|
|
425
488
|
}
|
|
426
489
|
|
|
427
490
|
/**
|
|
@@ -430,15 +493,15 @@ function generateRPCRuntimeMetadata(
|
|
|
430
493
|
* Creates a module augmentation for @agentuity/react that provides
|
|
431
494
|
* strongly-typed route keys with input/output schema information.
|
|
432
495
|
*/
|
|
433
|
-
export function generateRouteRegistry(
|
|
496
|
+
export async function generateRouteRegistry(
|
|
434
497
|
srcDir: string,
|
|
435
498
|
routes: RouteInfo[],
|
|
436
499
|
agents: AgentMetadata[] = []
|
|
437
|
-
): void {
|
|
438
|
-
// Check if project uses @agentuity/react
|
|
500
|
+
): Promise<void> {
|
|
439
501
|
const projectRoot = join(srcDir, '..');
|
|
440
502
|
const packageJsonPath = join(projectRoot, 'package.json');
|
|
441
503
|
let hasReactDependency = false;
|
|
504
|
+
let hasFrontendDependency = false;
|
|
442
505
|
|
|
443
506
|
try {
|
|
444
507
|
const packageJson = JSON.parse(readFileSync(packageJsonPath, 'utf-8'));
|
|
@@ -446,14 +509,32 @@ export function generateRouteRegistry(
|
|
|
446
509
|
packageJson.dependencies?.['@agentuity/react'] ||
|
|
447
510
|
packageJson.devDependencies?.['@agentuity/react']
|
|
448
511
|
);
|
|
512
|
+
hasFrontendDependency = !!(
|
|
513
|
+
packageJson.dependencies?.['@agentuity/frontend'] ||
|
|
514
|
+
packageJson.devDependencies?.['@agentuity/frontend']
|
|
515
|
+
);
|
|
516
|
+
} catch {
|
|
517
|
+
// If we can't read package.json, assume no frontend dependencies
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
const webDir = join(srcDir, 'web');
|
|
521
|
+
let hasWebDirectory = false;
|
|
522
|
+
try {
|
|
523
|
+
const webDirStat = await stat(webDir);
|
|
524
|
+
hasWebDirectory = webDirStat.isDirectory();
|
|
449
525
|
} catch {
|
|
450
|
-
//
|
|
526
|
+
// Directory doesn't exist
|
|
451
527
|
}
|
|
452
528
|
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
const
|
|
529
|
+
const shouldEmitFrontendClient = hasFrontendDependency && !hasReactDependency && hasWebDirectory;
|
|
530
|
+
|
|
531
|
+
// Filter routes by type and sort by path for deterministic output
|
|
532
|
+
const sortByPath = (a: RouteInfo, b: RouteInfo) => a.path.localeCompare(b.path);
|
|
533
|
+
const apiRoutes = routes
|
|
534
|
+
.filter((r) => r.routeType === 'api' || r.routeType === 'stream')
|
|
535
|
+
.sort(sortByPath);
|
|
536
|
+
const websocketRoutes = routes.filter((r) => r.routeType === 'websocket').sort(sortByPath);
|
|
537
|
+
const sseRoutes = routes.filter((r) => r.routeType === 'sse').sort(sortByPath);
|
|
457
538
|
|
|
458
539
|
const allRoutes = [...apiRoutes, ...websocketRoutes, ...sseRoutes];
|
|
459
540
|
|
|
@@ -637,8 +718,10 @@ export function generateRouteRegistry(
|
|
|
637
718
|
agentMeta = agentMetadataMap.get(route.agentVariable);
|
|
638
719
|
}
|
|
639
720
|
|
|
640
|
-
if
|
|
641
|
-
|
|
721
|
+
// Only generate agent-based types if the import was successfully added
|
|
722
|
+
// (import is only added when hasValidator && agentVariable && agentImportPath are all present)
|
|
723
|
+
const importName = route.agentVariable ? agentImports.get(route.agentVariable) : undefined;
|
|
724
|
+
if (importName) {
|
|
642
725
|
inputType = `InferInput<typeof ${importName}['inputSchema']>`;
|
|
643
726
|
outputType = `InferOutput<typeof ${importName}['outputSchema']>`;
|
|
644
727
|
inputSchemaType = `typeof ${importName} extends { inputSchema?: infer I } ? I : never`;
|
|
@@ -724,20 +807,28 @@ export function generateRouteRegistry(
|
|
|
724
807
|
.replace(/_+/g, '_');
|
|
725
808
|
const pascalName = toPascalCase(safeName);
|
|
726
809
|
|
|
810
|
+
// Use the exported schema types we generated above
|
|
811
|
+
// Note: agentImports.get() may return undefined if import wasn't added
|
|
812
|
+
const importName = route.agentVariable ? agentImports.get(route.agentVariable) : null;
|
|
813
|
+
|
|
727
814
|
// Use 'never' types if no schemas were actually extracted
|
|
728
815
|
// Note: hasValidator may be true (e.g., zValidator('query', ...)) but no schemas extracted
|
|
729
816
|
// because only 'json' validators extract input schemas
|
|
730
|
-
if
|
|
817
|
+
// Also check if agentVariable exists but import wasn't added (missing agentImportPath)
|
|
818
|
+
const hasValidAgentImport = route.agentVariable ? !!importName : false;
|
|
819
|
+
|
|
820
|
+
// Generate pathParams type
|
|
821
|
+
const pathParamsType = generatePathParamsType(route.pathParams);
|
|
822
|
+
|
|
823
|
+
if (!route.inputSchemaVariable && !route.outputSchemaVariable && !hasValidAgentImport) {
|
|
731
824
|
const streamValue = route.stream === true ? 'true' : 'false';
|
|
732
825
|
return `\t'${routeKey}': {
|
|
733
|
-
\t\tinputSchema: never;
|
|
734
|
-
\t\toutputSchema: never;
|
|
735
|
-
\t\tstream: ${streamValue};
|
|
736
|
-
\t}
|
|
826
|
+
\t\tinputSchema: never;
|
|
827
|
+
\t\toutputSchema: never;
|
|
828
|
+
\t\tstream: ${streamValue};
|
|
829
|
+
\t\tparams: ${pathParamsType};
|
|
830
|
+
\t};`;
|
|
737
831
|
}
|
|
738
|
-
|
|
739
|
-
// Use the exported schema types we generated above
|
|
740
|
-
const importName = route.agentVariable ? agentImports.get(route.agentVariable)! : null;
|
|
741
832
|
const streamValue = importName
|
|
742
833
|
? `typeof ${importName} extends { stream?: infer S } ? S : false`
|
|
743
834
|
: route.stream === true
|
|
@@ -745,10 +836,11 @@ export function generateRouteRegistry(
|
|
|
745
836
|
: 'false';
|
|
746
837
|
|
|
747
838
|
return `\t'${routeKey}': {
|
|
748
|
-
\t\tinputSchema: ${pascalName}InputSchema;
|
|
749
|
-
\t\toutputSchema: ${pascalName}OutputSchema;
|
|
750
|
-
\t\tstream: ${streamValue};
|
|
751
|
-
\t}
|
|
839
|
+
\t\tinputSchema: ${pascalName}InputSchema;
|
|
840
|
+
\t\toutputSchema: ${pascalName}OutputSchema;
|
|
841
|
+
\t\tstream: ${streamValue};
|
|
842
|
+
\t\tparams: ${pathParamsType};
|
|
843
|
+
\t};`;
|
|
752
844
|
};
|
|
753
845
|
|
|
754
846
|
// Generate route entries with METHOD prefix for API routes
|
|
@@ -778,7 +870,7 @@ export function generateRouteRegistry(
|
|
|
778
870
|
const generatedContent = `// @generated
|
|
779
871
|
// Auto-generated by Agentuity - DO NOT EDIT
|
|
780
872
|
${importsStr}${typeImports}${
|
|
781
|
-
|
|
873
|
+
shouldEmitFrontendClient
|
|
782
874
|
? `
|
|
783
875
|
import { createClient } from '@agentuity/frontend';`
|
|
784
876
|
: ''
|
|
@@ -803,7 +895,7 @@ ${routeSchemaTypes}
|
|
|
803
895
|
* Individual route Input/Output types are exported above for direct usage.
|
|
804
896
|
*/
|
|
805
897
|
${
|
|
806
|
-
|
|
898
|
+
shouldEmitFrontendClient
|
|
807
899
|
? `
|
|
808
900
|
/**
|
|
809
901
|
* RPC Route Registry
|
|
@@ -868,13 +960,14 @@ if (typeof globalThis !== 'undefined') {
|
|
|
868
960
|
(globalThis as Record<string, unknown>).__rpcRouteMetadata = _rpcRouteMetadata;
|
|
869
961
|
}
|
|
870
962
|
${
|
|
871
|
-
|
|
963
|
+
shouldEmitFrontendClient
|
|
872
964
|
? `
|
|
873
965
|
/**
|
|
874
966
|
* Create a type-safe API client with optional configuration.
|
|
875
967
|
*
|
|
876
|
-
* This function is only generated when @agentuity/
|
|
877
|
-
*
|
|
968
|
+
* This function is only generated when @agentuity/frontend is installed
|
|
969
|
+
* but @agentuity/react is not. For React apps, import createAPIClient
|
|
970
|
+
* from '@agentuity/react' instead.
|
|
878
971
|
*
|
|
879
972
|
* @example
|
|
880
973
|
* \`\`\`typescript
|
|
@@ -893,7 +986,8 @@ export function createAPIClient(options?: Parameters<typeof createClient>[0]): i
|
|
|
893
986
|
return createClient(options || {}, _rpcRouteMetadata) as import('@agentuity/frontend').Client<RPCRouteRegistry>;
|
|
894
987
|
}
|
|
895
988
|
`
|
|
896
|
-
:
|
|
989
|
+
: hasReactDependency
|
|
990
|
+
? `
|
|
897
991
|
/**
|
|
898
992
|
* Type-safe API client is available from @agentuity/react
|
|
899
993
|
*
|
|
@@ -906,6 +1000,7 @@ export function createAPIClient(options?: Parameters<typeof createClient>[0]): i
|
|
|
906
1000
|
* \`\`\`
|
|
907
1001
|
*/
|
|
908
1002
|
`
|
|
1003
|
+
: ''
|
|
909
1004
|
}
|
|
910
1005
|
|
|
911
1006
|
// FOUND AN ERROR IN THIS FILE?
|
|
@@ -916,9 +1011,7 @@ export function createAPIClient(options?: Parameters<typeof createClient>[0]): i
|
|
|
916
1011
|
const generatedDir = join(srcDir, 'generated');
|
|
917
1012
|
const registryPath = join(generatedDir, 'routes.ts');
|
|
918
1013
|
|
|
919
|
-
|
|
920
|
-
mkdirSync(generatedDir, { recursive: true });
|
|
921
|
-
}
|
|
1014
|
+
mkdirSync(generatedDir, { recursive: true });
|
|
922
1015
|
|
|
923
1016
|
// Collapse 2+ consecutive empty lines into 1 empty line (3+ \n becomes 2 \n)
|
|
924
1017
|
const cleanedContent = generatedContent.replace(/\n{3,}/g, '\n\n');
|
|
@@ -40,6 +40,24 @@ export interface RouteInfo {
|
|
|
40
40
|
inputSchemaCode?: string;
|
|
41
41
|
outputSchemaCode?: string;
|
|
42
42
|
stream?: boolean;
|
|
43
|
+
pathParams?: string[];
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Extract path parameters from a route path.
|
|
48
|
+
* Matches patterns like :id, :userId, :id?, *path, etc.
|
|
49
|
+
*/
|
|
50
|
+
export function extractPathParams(path: string): string[] {
|
|
51
|
+
const params: string[] = [];
|
|
52
|
+
const parts = path.split('/');
|
|
53
|
+
for (const part of parts) {
|
|
54
|
+
if (part.startsWith(':')) {
|
|
55
|
+
params.push(part.replace(/^:|[?+*]$/g, ''));
|
|
56
|
+
} else if (part.startsWith('*') && part.length > 1) {
|
|
57
|
+
params.push(part.substring(1).replace(/[?+*]$/g, ''));
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
return params;
|
|
43
61
|
}
|
|
44
62
|
|
|
45
63
|
/**
|
|
@@ -90,6 +108,7 @@ export async function discoverRoutes(
|
|
|
90
108
|
|
|
91
109
|
// Convert to RouteInfo for registry
|
|
92
110
|
for (const route of parsedRoutes) {
|
|
111
|
+
const pathParams = extractPathParams(route.path);
|
|
93
112
|
routeInfoList.push({
|
|
94
113
|
method: route.method.toUpperCase(),
|
|
95
114
|
path: route.path,
|
|
@@ -106,6 +125,7 @@ export async function discoverRoutes(
|
|
|
106
125
|
: route.type === 'stream'
|
|
107
126
|
? true
|
|
108
127
|
: undefined,
|
|
128
|
+
pathParams: pathParams.length > 0 ? pathParams : undefined,
|
|
109
129
|
});
|
|
110
130
|
}
|
|
111
131
|
}
|
|
@@ -10,6 +10,7 @@ import { createRequire } from 'node:module';
|
|
|
10
10
|
import type { InlineConfig, Plugin } from 'vite';
|
|
11
11
|
import type { Logger, DeployOptions } from '../../../types';
|
|
12
12
|
import { browserEnvPlugin } from './browser-env-plugin';
|
|
13
|
+
import type { BuildReportCollector } from '../../../build-report';
|
|
13
14
|
|
|
14
15
|
/**
|
|
15
16
|
* Vite plugin to flatten the output structure for index.html
|
|
@@ -56,6 +57,8 @@ export interface ViteBuildOptions {
|
|
|
56
57
|
workbenchEnabled?: boolean;
|
|
57
58
|
logger: Logger;
|
|
58
59
|
deploymentOptions?: DeployOptions;
|
|
60
|
+
/** Optional collector for structured error reporting */
|
|
61
|
+
collector?: BuildReportCollector;
|
|
59
62
|
}
|
|
60
63
|
|
|
61
64
|
/**
|
|
@@ -256,7 +259,7 @@ interface BuildResult {
|
|
|
256
259
|
* Run all builds in sequence: client -> workbench (if enabled) -> server
|
|
257
260
|
*/
|
|
258
261
|
export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Promise<BuildResult> {
|
|
259
|
-
const { rootDir, projectId = '', dev = false, logger } = options;
|
|
262
|
+
const { rootDir, projectId = '', dev = false, logger, collector } = options;
|
|
260
263
|
|
|
261
264
|
if (!dev) {
|
|
262
265
|
rmSync(join(rootDir, '.agentuity'), { force: true, recursive: true });
|
|
@@ -302,7 +305,7 @@ export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Pro
|
|
|
302
305
|
// Generate agent and route registries for type augmentation BEFORE builds
|
|
303
306
|
// (TypeScript needs these files to exist during type checking)
|
|
304
307
|
generateAgentRegistry(srcDir, agentMetadata);
|
|
305
|
-
generateRouteRegistry(srcDir, routeInfoList);
|
|
308
|
+
await generateRouteRegistry(srcDir, routeInfoList);
|
|
306
309
|
logger.debug('Agent and route registries generated');
|
|
307
310
|
|
|
308
311
|
// Check if web frontend exists
|
|
@@ -311,6 +314,7 @@ export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Pro
|
|
|
311
314
|
// 2. Build client (only if web frontend exists)
|
|
312
315
|
if (hasWebFrontend) {
|
|
313
316
|
logger.debug('Building client assets...');
|
|
317
|
+
const endClientDiagnostic = collector?.startDiagnostic('client-build');
|
|
314
318
|
const started = Date.now();
|
|
315
319
|
await runViteBuild({
|
|
316
320
|
...options,
|
|
@@ -320,6 +324,7 @@ export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Pro
|
|
|
320
324
|
});
|
|
321
325
|
result.client.included = true;
|
|
322
326
|
result.client.duration = Date.now() - started;
|
|
327
|
+
endClientDiagnostic?.();
|
|
323
328
|
} else {
|
|
324
329
|
logger.debug('Skipping client build - no src/web/index.html found');
|
|
325
330
|
}
|
|
@@ -327,6 +332,7 @@ export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Pro
|
|
|
327
332
|
// 3. Build workbench (if enabled in config)
|
|
328
333
|
if (workbenchConfig.enabled) {
|
|
329
334
|
logger.debug('Building workbench assets...');
|
|
335
|
+
const endWorkbenchDiagnostic = collector?.startDiagnostic('workbench-build');
|
|
330
336
|
const started = Date.now();
|
|
331
337
|
await runViteBuild({
|
|
332
338
|
...options,
|
|
@@ -336,17 +342,21 @@ export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Pro
|
|
|
336
342
|
});
|
|
337
343
|
result.workbench.included = true;
|
|
338
344
|
result.workbench.duration = Date.now() - started;
|
|
345
|
+
endWorkbenchDiagnostic?.();
|
|
339
346
|
}
|
|
340
347
|
|
|
341
348
|
// 4. Build server
|
|
342
349
|
logger.debug('Building server...');
|
|
350
|
+
const endServerDiagnostic = collector?.startDiagnostic('server-build');
|
|
343
351
|
const serverStarted = Date.now();
|
|
344
352
|
await runViteBuild({ ...options, mode: 'server' });
|
|
345
353
|
result.server.included = true;
|
|
346
354
|
result.server.duration = Date.now() - serverStarted;
|
|
355
|
+
endServerDiagnostic?.();
|
|
347
356
|
|
|
348
357
|
// 5. Generate metadata (after all builds complete)
|
|
349
358
|
logger.debug('Generating metadata...');
|
|
359
|
+
const endMetadataDiagnostic = collector?.startDiagnostic('metadata-generation');
|
|
350
360
|
const { generateMetadata, writeMetadataFile } = await import('./metadata-generator');
|
|
351
361
|
|
|
352
362
|
// Generate metadata
|
|
@@ -363,6 +373,7 @@ export async function runAllBuilds(options: Omit<ViteBuildOptions, 'mode'>): Pro
|
|
|
363
373
|
});
|
|
364
374
|
|
|
365
375
|
writeMetadataFile(rootDir, metadata, dev, logger);
|
|
376
|
+
endMetadataDiagnostic?.();
|
|
366
377
|
logger.debug('Registry and metadata generation complete');
|
|
367
378
|
|
|
368
379
|
logger.debug('All builds complete');
|