@nu-art/build-and-install 0.400.14 → 0.401.1

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.
Files changed (156) hide show
  1. package/BuildAndInstall.d.ts +40 -0
  2. package/BuildAndInstall.js +155 -0
  3. package/build-and-install-v3.d.ts +1 -32
  4. package/build-and-install-v3.js +1 -154
  5. package/build-and-install.js +11 -11
  6. package/config/consts.d.ts +43 -0
  7. package/config/consts.js +42 -0
  8. package/{core → config}/package/consts.d.ts +1 -1
  9. package/{core → config}/types/project-config.d.ts +3 -0
  10. package/core/FilesCache.d.ts +50 -0
  11. package/core/FilesCache.js +76 -0
  12. package/core/Unit_HelpPrinter.d.ts +16 -0
  13. package/core/Unit_HelpPrinter.js +47 -0
  14. package/core/params/params.d.ts +1 -41
  15. package/core/params/params.js +1 -334
  16. package/core/params.d.ts +50 -0
  17. package/core/params.js +441 -0
  18. package/{v3/core → core}/types.d.ts +1 -1
  19. package/{v3/UnitsDependencyMapper → dependencies}/UnitsDependencyMapper.d.ts +21 -1
  20. package/{v3/UnitsDependencyMapper → dependencies}/UnitsDependencyMapper.js +26 -3
  21. package/dependencies/types.d.ts +1 -0
  22. package/dependencies/types.js +1 -0
  23. package/exceptions/PhaseAggregatedException.d.ts +34 -0
  24. package/{core/exceptions → exceptions}/PhaseAggregatedException.js +26 -0
  25. package/exceptions/UnitPhaseException.d.ts +20 -0
  26. package/exceptions/UnitPhaseException.js +21 -0
  27. package/exports/ExportIndexCache.d.ts +25 -0
  28. package/exports/ExportIndexCache.js +115 -0
  29. package/exports/ExportMapper.d.ts +43 -0
  30. package/exports/ExportMapper.js +519 -0
  31. package/exports/IndicesMcpServer.d.ts +22 -0
  32. package/exports/IndicesMcpServer.js +220 -0
  33. package/exports/types.js +3 -0
  34. package/package.json +20 -9
  35. package/phases/PhaseManager.d.ts +130 -0
  36. package/phases/PhaseManager.js +267 -0
  37. package/{v3/phase → phases/definitions}/consts.d.ts +36 -0
  38. package/{v3/phase → phases/definitions}/consts.js +45 -2
  39. package/phases/definitions/types.d.ts +40 -0
  40. package/phases/index.d.ts +2 -0
  41. package/phases/index.js +2 -0
  42. package/run.js +10 -0
  43. package/runtime/RunningStatusHandler.d.ts +104 -0
  44. package/runtime/RunningStatusHandler.js +153 -0
  45. package/runtime/types.d.ts +1 -0
  46. package/runtime/types.js +2 -0
  47. package/{defaults → templates}/consts.d.ts +9 -0
  48. package/{defaults → templates}/consts.js +12 -2
  49. package/templates/firebase/functions/cloudbuild.yaml +17 -0
  50. package/templates/firebase/functions/dockerfile +19 -0
  51. package/templates/firebase/functions/service.yaml +49 -0
  52. package/{v3/units → units/base}/BaseUnit.d.ts +35 -3
  53. package/{v3/units → units/base}/BaseUnit.js +22 -2
  54. package/units/base/ProjectUnit.d.ts +32 -0
  55. package/units/base/ProjectUnit.js +25 -0
  56. package/units/base/types.js +1 -0
  57. package/units/discovery/UnitsMapper.d.ts +69 -0
  58. package/{v3/UnitsMapper → units/discovery}/UnitsMapper.js +51 -3
  59. package/units/discovery/resolvers/UnitMapper_Base.d.ts +65 -0
  60. package/units/discovery/resolvers/UnitMapper_Base.js +46 -0
  61. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseFunction.d.ts +5 -3
  62. package/units/discovery/resolvers/UnitMapper_FirebaseFunction.js +105 -0
  63. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseHosting.d.ts +3 -2
  64. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_FirebaseHosting.js +14 -10
  65. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_Node.d.ts +1 -1
  66. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_Node.js +2 -2
  67. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeLib.d.ts +24 -1
  68. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeLib.js +24 -1
  69. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeProject.d.ts +22 -1
  70. package/{v3/UnitsMapper → units/discovery}/resolvers/UnitMapper_NodeProject.js +22 -1
  71. package/units/discovery/types.js +1 -0
  72. package/units/implementations/Unit_NodeProject.d.ts +59 -0
  73. package/{v3/units → units/implementations}/Unit_NodeProject.js +67 -6
  74. package/units/implementations/Unit_PackageJson.d.ts +56 -0
  75. package/{v3/units → units/implementations}/Unit_PackageJson.js +39 -3
  76. package/{v3/units → units/implementations}/Unit_TypescriptLib.d.ts +40 -4
  77. package/{v3/units → units/implementations}/Unit_TypescriptLib.js +167 -17
  78. package/units/implementations/firebase/Unit_FirebaseFunctionsApp.d.ts +233 -0
  79. package/units/implementations/firebase/Unit_FirebaseFunctionsApp.js +804 -0
  80. package/units/implementations/firebase/Unit_FirebaseHostingApp.d.ts +113 -0
  81. package/units/implementations/firebase/Unit_FirebaseHostingApp.js +320 -0
  82. package/units/implementations/firebase/common.d.ts +26 -0
  83. package/units/implementations/firebase/common.js +65 -0
  84. package/units/index.d.ts +6 -0
  85. package/units/index.js +6 -0
  86. package/v3/core/Unit_HelpPrinter.d.ts +1 -16
  87. package/v3/core/Unit_HelpPrinter.js +1 -47
  88. package/workspace/Workspace.d.ts +95 -0
  89. package/workspace/Workspace.js +192 -0
  90. package/core/consts.d.ts +0 -13
  91. package/core/consts.js +0 -12
  92. package/core/exceptions/PhaseAggregatedException.d.ts +0 -8
  93. package/core/exceptions/UnitPhaseException.d.ts +0 -5
  94. package/core/exceptions/UnitPhaseException.js +0 -6
  95. package/old/PhaseRunnerDispatcher.d.ts +0 -24
  96. package/old/PhaseRunnerDispatcher.js +0 -32
  97. package/old/runner-dispatchers.d.ts +0 -10
  98. package/old/runner-dispatchers.js +0 -3
  99. package/v3/PhaseManager.d.ts +0 -26
  100. package/v3/PhaseManager.js +0 -158
  101. package/v3/RunningStatusHandler.d.ts +0 -18
  102. package/v3/RunningStatusHandler.js +0 -67
  103. package/v3/UnitsMapper/UnitsMapper.d.ts +0 -21
  104. package/v3/UnitsMapper/resolvers/UnitMapper_Base.d.ts +0 -23
  105. package/v3/UnitsMapper/resolvers/UnitMapper_Base.js +0 -16
  106. package/v3/UnitsMapper/resolvers/UnitMapper_FirebaseFunction.js +0 -66
  107. package/v3/core/FilesCache.d.ts +0 -7
  108. package/v3/core/FilesCache.js +0 -33
  109. package/v3/phase/types.d.ts +0 -9
  110. package/v3/units/ProjectUnit.d.ts +0 -18
  111. package/v3/units/ProjectUnit.js +0 -11
  112. package/v3/units/Unit_NodeProject.d.ts +0 -30
  113. package/v3/units/Unit_PackageJson.d.ts +0 -17
  114. package/v3/units/firebase/Unit_FirebaseFunctionsApp.d.ts +0 -64
  115. package/v3/units/firebase/Unit_FirebaseFunctionsApp.js +0 -306
  116. package/v3/units/firebase/Unit_FirebaseHostingApp.d.ts +0 -49
  117. package/v3/units/firebase/Unit_FirebaseHostingApp.js +0 -114
  118. package/v3/units/firebase/common.d.ts +0 -3
  119. package/v3/units/firebase/common.js +0 -13
  120. package/v3/units/index.d.ts +0 -6
  121. package/v3/units/index.js +0 -6
  122. /package/{core → config}/package/consts.js +0 -0
  123. /package/{core → config}/types/configs/firebasejson.d.ts +0 -0
  124. /package/{core → config}/types/configs/firebasejson.js +0 -0
  125. /package/{core → config}/types/configs/firebaserc.d.ts +0 -0
  126. /package/{core → config}/types/configs/firebaserc.js +0 -0
  127. /package/{core → config}/types/configs/index.d.ts +0 -0
  128. /package/{core → config}/types/configs/index.js +0 -0
  129. /package/{core → config}/types/configs/package-json.d.ts +0 -0
  130. /package/{core → config}/types/configs/package-json.js +0 -0
  131. /package/{core → config}/types/core.d.ts +0 -0
  132. /package/{core → config}/types/core.js +0 -0
  133. /package/{core → config}/types/index.d.ts +0 -0
  134. /package/{core → config}/types/index.js +0 -0
  135. /package/{core → config}/types/package/index.d.ts +0 -0
  136. /package/{core → config}/types/package/index.js +0 -0
  137. /package/{core → config}/types/package/package.d.ts +0 -0
  138. /package/{core → config}/types/package/package.js +0 -0
  139. /package/{core → config}/types/package/runtime-package.d.ts +0 -0
  140. /package/{core → config}/types/package/runtime-package.js +0 -0
  141. /package/{core → config}/types/project-config.js +0 -0
  142. /package/{v3/core → core}/types.js +0 -0
  143. /package/{v3/UnitsMapper/types.js → exports/types.d.ts} +0 -0
  144. /package/{v3/phase → phases/definitions}/index.d.ts +0 -0
  145. /package/{v3/phase → phases/definitions}/index.js +0 -0
  146. /package/{v3/phase → phases/definitions}/types.js +0 -0
  147. /package/{v3/units/types.js → run.d.ts} +0 -0
  148. /package/{defaults/backend-proxy → templates/backend/proxy}/proxy._ts +0 -0
  149. /package/{defaults/.firebase_config → templates/firebase/config}/database.rules.json +0 -0
  150. /package/{defaults/.firebase_config → templates/firebase/config}/firestore.indexes.json +0 -0
  151. /package/{defaults/.firebase_config → templates/firebase/config}/firestore.rules +0 -0
  152. /package/{defaults/.firebase_config → templates/firebase/config}/storage.rules +0 -0
  153. /package/{v3/units → units/base}/types.d.ts +0 -0
  154. /package/{v3/UnitsMapper → units/discovery}/resolvers/index.d.ts +0 -0
  155. /package/{v3/UnitsMapper → units/discovery}/resolvers/index.js +0 -0
  156. /package/{v3/UnitsMapper → units/discovery}/types.d.ts +0 -0
