@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
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@agentuity/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.111",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"author": "Agentuity employees and contributors",
|
|
6
6
|
"type": "module",
|
|
@@ -40,8 +40,9 @@
|
|
|
40
40
|
"prepublishOnly": "bun run clean && bun run build"
|
|
41
41
|
},
|
|
42
42
|
"dependencies": {
|
|
43
|
-
"@agentuity/
|
|
44
|
-
"@agentuity/
|
|
43
|
+
"@agentuity/auth": "0.0.111",
|
|
44
|
+
"@agentuity/core": "0.0.111",
|
|
45
|
+
"@agentuity/server": "0.0.111",
|
|
45
46
|
"@datasert/cronjs-parser": "^1.4.0",
|
|
46
47
|
"@terascope/fetch-github-release": "^2.2.1",
|
|
47
48
|
"@vitejs/plugin-react": "^5.1.2",
|
|
@@ -58,10 +59,10 @@
|
|
|
58
59
|
"tar-fs": "^3.1.1",
|
|
59
60
|
"typescript": "^5.9.0",
|
|
60
61
|
"vite": "^7.2.7",
|
|
61
|
-
"zod": "^4.
|
|
62
|
+
"zod": "^4.3.5"
|
|
62
63
|
},
|
|
63
64
|
"devDependencies": {
|
|
64
|
-
"@agentuity/test-utils": "0.0.
|
|
65
|
+
"@agentuity/test-utils": "0.0.111",
|
|
65
66
|
"@types/adm-zip": "^0.5.7",
|
|
66
67
|
"@types/bun": "latest",
|
|
67
68
|
"@types/tar-fs": "^2.0.4",
|
|
@@ -0,0 +1,457 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Build Report
|
|
3
|
+
*
|
|
4
|
+
* Structured error/warning collection and reporting for build and deploy commands.
|
|
5
|
+
* Outputs a JSON file with a strict schema for CI tooling integration.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { writeFileSync } from 'node:fs';
|
|
9
|
+
import type { GrammarItem } from './tsc-output-parser';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Error codes for non-TypeScript errors.
|
|
13
|
+
* TypeScript errors use their native TS#### codes.
|
|
14
|
+
*/
|
|
15
|
+
export const BuildErrorCodes = {
|
|
16
|
+
// AST/Metadata errors (AST0xx)
|
|
17
|
+
AST001: 'MetadataNameMissing',
|
|
18
|
+
AST002: 'DuplicateName',
|
|
19
|
+
AST003: 'InvalidExport',
|
|
20
|
+
AST004: 'InvalidCronExpression',
|
|
21
|
+
AST005: 'InvalidAgentConfig',
|
|
22
|
+
|
|
23
|
+
// Build errors (BUILD0xx)
|
|
24
|
+
BUILD001: 'AppFileNotFound',
|
|
25
|
+
BUILD002: 'SourceDirNotFound',
|
|
26
|
+
BUILD003: 'DependencyUpgradeFailed',
|
|
27
|
+
BUILD004: 'BundleFailed',
|
|
28
|
+
BUILD005: 'EntryPointNotFound',
|
|
29
|
+
BUILD006: 'ViteBuildFailed',
|
|
30
|
+
BUILD007: 'RuntimePackageNotFound',
|
|
31
|
+
BUILD008: 'TypecheckToolFailed',
|
|
32
|
+
|
|
33
|
+
// Validation errors (VAL0xx)
|
|
34
|
+
VAL001: 'AgentIdentifierCollision',
|
|
35
|
+
VAL002: 'InvalidRoutePath',
|
|
36
|
+
VAL003: 'InvalidRouteMethod',
|
|
37
|
+
VAL004: 'SchemaValidationFailed',
|
|
38
|
+
|
|
39
|
+
// Deploy errors (DEPLOY0xx)
|
|
40
|
+
DEPLOY001: 'DeploymentCreationFailed',
|
|
41
|
+
DEPLOY002: 'UploadFailed',
|
|
42
|
+
DEPLOY003: 'DeploymentTimeout',
|
|
43
|
+
DEPLOY004: 'DeploymentFailed',
|
|
44
|
+
DEPLOY005: 'EncryptionFailed',
|
|
45
|
+
DEPLOY006: 'CDNUploadFailed',
|
|
46
|
+
} as const;
|
|
47
|
+
|
|
48
|
+
export type BuildErrorCode = keyof typeof BuildErrorCodes;
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Error scopes for categorizing errors
|
|
52
|
+
*/
|
|
53
|
+
export type ErrorScope = 'typescript' | 'ast' | 'build' | 'bundler' | 'validation' | 'deploy';
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* File-specific error with location information
|
|
57
|
+
*/
|
|
58
|
+
export interface FileError {
|
|
59
|
+
type: 'file';
|
|
60
|
+
scope: ErrorScope;
|
|
61
|
+
path: string;
|
|
62
|
+
line: number;
|
|
63
|
+
column: number;
|
|
64
|
+
message: string;
|
|
65
|
+
code?: string;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* General error without file location
|
|
70
|
+
*/
|
|
71
|
+
export interface GeneralError {
|
|
72
|
+
type: 'general';
|
|
73
|
+
scope: ErrorScope;
|
|
74
|
+
message: string;
|
|
75
|
+
code?: string;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* Union type for all build errors
|
|
80
|
+
*/
|
|
81
|
+
export type BuildError = FileError | GeneralError;
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Union type for all build warnings (same structure as errors)
|
|
85
|
+
*/
|
|
86
|
+
export type BuildWarning = FileError | GeneralError;
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Diagnostic timing information for a build phase
|
|
90
|
+
*/
|
|
91
|
+
export interface BuildDiagnostic {
|
|
92
|
+
name: string;
|
|
93
|
+
startedAt: string;
|
|
94
|
+
completedAt: string;
|
|
95
|
+
durationMs: number;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* Complete build report structure
|
|
100
|
+
*/
|
|
101
|
+
export interface BuildReport {
|
|
102
|
+
success: boolean;
|
|
103
|
+
errors: BuildError[];
|
|
104
|
+
warnings: BuildWarning[];
|
|
105
|
+
diagnostics: BuildDiagnostic[];
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Diagnostic phases for timing
|
|
110
|
+
*/
|
|
111
|
+
export const DiagnosticPhases = [
|
|
112
|
+
'typecheck',
|
|
113
|
+
'client-build',
|
|
114
|
+
'workbench-build',
|
|
115
|
+
'server-build',
|
|
116
|
+
'metadata-generation',
|
|
117
|
+
'zip-package',
|
|
118
|
+
'encrypt',
|
|
119
|
+
'code-upload',
|
|
120
|
+
'cdn-upload',
|
|
121
|
+
'deployment-wait',
|
|
122
|
+
] as const;
|
|
123
|
+
|
|
124
|
+
export type DiagnosticPhase = (typeof DiagnosticPhases)[number];
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Active diagnostic tracker
|
|
128
|
+
*/
|
|
129
|
+
interface ActiveDiagnostic {
|
|
130
|
+
name: string;
|
|
131
|
+
startedAt: Date;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
/**
|
|
135
|
+
* Build Report Collector
|
|
136
|
+
*
|
|
137
|
+
* Collects errors, warnings, and diagnostic timing information throughout
|
|
138
|
+
* the build/deploy pipeline. Can be configured to automatically write
|
|
139
|
+
* the report on process exit.
|
|
140
|
+
*/
|
|
141
|
+
export class BuildReportCollector {
|
|
142
|
+
private errors: BuildError[] = [];
|
|
143
|
+
private warnings: BuildWarning[] = [];
|
|
144
|
+
private diagnostics: BuildDiagnostic[] = [];
|
|
145
|
+
private activeDiagnostics: Map<string, ActiveDiagnostic> = new Map();
|
|
146
|
+
private outputPath: string | null = null;
|
|
147
|
+
private autoWriteEnabled = false;
|
|
148
|
+
private written = false;
|
|
149
|
+
|
|
150
|
+
private beforeExitHandler: (() => void) | null = null;
|
|
151
|
+
private sigintHandler: (() => void) | null = null;
|
|
152
|
+
private sigtermHandler: (() => void) | null = null;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Set the output path for the report file
|
|
156
|
+
*/
|
|
157
|
+
setOutputPath(path: string): void {
|
|
158
|
+
this.outputPath = path;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/**
|
|
162
|
+
* Enable automatic writing of the report on process exit.
|
|
163
|
+
* This ensures the report is written even if the process exits unexpectedly.
|
|
164
|
+
*/
|
|
165
|
+
enableAutoWrite(): void {
|
|
166
|
+
if (this.autoWriteEnabled || !this.outputPath) return;
|
|
167
|
+
|
|
168
|
+
this.autoWriteEnabled = true;
|
|
169
|
+
|
|
170
|
+
// Use beforeExit for graceful exits
|
|
171
|
+
this.beforeExitHandler = () => {
|
|
172
|
+
this.writeSync();
|
|
173
|
+
};
|
|
174
|
+
process.once('beforeExit', this.beforeExitHandler);
|
|
175
|
+
|
|
176
|
+
// Handle SIGINT/SIGTERM with process.once to avoid stacking handlers
|
|
177
|
+
this.sigintHandler = () => {
|
|
178
|
+
this.writeSync();
|
|
179
|
+
process.exit(130);
|
|
180
|
+
};
|
|
181
|
+
this.sigtermHandler = () => {
|
|
182
|
+
this.writeSync();
|
|
183
|
+
process.exit(143);
|
|
184
|
+
};
|
|
185
|
+
process.once('SIGINT', this.sigintHandler);
|
|
186
|
+
process.once('SIGTERM', this.sigtermHandler);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
/**
|
|
190
|
+
* Disable automatic writing and remove signal handlers.
|
|
191
|
+
* Call this when done with the collector to prevent handler conflicts.
|
|
192
|
+
*/
|
|
193
|
+
disableAutoWrite(): void {
|
|
194
|
+
if (!this.autoWriteEnabled) return;
|
|
195
|
+
|
|
196
|
+
this.autoWriteEnabled = false;
|
|
197
|
+
|
|
198
|
+
if (this.beforeExitHandler) {
|
|
199
|
+
process.removeListener('beforeExit', this.beforeExitHandler);
|
|
200
|
+
this.beforeExitHandler = null;
|
|
201
|
+
}
|
|
202
|
+
if (this.sigintHandler) {
|
|
203
|
+
process.removeListener('SIGINT', this.sigintHandler);
|
|
204
|
+
this.sigintHandler = null;
|
|
205
|
+
}
|
|
206
|
+
if (this.sigtermHandler) {
|
|
207
|
+
process.removeListener('SIGTERM', this.sigtermHandler);
|
|
208
|
+
this.sigtermHandler = null;
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
/**
|
|
213
|
+
* Add TypeScript errors from parsed tsc output
|
|
214
|
+
*/
|
|
215
|
+
addTypeScriptErrors(items: GrammarItem[]): void {
|
|
216
|
+
for (const item of items) {
|
|
217
|
+
if (item.type !== 'Item' || !item.value) continue;
|
|
218
|
+
|
|
219
|
+
const val = item.value;
|
|
220
|
+
const isError = val.tsError?.value?.type === 'error';
|
|
221
|
+
const isWarning = val.tsError?.value?.type === 'warning';
|
|
222
|
+
|
|
223
|
+
if (!isError && !isWarning) continue;
|
|
224
|
+
|
|
225
|
+
const entry: FileError = {
|
|
226
|
+
type: 'file',
|
|
227
|
+
scope: 'typescript',
|
|
228
|
+
path: val.path?.value ?? 'unknown',
|
|
229
|
+
line: val.cursor?.value?.line ?? 0,
|
|
230
|
+
column: val.cursor?.value?.col ?? 0,
|
|
231
|
+
message: (val.message?.value ?? '').trim(),
|
|
232
|
+
code: val.tsError?.value?.errorString,
|
|
233
|
+
};
|
|
234
|
+
|
|
235
|
+
if (isError) {
|
|
236
|
+
this.errors.push(entry);
|
|
237
|
+
} else {
|
|
238
|
+
this.warnings.push(entry);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/**
|
|
244
|
+
* Add a file-specific error
|
|
245
|
+
*/
|
|
246
|
+
addFileError(
|
|
247
|
+
scope: ErrorScope,
|
|
248
|
+
path: string,
|
|
249
|
+
line: number,
|
|
250
|
+
column: number,
|
|
251
|
+
message: string,
|
|
252
|
+
code?: string
|
|
253
|
+
): void {
|
|
254
|
+
this.errors.push({
|
|
255
|
+
type: 'file',
|
|
256
|
+
scope,
|
|
257
|
+
path,
|
|
258
|
+
line,
|
|
259
|
+
column,
|
|
260
|
+
message,
|
|
261
|
+
code,
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* Add a general error without file location
|
|
267
|
+
*/
|
|
268
|
+
addGeneralError(scope: ErrorScope, message: string, code?: string): void {
|
|
269
|
+
this.errors.push({
|
|
270
|
+
type: 'general',
|
|
271
|
+
scope,
|
|
272
|
+
message,
|
|
273
|
+
code,
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
/**
|
|
278
|
+
* Add a file-specific warning
|
|
279
|
+
*/
|
|
280
|
+
addFileWarning(
|
|
281
|
+
scope: ErrorScope,
|
|
282
|
+
path: string,
|
|
283
|
+
line: number,
|
|
284
|
+
column: number,
|
|
285
|
+
message: string,
|
|
286
|
+
code?: string
|
|
287
|
+
): void {
|
|
288
|
+
this.warnings.push({
|
|
289
|
+
type: 'file',
|
|
290
|
+
scope,
|
|
291
|
+
path,
|
|
292
|
+
line,
|
|
293
|
+
column,
|
|
294
|
+
message,
|
|
295
|
+
code,
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Add a general warning without file location
|
|
301
|
+
*/
|
|
302
|
+
addGeneralWarning(scope: ErrorScope, message: string, code?: string): void {
|
|
303
|
+
this.warnings.push({
|
|
304
|
+
type: 'general',
|
|
305
|
+
scope,
|
|
306
|
+
message,
|
|
307
|
+
code,
|
|
308
|
+
});
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
/**
|
|
312
|
+
* Start timing a diagnostic phase
|
|
313
|
+
* @returns A function to call when the phase completes
|
|
314
|
+
*/
|
|
315
|
+
startDiagnostic(name: string): () => void {
|
|
316
|
+
const startedAt = new Date();
|
|
317
|
+
this.activeDiagnostics.set(name, { name, startedAt });
|
|
318
|
+
|
|
319
|
+
return () => {
|
|
320
|
+
this.endDiagnostic(name);
|
|
321
|
+
};
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* End a diagnostic phase
|
|
326
|
+
*/
|
|
327
|
+
private endDiagnostic(name: string): void {
|
|
328
|
+
const active = this.activeDiagnostics.get(name);
|
|
329
|
+
if (!active) return;
|
|
330
|
+
|
|
331
|
+
const completedAt = new Date();
|
|
332
|
+
const durationMs = completedAt.getTime() - active.startedAt.getTime();
|
|
333
|
+
|
|
334
|
+
this.diagnostics.push({
|
|
335
|
+
name,
|
|
336
|
+
startedAt: active.startedAt.toISOString(),
|
|
337
|
+
completedAt: completedAt.toISOString(),
|
|
338
|
+
durationMs,
|
|
339
|
+
});
|
|
340
|
+
|
|
341
|
+
this.activeDiagnostics.delete(name);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
/**
|
|
345
|
+
* Check if there are any errors
|
|
346
|
+
*/
|
|
347
|
+
hasErrors(): boolean {
|
|
348
|
+
return this.errors.length > 0;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
* Check if there are any warnings
|
|
353
|
+
*/
|
|
354
|
+
hasWarnings(): boolean {
|
|
355
|
+
return this.warnings.length > 0;
|
|
356
|
+
}
|
|
357
|
+
|
|
358
|
+
/**
|
|
359
|
+
* Get the error count
|
|
360
|
+
*/
|
|
361
|
+
getErrorCount(): number {
|
|
362
|
+
return this.errors.length;
|
|
363
|
+
}
|
|
364
|
+
|
|
365
|
+
/**
|
|
366
|
+
* Get the warning count
|
|
367
|
+
*/
|
|
368
|
+
getWarningCount(): number {
|
|
369
|
+
return this.warnings.length;
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Generate the complete build report
|
|
374
|
+
*/
|
|
375
|
+
toReport(): BuildReport {
|
|
376
|
+
// Complete any active diagnostics - collect keys first to avoid
|
|
377
|
+
// iterating while modifying the map
|
|
378
|
+
const activeKeys = [...this.activeDiagnostics.keys()];
|
|
379
|
+
for (const name of activeKeys) {
|
|
380
|
+
this.endDiagnostic(name);
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
return {
|
|
384
|
+
success: this.errors.length === 0,
|
|
385
|
+
errors: [...this.errors],
|
|
386
|
+
warnings: [...this.warnings],
|
|
387
|
+
diagnostics: [...this.diagnostics],
|
|
388
|
+
};
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
/**
|
|
392
|
+
* Write the report to the configured output path asynchronously
|
|
393
|
+
*/
|
|
394
|
+
async write(): Promise<void> {
|
|
395
|
+
if (!this.outputPath || this.written) return;
|
|
396
|
+
|
|
397
|
+
this.written = true;
|
|
398
|
+
const report = this.toReport();
|
|
399
|
+
const file = Bun.file(this.outputPath);
|
|
400
|
+
await file.write(JSON.stringify(report, null, '\t'));
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
/**
|
|
404
|
+
* Write the report synchronously (for exit handlers)
|
|
405
|
+
*/
|
|
406
|
+
writeSync(): void {
|
|
407
|
+
if (!this.outputPath || this.written) return;
|
|
408
|
+
|
|
409
|
+
this.written = true;
|
|
410
|
+
const report = this.toReport();
|
|
411
|
+
writeFileSync(this.outputPath, JSON.stringify(report, null, '\t'));
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
/**
|
|
415
|
+
* Force write the report (bypasses the written flag)
|
|
416
|
+
* Use this when you want to update the report file mid-process
|
|
417
|
+
*/
|
|
418
|
+
async forceWrite(): Promise<void> {
|
|
419
|
+
if (!this.outputPath) return;
|
|
420
|
+
|
|
421
|
+
const report = this.toReport();
|
|
422
|
+
const file = Bun.file(this.outputPath);
|
|
423
|
+
await file.write(JSON.stringify(report, null, '\t'));
|
|
424
|
+
this.written = true;
|
|
425
|
+
}
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
/**
|
|
429
|
+
* Global collector instance for use across the build pipeline.
|
|
430
|
+
* Commands should create their own collector and pass it through,
|
|
431
|
+
* but this provides a fallback for error handling in deeply nested code.
|
|
432
|
+
*/
|
|
433
|
+
let globalCollector: BuildReportCollector | null = null;
|
|
434
|
+
|
|
435
|
+
/**
|
|
436
|
+
* Set the global collector instance
|
|
437
|
+
*/
|
|
438
|
+
export function setGlobalCollector(collector: BuildReportCollector): void {
|
|
439
|
+
globalCollector = collector;
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
/**
|
|
443
|
+
* Get the global collector instance (may be null)
|
|
444
|
+
*/
|
|
445
|
+
export function getGlobalCollector(): BuildReportCollector | null {
|
|
446
|
+
return globalCollector;
|
|
447
|
+
}
|
|
448
|
+
|
|
449
|
+
/**
|
|
450
|
+
* Clear the global collector instance and clean up its signal handlers
|
|
451
|
+
*/
|
|
452
|
+
export function clearGlobalCollector(): void {
|
|
453
|
+
if (globalCollector) {
|
|
454
|
+
globalCollector.disableAutoWrite();
|
|
455
|
+
}
|
|
456
|
+
globalCollector = null;
|
|
457
|
+
}
|
package/src/cli.ts
CHANGED
|
@@ -15,7 +15,7 @@ import type {
|
|
|
15
15
|
} from './types';
|
|
16
16
|
import { showBanner, generateBanner } from './banner';
|
|
17
17
|
import { requireAuth, optionalAuth, requireOrg, optionalOrg as selectOptionalOrg } from './auth';
|
|
18
|
-
import { listRegions, type RegionList } from '@agentuity/server';
|
|
18
|
+
import { listRegions, type RegionList, ValidationOutputError } from '@agentuity/server';
|
|
19
19
|
import enquirer from 'enquirer';
|
|
20
20
|
import * as tui from './tui';
|
|
21
21
|
import { parseArgsSchema, parseOptionsSchema, buildValidationInput } from './schema-parser';
|
|
@@ -26,6 +26,22 @@ import { getCommand } from './command-prefix';
|
|
|
26
26
|
import { isValidateMode, outputValidation, type ValidationResult } from './output';
|
|
27
27
|
import { StructuredError } from '@agentuity/core';
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* Check if an error is a CLI input validation error (Zod error from schema parsing),
|
|
31
|
+
* and not an API response validation error (ValidationOutputError).
|
|
32
|
+
*/
|
|
33
|
+
function isCLIValidationError(error: unknown): boolean {
|
|
34
|
+
if (!error || typeof error !== 'object' || !('issues' in error)) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
// ValidationOutputError from API responses should NOT be treated as CLI validation errors
|
|
38
|
+
if (error instanceof ValidationOutputError) {
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
// Check for Zod error structure (has name 'ZodError' or is from SchemaValidationError)
|
|
42
|
+
return true;
|
|
43
|
+
}
|
|
44
|
+
|
|
29
45
|
const APIClientConfigError = StructuredError('APIClientConfigError');
|
|
30
46
|
|
|
31
47
|
function createAPIClient(baseCtx: CommandContext, config: Config | null): APIClient {
|
|
@@ -1143,7 +1159,7 @@ async function registerSubcommand(
|
|
|
1143
1159
|
subcommand.webUrl
|
|
1144
1160
|
);
|
|
1145
1161
|
} catch (error) {
|
|
1146
|
-
if (error
|
|
1162
|
+
if (isCLIValidationError(error)) {
|
|
1147
1163
|
handleValidationError(error, getFullCommandPath(cmd), baseCtx);
|
|
1148
1164
|
}
|
|
1149
1165
|
handleProjectConfigError(
|
|
@@ -1322,7 +1338,7 @@ async function registerSubcommand(
|
|
|
1322
1338
|
subcommand.webUrl
|
|
1323
1339
|
);
|
|
1324
1340
|
} catch (error) {
|
|
1325
|
-
if (error
|
|
1341
|
+
if (isCLIValidationError(error)) {
|
|
1326
1342
|
handleValidationError(error, getFullCommandPath(cmd), baseCtx);
|
|
1327
1343
|
}
|
|
1328
1344
|
handleProjectConfigError(
|
|
@@ -1447,7 +1463,7 @@ async function registerSubcommand(
|
|
|
1447
1463
|
subcommand.webUrl
|
|
1448
1464
|
);
|
|
1449
1465
|
} catch (error) {
|
|
1450
|
-
if (error
|
|
1466
|
+
if (isCLIValidationError(error)) {
|
|
1451
1467
|
handleValidationError(error, getFullCommandPath(cmd), baseCtx);
|
|
1452
1468
|
}
|
|
1453
1469
|
handleProjectConfigError(
|
|
@@ -85,10 +85,12 @@ export async function generateEntryFile(options: GenerateEntryOptions): Promise<
|
|
|
85
85
|
imports.push(`import { type LogLevel } from '@agentuity/core';`);
|
|
86
86
|
|
|
87
87
|
// Generate route mounting code for all discovered routes
|
|
88
|
+
// Sort route files for deterministic output
|
|
89
|
+
const sortedRouteFiles = [...routeFiles].sort();
|
|
88
90
|
const routeImportsAndMounts: string[] = [];
|
|
89
91
|
let routeIndex = 0;
|
|
90
92
|
|
|
91
|
-
for (const routeFile of
|
|
93
|
+
for (const routeFile of sortedRouteFiles) {
|
|
92
94
|
// Convert src/api/auth/route.ts -> auth/route
|
|
93
95
|
const relativePath = routeFile.replace(/^src\/api\//, '').replace(/\.tsx?$/, '');
|
|
94
96
|
|
package/src/cmd/build/index.ts
CHANGED
|
@@ -6,6 +6,7 @@ import * as tui from '../../tui';
|
|
|
6
6
|
import { getCommand } from '../../command-prefix';
|
|
7
7
|
import { ErrorCode } from '../../errors';
|
|
8
8
|
import { typecheck } from './typecheck';
|
|
9
|
+
import { BuildReportCollector, setGlobalCollector, clearGlobalCollector } from '../../build-report';
|
|
9
10
|
|
|
10
11
|
const BuildResponseSchema = z.object({
|
|
11
12
|
success: z.boolean().describe('Whether the build succeeded'),
|
|
@@ -36,6 +37,10 @@ export const command = createCommand({
|
|
|
36
37
|
.default(false)
|
|
37
38
|
.optional()
|
|
38
39
|
.describe('Skip typecheck after build'),
|
|
40
|
+
reportFile: z
|
|
41
|
+
.string()
|
|
42
|
+
.optional()
|
|
43
|
+
.describe('file path to save build report JSON with errors, warnings, and diagnostics'),
|
|
39
44
|
}),
|
|
40
45
|
response: BuildResponseSchema,
|
|
41
46
|
},
|
|
@@ -43,6 +48,14 @@ export const command = createCommand({
|
|
|
43
48
|
async handler(ctx) {
|
|
44
49
|
const { opts, projectDir, project } = ctx;
|
|
45
50
|
|
|
51
|
+
// Initialize build report collector if reportFile is specified
|
|
52
|
+
const collector = new BuildReportCollector();
|
|
53
|
+
if (opts.reportFile) {
|
|
54
|
+
collector.setOutputPath(opts.reportFile);
|
|
55
|
+
collector.enableAutoWrite();
|
|
56
|
+
setGlobalCollector(collector);
|
|
57
|
+
}
|
|
58
|
+
|
|
46
59
|
const absoluteProjectDir = resolve(projectDir);
|
|
47
60
|
const outDir = opts.outdir ? resolve(opts.outdir) : join(absoluteProjectDir, '.agentuity');
|
|
48
61
|
|
|
@@ -59,6 +72,7 @@ export const command = createCommand({
|
|
|
59
72
|
orgId: project?.orgId,
|
|
60
73
|
region: project?.region ?? 'local',
|
|
61
74
|
logger: ctx.logger,
|
|
75
|
+
collector,
|
|
62
76
|
});
|
|
63
77
|
|
|
64
78
|
// Copy profile-specific .env file AFTER bundling (bundler clears outDir first)
|
|
@@ -79,7 +93,10 @@ export const command = createCommand({
|
|
|
79
93
|
if (!opts.dev && !opts.skipTypeCheck) {
|
|
80
94
|
try {
|
|
81
95
|
tui.info('Running type check...');
|
|
82
|
-
const
|
|
96
|
+
const endTypecheckDiagnostic = collector.startDiagnostic('typecheck');
|
|
97
|
+
const typeResult = await typecheck(absoluteProjectDir, { collector });
|
|
98
|
+
endTypecheckDiagnostic();
|
|
99
|
+
|
|
83
100
|
if (typeResult.success) {
|
|
84
101
|
tui.success('Type check passed');
|
|
85
102
|
} else {
|
|
@@ -88,10 +105,24 @@ export const command = createCommand({
|
|
|
88
105
|
console.error('');
|
|
89
106
|
const msg =
|
|
90
107
|
'errors' in typeResult ? 'Fix type errors before building' : 'Build error';
|
|
108
|
+
|
|
109
|
+
// Write report before fatal exit
|
|
110
|
+
if (opts.reportFile) {
|
|
111
|
+
await collector.forceWrite();
|
|
112
|
+
}
|
|
113
|
+
clearGlobalCollector();
|
|
91
114
|
tui.fatal(msg, ErrorCode.BUILD_FAILED);
|
|
92
115
|
}
|
|
93
116
|
} catch (error: unknown) {
|
|
94
117
|
const errorMsg = error instanceof Error ? error.message : String(error);
|
|
118
|
+
collector.addGeneralError('typescript', errorMsg, 'BUILD008');
|
|
119
|
+
|
|
120
|
+
// Write report before fatal exit
|
|
121
|
+
if (opts.reportFile) {
|
|
122
|
+
await collector.forceWrite();
|
|
123
|
+
}
|
|
124
|
+
clearGlobalCollector();
|
|
125
|
+
|
|
95
126
|
tui.error(`Type check failed to run: ${errorMsg}`);
|
|
96
127
|
tui.fatal(
|
|
97
128
|
'Unable to run TypeScript type checking. Ensure TypeScript is installed.',
|
|
@@ -102,6 +133,12 @@ export const command = createCommand({
|
|
|
102
133
|
|
|
103
134
|
tui.success('Build complete');
|
|
104
135
|
|
|
136
|
+
// Write final report on success
|
|
137
|
+
if (opts.reportFile) {
|
|
138
|
+
await collector.forceWrite();
|
|
139
|
+
}
|
|
140
|
+
clearGlobalCollector();
|
|
141
|
+
|
|
105
142
|
return {
|
|
106
143
|
success: true,
|
|
107
144
|
bundlePath: outDir,
|
|
@@ -109,11 +146,24 @@ export const command = createCommand({
|
|
|
109
146
|
dev: opts.dev || false,
|
|
110
147
|
};
|
|
111
148
|
} catch (error: unknown) {
|
|
149
|
+
// Add error to collector
|
|
112
150
|
if (error instanceof AggregateError) {
|
|
113
151
|
const ae = error as AggregateError;
|
|
114
152
|
for (const e of ae.errors) {
|
|
153
|
+
collector.addGeneralError('build', e.message, 'BUILD004');
|
|
115
154
|
tui.error(e.message);
|
|
116
155
|
}
|
|
156
|
+
} else {
|
|
157
|
+
collector.addGeneralError('build', String(error), 'BUILD004');
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Write report before fatal exit
|
|
161
|
+
if (opts.reportFile) {
|
|
162
|
+
await collector.forceWrite();
|
|
163
|
+
}
|
|
164
|
+
clearGlobalCollector();
|
|
165
|
+
|
|
166
|
+
if (error instanceof AggregateError) {
|
|
117
167
|
tui.fatal('Build failed', ErrorCode.BUILD_FAILED);
|
|
118
168
|
} else {
|
|
119
169
|
tui.fatal(`Build failed: ${error}`, ErrorCode.BUILD_FAILED);
|