@@ -0,0 +1,22 @@
1
+ import { ProjectUnit } from '../units/base/ProjectUnit.js';
2
+ import { Logger } from '@nu-art/ts-common';
3
+ export declare class IndicesMcpServer extends Logger {
4
+ private server?;
5
+ private port;
6
+ private projectRoot;
7
+ private packages;
8
+ constructor(port: number, projectRoot: string, packages: ProjectUnit[]);
9
+ start(): Promise<void>;
10
+ stop(): Promise<void>;
11
+ private handleRequest;
12
+ private handleHealth;
13
+ private handlePackages;
14
+ private handlePackageRoutes;
15
+ private handleGetAllExports;
16
+ private handleGetByName;
17
+ private handleGetByFile;
18
+ private handleGetByType;
19
+ private handleStale;
20
+ private sendJson;
21
+ private sendError;
22
+ }
@@ -0,0 +1,220 @@
1
+ import { createServer } from 'http';
2
+ import { URL } from 'url';
3
+ import { ExportIndexCache } from './ExportIndexCache.js';
4
+ import { Unit_TypescriptLib } from '../units/implementations/Unit_TypescriptLib.js';
5
+ import { Logger } from '@nu-art/ts-common';
6
+ export class IndicesMcpServer extends Logger {
7
+ server;
8
+ port;
9
+ projectRoot;
10
+ packages;
11
+ constructor(port, projectRoot, packages) {
12
+ super();
13
+ this.port = port;
14
+ this.projectRoot = projectRoot;
15
+ this.packages = packages;
16
+ }
17
+ async start() {
18
+ return new Promise((resolve, reject) => {
19
+ this.server = createServer((req, res) => this.handleRequest(req, res));
20
+ this.server.listen(this.port, () => {
21
+ this.logInfo(`Export Indices MCP Server started on port ${this.port}`);
22
+ this.logInfo(`Available packages: ${this.packages.map(p => p.config.key).join(', ')}`);
23
+ resolve();
24
+ });
25
+ this.server.on('error', (error) => {
26
+ if (error.code === 'EADDRINUSE') {
27
+ this.logError(`Port ${this.port} is already in use`);
28
+ reject(new Error(`Port ${this.port} is already in use`));
29
+ }
30
+ else {
31
+ this.logError('Server error:', error);
32
+ reject(error);
33
+ }
34
+ });
35
+ });
36
+ }
37
+ async stop() {
38
+ return new Promise((resolve) => {
39
+ if (!this.server) {
40
+ resolve();
41
+ return;
42
+ }
43
+ this.server.close(() => {
44
+ this.logInfo('Export Indices MCP Server stopped');
45
+ resolve();
46
+ });
47
+ });
48
+ }
49
+ async handleRequest(req, res) {
50
+ try {
51
+ const url = new URL(req.url || '/', `http://${req.headers.host}`);
52
+ const path = url.pathname;
53
+ const method = req.method;
54
+ // Set CORS headers
55
+ res.setHeader('Access-Control-Allow-Origin', '*');
56
+ res.setHeader('Access-Control-Allow-Methods', 'GET, OPTIONS');
57
+ res.setHeader('Access-Control-Allow-Headers', 'Content-Type');
58
+ res.setHeader('Content-Type', 'application/json');
59
+ if (method === 'OPTIONS') {
60
+ res.writeHead(200);
61
+ res.end();
62
+ return;
63
+ }
64
+ if (method !== 'GET') {
65
+ this.sendError(res, 405, 'Method not allowed');
66
+ return;
67
+ }
68
+ // Route handling
69
+ if (path === '/health') {
70
+ this.handleHealth(res);
71
+ }
72
+ else if (path === '/packages') {
73
+ await this.handlePackages(res);
74
+ }
75
+ else if (path.startsWith('/packages/')) {
76
+ await this.handlePackageRoutes(path, res);
77
+ }
78
+ else {
79
+ this.sendError(res, 404, 'Not found');
80
+ }
81
+ }
82
+ catch (error) {
83
+ this.logError('Request handling error:', error);
84
+ this.sendError(res, 500, error.message || 'Internal server error');
85
+ }
86
+ }
87
+ handleHealth(res) {
88
+ this.sendJson(res, { status: 'ok', service: 'Export Indices MCP Server' });
89
+ }
90
+ async handlePackages(res) {
91
+ const packages = this.packages
92
+ .filter(unit => unit.isInstanceOf(Unit_TypescriptLib))
93
+ .map(unit => ({
94
+ name: unit.config.key,
95
+ root: unit.config.fullPath
96
+ }));
97
+ this.sendJson(res, { packages });
98
+ }
99
+ async handlePackageRoutes(path, res) {
100
+ // Extract package name and remaining path
101
+ // Path format: /packages/:packageName/...
102
+ const pathParts = path.split('/').filter(p => p);
103
+ if (pathParts.length < 2 || pathParts[0] !== 'packages') {
104
+ this.sendError(res, 404, 'Invalid path');
105
+ return;
106
+ }
107
+ const packageName = decodeURIComponent(pathParts[1]);
108
+ const packageUnit = this.packages.find(p => p.config.key === packageName);
109
+ if (!packageUnit || !packageUnit.isInstanceOf(Unit_TypescriptLib)) {
110
+ this.sendError(res, 404, `Package '${packageName}' not found`);
111
+ return;
112
+ }
113
+ const packageRoot = packageUnit.config.fullPath;
114
+ const remainingPath = pathParts.slice(2).join('/');
115
+ if (remainingPath === 'exports') {
116
+ await this.handleGetAllExports(packageName, packageRoot, res);
117
+ }
118
+ else if (remainingPath.startsWith('exports/by-name/')) {
119
+ const symbolName = decodeURIComponent(remainingPath.replace('exports/by-name/', ''));
120
+ await this.handleGetByName(packageName, packageRoot, symbolName, res);
121
+ }
122
+ else if (remainingPath.startsWith('exports/by-file/')) {
123
+ const filePath = decodeURIComponent(remainingPath.replace('exports/by-file/', ''));
124
+ await this.handleGetByFile(packageName, packageRoot, filePath, res);
125
+ }
126
+ else if (remainingPath.startsWith('exports/by-type/')) {
127
+ const symbolType = decodeURIComponent(remainingPath.replace('exports/by-type/', ''));
128
+ await this.handleGetByType(packageName, packageRoot, symbolType, res);
129
+ }
130
+ else if (remainingPath === 'stale') {
131
+ await this.handleStale(packageName, packageRoot, res);
132
+ }
133
+ else {
134
+ this.sendError(res, 404, 'Not found');
135
+ }
136
+ }
137
+ async handleGetAllExports(packageName, packageRoot, res) {
138
+ try {
139
+ const exports = await ExportIndexCache.getAll(this.projectRoot, packageRoot, packageName);
140
+ this.sendJson(res, { package: packageName, exports });
141
+ }
142
+ catch (error) {
143
+ if (error.message?.includes('Index file not found')) {
144
+ this.sendError(res, 404, `Indices not found for package '${packageName}'. Run 'bai --map-exports' to generate indices.`);
145
+ }
146
+ else {
147
+ this.sendError(res, 500, error.message || 'Failed to get exports');
148
+ }
149
+ }
150
+ }
151
+ async handleGetByName(packageName, packageRoot, symbolName, res) {
152
+ try {
153
+ const symbol = await ExportIndexCache.getByName(this.projectRoot, packageRoot, packageName, symbolName);
154
+ if (!symbol) {
155
+ this.sendError(res, 404, `Symbol '${symbolName}' not found in package '${packageName}'`);
156
+ return;
157
+ }
158
+ this.sendJson(res, { package: packageName, symbol });
159
+ }
160
+ catch (error) {
161
+ if (error.message?.includes('Index file not found')) {
162
+ this.sendError(res, 404, `Indices not found for package '${packageName}'. Run 'bai --map-exports' to generate indices.`);
163
+ }
164
+ else {
165
+ this.sendError(res, 500, error.message || 'Failed to get symbol');
166
+ }
167
+ }
168
+ }
169
+ async handleGetByFile(packageName, packageRoot, filePath, res) {
170
+ try {
171
+ const exports = await ExportIndexCache.getByFile(this.projectRoot, packageRoot, packageName, filePath);
172
+ this.sendJson(res, { package: packageName, filePath, exports });
173
+ }
174
+ catch (error) {
175
+ if (error.message?.includes('Index file not found')) {
176
+ this.sendError(res, 404, `Indices not found for package '${packageName}'. Run 'bai --map-exports' to generate indices.`);
177
+ }
178
+ else {
179
+ this.sendError(res, 500, error.message || 'Failed to get exports by file');
180
+ }
181
+ }
182
+ }
183
+ async handleGetByType(packageName, packageRoot, symbolType, res) {
184
+ try {
185
+ const exports = await ExportIndexCache.getByType(this.projectRoot, packageRoot, packageName, symbolType);
186
+ this.sendJson(res, { package: packageName, symbolType, exports });
187
+ }
188
+ catch (error) {
189
+ if (error.message?.includes('Index file not found')) {
190
+ this.sendError(res, 404, `Indices not found for package '${packageName}'. Run 'bai --map-exports' to generate indices.`);
191
+ }
192
+ else {
193
+ this.sendError(res, 500, error.message || 'Failed to get exports by type');
194
+ }
195
+ }
196
+ }
197
+ async handleStale(packageName, packageRoot, res) {
198
+ try {
199
+ const stale = await ExportIndexCache.isStale(this.projectRoot, packageRoot, packageName);
200
+ this.sendJson(res, {
201
+ package: packageName,
202
+ stale,
203
+ message: stale
204
+ ? "Source files are newer than index files. Run 'bai --map-exports' to regenerate."
205
+ : 'Indices are up to date.'
206
+ });
207
+ }
208
+ catch (error) {
209
+ this.sendError(res, 500, error.message || 'Failed to check stale status');
210
+ }
211
+ }
212
+ sendJson(res, data) {
213
+ res.writeHead(200);
214
+ res.end(JSON.stringify(data, null, 2));
215
+ }
216
+ sendError(res, statusCode, message) {
217
+ res.writeHead(statusCode);
218
+ res.end(JSON.stringify({ error: message }, null, 2));
219
+ }
220
+ }
@@ -0,0 +1,3 @@
1
+ // Export types will be defined here if needed
2
+ // Currently using types from ExportMapper.ts
3
+ export {};
package/package.json CHANGED
@@ -1,24 +1,32 @@
1
1
  {
2
2
  "name": "@nu-art/build-and-install",
3
- "version": "0.400.14",
4
- "description": "",
3
+ "version": "0.401.1",
4
+ "description": "A build system for monorepos that orchestrates building, testing, and deploying units with dependency-aware phase execution",
5
5
  "type": "module",
6
6
  "keywords": [
7
- "TacB0sS",
8
- "infra",
7
+ "typescript",
8
+ "build-system",
9
+ "monorepo",
10
+ "dependency-management",
11
+ "phase-execution",
12
+ "workspace",
13
+ "units",
14
+ "automation",
9
15
  "nu-art",
10
- "commando"
16
+ "thunderstorm",
17
+ "build-and-install"
11
18
  ],
12
19
  "homepage": "https://github.com/nu-art-js/thunderstorm",
13
20
  "bugs": {
14
- "url": "https://github.com/nu-art-js/thunderstorm/issues"
21
+ "url": "https://github.com/nu-art-js/thunderstorm/issues?q=is%3Aissue+label%3Abuild-and-install"
15
22
  },
16
23
  "publishConfig": {
17
24
  "directory": "dist"
18
25
  },
19
26
  "repository": {
20
27
  "type": "git",
21
- "url": "git+ssh://git@github.com:nu-art-js/thunderstorm.git"
28
+ "url": "git+ssh://git@github.com:nu-art-js/thunderstorm.git",
29
+ "directory": "_thunderstorm/build-and-install"
22
30
  },
23
31
  "license": "Apache-2.0",
24
32
  "author": "TacB0sS",
@@ -31,8 +39,11 @@
31
39
  },
32
40
  "dependencies": {
33
41
  "chokidar": "^3.6.0",
34
- "@nu-art/ts-common": "0.400.14",
35
- "@nu-art/commando": "0.400.14"
42
+ "@nu-art/ts-common": "0.401.1",
43
+ "@nu-art/commando": "0.401.1"
44
+ },
45
+ "devDependencies": {
46
+ "@nu-art/testalot": "0.401.1"
36
47
  },
37
48
  "unitConfig": {
38
49
  "type": "typescript-lib"
@@ -0,0 +1,130 @@
1
+ import { Logger } from '@nu-art/ts-common';
2
+ import { RunningStatusHandler } from '../runtime/RunningStatusHandler.js';
3
+ import { Phase } from './definitions/index.js';
4
+ import { BaseUnit } from '../units/index.js';
5
+ /**
6
+ * Scheduled execution step (before mapping to actual phases/units).
7
+ */
8
+ export type ScheduledStep = {
9
+ phases: string[];
10
+ units: string[];
11
+ };
12
+ /**
13
+ * Mapped execution step with actual phase and unit instances.
14
+ */
15
+ export type ExecutionStep = {
16
+ phases: Phase<any>[];
17
+ units: BaseUnit<any>[];
18
+ };
19
+ /**
20
+ * Manages phase execution across units in dependency order.
21
+ *
22
+ * **Execution Model**:
23
+ * - **Phase Groups**: Phases that can run in parallel (e.g., [prepare, compile])
24
+ * - **Unit Layers**: Units grouped by dependency level (dependencies first)
25
+ * - **Steps**: Combinations of phase groups × unit layers
26
+ *
27
+ * **Execution Flow**:
28
+ * 1. `calculateExecutionSteps()`: Plans which phases run on which units
29
+ * 2. `execute()`: Executes steps sequentially, phases in parallel within steps
30
+ * 3. Units in same layer run phases in parallel (Promise.all)
31
+ *
32
+ * **Eligibility Rules**:
33
+ * - Unit must implement the phase method (e.g., `compile()`, `test()`)
34
+ * - Unit must be in active/project units (based on phase.unitCategory)
35
+ * - Phase filter (if present) must pass runtime params
36
+ *
37
+ * **Error Handling**:
38
+ * - First failure stops execution (sets `killed = true`)
39
+ * - Aggregates all errors into `PhaseAggregatedException`
40
+ * - Tracks running units for graceful shutdown
41
+ *
42
+ * **Resume Support**:
43
+ * - Skips completed steps (via `runningStatus.startIndex`)
44
+ * - Skips completed units within steps (via `runningStatus.isCompleted()`)
45
+ *
46
+ * **Validation**:
47
+ * - Constructor validates no duplicate units or phases
48
+ * - Throws `BadImplementationException` on duplicates
49
+ */
50
+ export declare class PhaseManager extends Logger {
51
+ private readonly phases;
52
+ private readonly units;
53
+ private runningUnits;
54
+ private killed;
55
+ private runningStatus;
56
+ private activeUnits;
57
+ private projectUnitKeys;
58
+ private readonly keyToPhaseMap;
59
+ constructor(runningStatus: RunningStatusHandler, phases: Phase<any>[][], units: BaseUnit[][], activeUnits: string[], projectUnitKeys: string[]);
60
+ /**
61
+ * Calculates the execution plan: which phases run on which units.
62
+ *
63
+ * **Algorithm**:
64
+ * 1. For each phase group (phases that can run together)
65
+ * 2. Filter phases by runtime params (if phase.filter exists)
66
+ * 3. For each unit layer (dependency level)
67
+ * 4. Find units eligible for at least one phase in the group
68
+ * 5. Group units by which phases they support
69
+ * 6. Create steps: phase combinations × unit groups
70
+ *
71
+ * **Phase Grouping**: Units that support the same set of phases are grouped
72
+ * together in a step (identified by phase keys joined with '|').
73
+ *
74
+ * **Unit Eligibility**:
75
+ * - Unit must implement phase method
76
+ * - Unit must be in active/project units (based on phase.unitCategory)
77
+ *
78
+ * @returns Array of scheduled steps (phases and unit keys)
79
+ */
80
+ calculateExecutionSteps(): Promise<ScheduledStep[]>;
81
+ /**
82
+ * Executes the planned steps sequentially.
83
+ *
84
+ * **Execution Model**:
85
+ * - Steps run sequentially (one after another)
86
+ * - Units within a step run phases in parallel (Promise.all)
87
+ * - Phases for a unit run sequentially (in phase group order)
88
+ *
89
+ * **Resume Support**:
90
+ * - Starts from `runningStatus.startIndex` (if --continue)
91
+ * - Skips units marked as completed
92
+ *
93
+ * **Dry Run**: If `--dry-run`, only logs phase/unit names without executing.
94
+ *
95
+ * **Error Handling**:
96
+ * - First error stops execution (sets `killed = true`)
97
+ * - All errors aggregated into `PhaseAggregatedException`
98
+ * - Running units tracked for graceful shutdown
99
+ *
100
+ * **Performance**: Logs operation duration if > 1.5 seconds.
101
+ *
102
+ * @param _steps - Scheduled steps to execute
103
+ * @throws PhaseAggregatedException if any phase fails
104
+ */
105
+ execute(_steps: ScheduledStep[]): Promise<void>;
106
+ /**
107
+ * Gracefully stops execution and kills all running units.
108
+ *
109
+ * Called on SIGINT (Ctrl+C). Sets `killed = true` to stop further execution,
110
+ * then calls `kill()` on all currently running units.
111
+ *
112
+ * @returns Promise that resolves when all units are killed
113
+ */
114
+ break(): Promise<void[]>;
115
+ /**
116
+ * Maps scheduled step (with string keys) to execution step (with actual instances).
117
+ *
118
+ * **Mapping Process**:
119
+ * - Maps phase keys to Phase instances using `keyToPhaseMap`
120
+ * - Maps unit keys to BaseUnit instances by searching through unit layers
121
+ *
122
+ * **Performance Note**: Unit lookup iterates through all layers (O(n) complexity).
123
+ * Consider using a lookup map for O(1) access in large workspaces.
124
+ *
125
+ * @param scheduledStep - Scheduled step with phase/unit keys
126
+ * @returns Execution step with phase/unit instances
127
+ * @throws Error if phase or unit not found
128
+ */
129
+ private mapStep;
130
+ }