nexusforge-cli 1.1.1 → 1.2.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.
- package/dist/components/App.d.ts.map +1 -1
- package/dist/components/App.js +183 -17
- package/dist/components/App.js.map +1 -1
- package/dist/index.js +462 -10
- package/dist/index.js.map +1 -1
- package/dist/modules/commandEngine.d.ts +70 -0
- package/dist/modules/commandEngine.d.ts.map +1 -0
- package/dist/modules/commandEngine.js +672 -0
- package/dist/modules/commandEngine.js.map +1 -0
- package/dist/modules/contextBuilder.d.ts +51 -0
- package/dist/modules/contextBuilder.d.ts.map +1 -0
- package/dist/modules/contextBuilder.js +725 -0
- package/dist/modules/contextBuilder.js.map +1 -0
- package/dist/modules/domainDetector.d.ts +64 -0
- package/dist/modules/domainDetector.d.ts.map +1 -0
- package/dist/modules/domainDetector.js +722 -0
- package/dist/modules/domainDetector.js.map +1 -0
- package/dist/modules/fileOperations.d.ts +99 -0
- package/dist/modules/fileOperations.d.ts.map +1 -0
- package/dist/modules/fileOperations.js +543 -0
- package/dist/modules/fileOperations.js.map +1 -0
- package/dist/modules/forgeEngine.d.ts +153 -0
- package/dist/modules/forgeEngine.d.ts.map +1 -0
- package/dist/modules/forgeEngine.js +652 -0
- package/dist/modules/forgeEngine.js.map +1 -0
- package/dist/modules/gitManager.d.ts +151 -0
- package/dist/modules/gitManager.d.ts.map +1 -0
- package/dist/modules/gitManager.js +539 -0
- package/dist/modules/gitManager.js.map +1 -0
- package/dist/modules/index.d.ts +25 -0
- package/dist/modules/index.d.ts.map +1 -0
- package/dist/modules/index.js +25 -0
- package/dist/modules/index.js.map +1 -0
- package/dist/modules/prdProcessor.d.ts +125 -0
- package/dist/modules/prdProcessor.d.ts.map +1 -0
- package/dist/modules/prdProcessor.js +466 -0
- package/dist/modules/prdProcessor.js.map +1 -0
- package/dist/modules/projectScanner.d.ts +105 -0
- package/dist/modules/projectScanner.d.ts.map +1 -0
- package/dist/modules/projectScanner.js +859 -0
- package/dist/modules/projectScanner.js.map +1 -0
- package/dist/modules/safetyGuard.d.ts +83 -0
- package/dist/modules/safetyGuard.d.ts.map +1 -0
- package/dist/modules/safetyGuard.js +492 -0
- package/dist/modules/safetyGuard.js.map +1 -0
- package/dist/modules/templateManager.d.ts +78 -0
- package/dist/modules/templateManager.d.ts.map +1 -0
- package/dist/modules/templateManager.js +556 -0
- package/dist/modules/templateManager.js.map +1 -0
- package/dist/native/index.d.ts +125 -0
- package/dist/native/index.d.ts.map +1 -0
- package/dist/native/index.js +164 -0
- package/dist/native/index.js.map +1 -0
- package/dist/services/executor.d.ts +24 -0
- package/dist/services/executor.d.ts.map +1 -1
- package/dist/services/executor.js +149 -6
- package/dist/services/executor.js.map +1 -1
- package/dist/services/fileManager.d.ts +134 -0
- package/dist/services/fileManager.d.ts.map +1 -0
- package/dist/services/fileManager.js +489 -0
- package/dist/services/fileManager.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,652 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* NexusForge Forge Engine
|
|
3
|
+
* Autonomous building and execution system
|
|
4
|
+
* Ported from Python: nexusforge/modules/architecture/forge_engine.py
|
|
5
|
+
*/
|
|
6
|
+
import { resolve, join } from 'path';
|
|
7
|
+
import { mkdirSync, existsSync, writeFileSync, readdirSync, statSync } from 'fs';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// ENUMS
|
|
10
|
+
// ============================================================================
|
|
11
|
+
export var ForgeMode;
|
|
12
|
+
(function (ForgeMode) {
|
|
13
|
+
ForgeMode["ARCHITECT"] = "architect";
|
|
14
|
+
ForgeMode["BUILDER"] = "builder";
|
|
15
|
+
ForgeMode["ANALYST"] = "analyst";
|
|
16
|
+
ForgeMode["OPTIMIZER"] = "optimizer";
|
|
17
|
+
ForgeMode["DEBUGGER"] = "debugger";
|
|
18
|
+
ForgeMode["MENTOR"] = "mentor";
|
|
19
|
+
ForgeMode["REFACTOR"] = "refactor";
|
|
20
|
+
ForgeMode["SECURITY"] = "security";
|
|
21
|
+
})(ForgeMode || (ForgeMode = {}));
|
|
22
|
+
export var BuildPhase;
|
|
23
|
+
(function (BuildPhase) {
|
|
24
|
+
BuildPhase["PLANNING"] = "planning";
|
|
25
|
+
BuildPhase["SCAFFOLDING"] = "scaffolding";
|
|
26
|
+
BuildPhase["IMPLEMENTING"] = "implementing";
|
|
27
|
+
BuildPhase["TESTING"] = "testing";
|
|
28
|
+
BuildPhase["VALIDATING"] = "validating";
|
|
29
|
+
BuildPhase["OPTIMIZING"] = "optimizing";
|
|
30
|
+
BuildPhase["DOCUMENTING"] = "documenting";
|
|
31
|
+
BuildPhase["DEPLOYING"] = "deploying";
|
|
32
|
+
BuildPhase["COMPLETE"] = "complete";
|
|
33
|
+
BuildPhase["FAILED"] = "failed";
|
|
34
|
+
})(BuildPhase || (BuildPhase = {}));
|
|
35
|
+
export var TaskStatus;
|
|
36
|
+
(function (TaskStatus) {
|
|
37
|
+
TaskStatus["PENDING"] = "pending";
|
|
38
|
+
TaskStatus["IN_PROGRESS"] = "in_progress";
|
|
39
|
+
TaskStatus["BLOCKED"] = "blocked";
|
|
40
|
+
TaskStatus["COMPLETED"] = "completed";
|
|
41
|
+
TaskStatus["FAILED"] = "failed";
|
|
42
|
+
TaskStatus["CANCELLED"] = "cancelled";
|
|
43
|
+
})(TaskStatus || (TaskStatus = {}));
|
|
44
|
+
// ============================================================================
|
|
45
|
+
// TECH STACK INFERENCE
|
|
46
|
+
// ============================================================================
|
|
47
|
+
const TECH_HINTS = {
|
|
48
|
+
web: ['HTML', 'CSS', 'JavaScript'],
|
|
49
|
+
react: ['React', 'Node.js', 'Webpack', 'Babel'],
|
|
50
|
+
vue: ['Vue.js', 'Node.js', 'Webpack'],
|
|
51
|
+
angular: ['Angular', 'TypeScript', 'RxJS'],
|
|
52
|
+
next: ['Next.js', 'React', 'Node.js'],
|
|
53
|
+
python: ['Python', 'pip', 'virtualenv'],
|
|
54
|
+
api: ['FastAPI', 'PostgreSQL', 'Redis'],
|
|
55
|
+
'rest api': ['FastAPI', 'OpenAPI', 'Pydantic'],
|
|
56
|
+
graphql: ['GraphQL', 'Apollo', 'PostgreSQL'],
|
|
57
|
+
mobile: ['React Native', 'Expo', 'TypeScript'],
|
|
58
|
+
ios: ['Swift', 'UIKit', 'CocoaPods'],
|
|
59
|
+
android: ['Kotlin', 'Android SDK', 'Gradle'],
|
|
60
|
+
desktop: ['Electron', 'TypeScript', 'Node.js'],
|
|
61
|
+
cli: ['Node.js', 'TypeScript', 'Commander'],
|
|
62
|
+
bot: ['Node.js', 'Discord.js'],
|
|
63
|
+
ml: ['Python', 'TensorFlow', 'NumPy', 'scikit-learn'],
|
|
64
|
+
data: ['Python', 'Pandas', 'Jupyter', 'Matplotlib'],
|
|
65
|
+
rust: ['Rust', 'Cargo', 'tokio'],
|
|
66
|
+
go: ['Go', 'Go Modules'],
|
|
67
|
+
docker: ['Docker', 'Docker Compose'],
|
|
68
|
+
kubernetes: ['Kubernetes', 'Helm', 'kubectl'],
|
|
69
|
+
typescript: ['TypeScript', 'Node.js'],
|
|
70
|
+
express: ['Express', 'Node.js'],
|
|
71
|
+
nestjs: ['NestJS', 'TypeScript', 'Node.js'],
|
|
72
|
+
django: ['Django', 'Python', 'PostgreSQL'],
|
|
73
|
+
flask: ['Flask', 'Python'],
|
|
74
|
+
};
|
|
75
|
+
// ============================================================================
|
|
76
|
+
// FORGE ENGINE CLASS
|
|
77
|
+
// ============================================================================
|
|
78
|
+
export class ForgeEngine {
|
|
79
|
+
workspace;
|
|
80
|
+
projectName;
|
|
81
|
+
activeMode;
|
|
82
|
+
taskQueue;
|
|
83
|
+
completedTasks;
|
|
84
|
+
failedTasks;
|
|
85
|
+
currentTask;
|
|
86
|
+
blueprint;
|
|
87
|
+
forgeState;
|
|
88
|
+
constructor(workspace, projectName) {
|
|
89
|
+
this.workspace = workspace ? resolve(workspace) : process.cwd();
|
|
90
|
+
this.projectName = projectName || this.workspace.split(/[/\\]/).pop() || 'project';
|
|
91
|
+
this.activeMode = ForgeMode.BUILDER;
|
|
92
|
+
this.taskQueue = [];
|
|
93
|
+
this.completedTasks = [];
|
|
94
|
+
this.failedTasks = [];
|
|
95
|
+
this.forgeState = {
|
|
96
|
+
totalBuilds: 0,
|
|
97
|
+
successfulBuilds: 0,
|
|
98
|
+
failedBuilds: 0,
|
|
99
|
+
linesWritten: 0,
|
|
100
|
+
testsPassed: 0,
|
|
101
|
+
optimizationsMade: 0,
|
|
102
|
+
bugsFixed: 0,
|
|
103
|
+
};
|
|
104
|
+
// Ensure workspace exists
|
|
105
|
+
if (!existsSync(this.workspace)) {
|
|
106
|
+
mkdirSync(this.workspace, { recursive: true });
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
// ========================================================================
|
|
110
|
+
// DIRECTIVE PROCESSING
|
|
111
|
+
// ========================================================================
|
|
112
|
+
async processDirective(directive, context) {
|
|
113
|
+
const mode = this.determineMode(directive);
|
|
114
|
+
this.activeMode = mode;
|
|
115
|
+
const task = {
|
|
116
|
+
id: `task_${Date.now()}`,
|
|
117
|
+
directive,
|
|
118
|
+
mode,
|
|
119
|
+
phase: BuildPhase.PLANNING,
|
|
120
|
+
priority: 5,
|
|
121
|
+
dependencies: [],
|
|
122
|
+
artifacts: {},
|
|
123
|
+
progress: 0,
|
|
124
|
+
status: TaskStatus.PENDING,
|
|
125
|
+
createdAt: Date.now(),
|
|
126
|
+
};
|
|
127
|
+
this.taskQueue.push(task);
|
|
128
|
+
this.currentTask = task;
|
|
129
|
+
try {
|
|
130
|
+
const blueprint = await this.generateBlueprint(directive, mode, context);
|
|
131
|
+
this.blueprint = blueprint;
|
|
132
|
+
task.status = TaskStatus.COMPLETED;
|
|
133
|
+
task.phase = BuildPhase.PLANNING;
|
|
134
|
+
task.progress = 100;
|
|
135
|
+
task.completedAt = Date.now();
|
|
136
|
+
return blueprint;
|
|
137
|
+
}
|
|
138
|
+
catch (error) {
|
|
139
|
+
task.status = TaskStatus.FAILED;
|
|
140
|
+
task.error = error instanceof Error ? error.message : 'Unknown error';
|
|
141
|
+
throw error;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
determineMode(directive) {
|
|
145
|
+
const directiveLower = directive.toLowerCase();
|
|
146
|
+
const modePatterns = {
|
|
147
|
+
[ForgeMode.BUILDER]: ['build', 'create', 'implement', 'make', 'develop', 'generate'],
|
|
148
|
+
[ForgeMode.ANALYST]: ['analyze', 'review', 'audit', 'examine', 'inspect', 'check'],
|
|
149
|
+
[ForgeMode.OPTIMIZER]: ['optimize', 'improve', 'speed up', 'enhance', 'performance'],
|
|
150
|
+
[ForgeMode.DEBUGGER]: ['debug', 'fix', 'solve', 'troubleshoot', 'repair'],
|
|
151
|
+
[ForgeMode.MENTOR]: ['explain', 'how', 'why', 'teach', 'describe', 'what is'],
|
|
152
|
+
[ForgeMode.ARCHITECT]: ['design', 'architect', 'plan', 'structure', 'layout'],
|
|
153
|
+
[ForgeMode.REFACTOR]: ['refactor', 'restructure', 'reorganize', 'clean up'],
|
|
154
|
+
[ForgeMode.SECURITY]: ['secure', 'security', 'vulnerabilities', 'audit security'],
|
|
155
|
+
};
|
|
156
|
+
for (const [mode, patterns] of Object.entries(modePatterns)) {
|
|
157
|
+
if (patterns.some(word => directiveLower.includes(word))) {
|
|
158
|
+
return mode;
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
return ForgeMode.BUILDER;
|
|
162
|
+
}
|
|
163
|
+
async generateBlueprint(directive, mode, context) {
|
|
164
|
+
const requirements = this.extractRequirements(directive);
|
|
165
|
+
const techStack = this.inferTechStack(directive);
|
|
166
|
+
const architecture = this.designArchitecture(directive, mode);
|
|
167
|
+
const fileStructure = this.planFileStructure(directive, techStack);
|
|
168
|
+
const dependencies = this.identifyDependencies(techStack);
|
|
169
|
+
const testStrategy = this.planTesting(techStack);
|
|
170
|
+
return {
|
|
171
|
+
name: this.generateProjectName(directive),
|
|
172
|
+
description: `Project generated from: ${directive}`,
|
|
173
|
+
requirements,
|
|
174
|
+
architecture,
|
|
175
|
+
techStack,
|
|
176
|
+
fileStructure,
|
|
177
|
+
dependencies,
|
|
178
|
+
testStrategy,
|
|
179
|
+
deploymentConfig: this.planDeployment(techStack),
|
|
180
|
+
qualityMetrics: {
|
|
181
|
+
targetCoverage: 80,
|
|
182
|
+
complexityLimit: 10,
|
|
183
|
+
maintainabilityIndex: 70,
|
|
184
|
+
},
|
|
185
|
+
timelineEstimate: this.estimateTimeline(requirements, fileStructure),
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
extractRequirements(directive) {
|
|
189
|
+
const requirements = [];
|
|
190
|
+
const patterns = [
|
|
191
|
+
/should\s+(.+?)(?:\.|,|and|$)/gi,
|
|
192
|
+
/must\s+(.+?)(?:\.|,|and|$)/gi,
|
|
193
|
+
/need(?:s)?\s+to\s+(.+?)(?:\.|,|and|$)/gi,
|
|
194
|
+
/feature(?:s)?:?\s*(.+?)(?:\.|$)/gi,
|
|
195
|
+
/(?:can|able to)\s+(.+?)(?:\.|,|and|$)/gi,
|
|
196
|
+
];
|
|
197
|
+
for (const pattern of patterns) {
|
|
198
|
+
let match;
|
|
199
|
+
while ((match = pattern.exec(directive)) !== null) {
|
|
200
|
+
if (match[1]?.trim()) {
|
|
201
|
+
requirements.push(match[1].trim());
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
if (requirements.length === 0) {
|
|
206
|
+
requirements.push('Build according to best practices');
|
|
207
|
+
requirements.push(directive);
|
|
208
|
+
}
|
|
209
|
+
return [...new Set(requirements)];
|
|
210
|
+
}
|
|
211
|
+
inferTechStack(directive) {
|
|
212
|
+
const directiveLower = directive.toLowerCase();
|
|
213
|
+
const stack = new Set();
|
|
214
|
+
for (const [keyword, techs] of Object.entries(TECH_HINTS)) {
|
|
215
|
+
if (directiveLower.includes(keyword)) {
|
|
216
|
+
techs.forEach(tech => stack.add(tech));
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
if (stack.size === 0) {
|
|
220
|
+
stack.add('Node.js');
|
|
221
|
+
stack.add('TypeScript');
|
|
222
|
+
}
|
|
223
|
+
return [...stack].sort();
|
|
224
|
+
}
|
|
225
|
+
designArchitecture(directive, mode) {
|
|
226
|
+
const architecture = {
|
|
227
|
+
type: 'modular',
|
|
228
|
+
layers: [],
|
|
229
|
+
patterns: [],
|
|
230
|
+
principles: ['SOLID', 'DRY', 'KISS'],
|
|
231
|
+
};
|
|
232
|
+
const directiveLower = directive.toLowerCase();
|
|
233
|
+
if (directiveLower.includes('api')) {
|
|
234
|
+
architecture.layers = ['API', 'Service', 'Repository', 'Database'];
|
|
235
|
+
architecture.patterns = ['REST', 'Repository', 'Dependency Injection'];
|
|
236
|
+
}
|
|
237
|
+
else if (directiveLower.includes('web')) {
|
|
238
|
+
architecture.layers = ['Presentation', 'Business Logic', 'Data Access'];
|
|
239
|
+
architecture.patterns = ['MVC', 'Component-Based', 'State Management'];
|
|
240
|
+
}
|
|
241
|
+
else if (directiveLower.includes('cli')) {
|
|
242
|
+
architecture.layers = ['CLI Interface', 'Core Logic', 'Utilities'];
|
|
243
|
+
architecture.patterns = ['Command Pattern', 'Strategy Pattern'];
|
|
244
|
+
}
|
|
245
|
+
else {
|
|
246
|
+
architecture.layers = ['Presentation', 'Business', 'Data'];
|
|
247
|
+
architecture.patterns = ['Layered', 'Service-Oriented'];
|
|
248
|
+
}
|
|
249
|
+
return architecture;
|
|
250
|
+
}
|
|
251
|
+
planFileStructure(directive, techStack) {
|
|
252
|
+
const structure = {
|
|
253
|
+
'src/': 'Source code',
|
|
254
|
+
'tests/': 'Test files',
|
|
255
|
+
'docs/': 'Documentation',
|
|
256
|
+
'config/': 'Configuration files',
|
|
257
|
+
};
|
|
258
|
+
if (techStack.includes('TypeScript') || techStack.includes('Node.js')) {
|
|
259
|
+
structure['src/index.ts'] = 'Main entry point';
|
|
260
|
+
structure['package.json'] = 'Package configuration';
|
|
261
|
+
structure['tsconfig.json'] = 'TypeScript configuration';
|
|
262
|
+
}
|
|
263
|
+
if (techStack.includes('Python')) {
|
|
264
|
+
structure['src/__init__.py'] = 'Package initialization';
|
|
265
|
+
structure['requirements.txt'] = 'Python dependencies';
|
|
266
|
+
structure['setup.py'] = 'Package setup';
|
|
267
|
+
}
|
|
268
|
+
if (techStack.includes('React') || techStack.includes('Vue.js')) {
|
|
269
|
+
structure['src/components/'] = 'UI components';
|
|
270
|
+
structure['src/pages/'] = 'Page components';
|
|
271
|
+
structure['src/styles/'] = 'Stylesheets';
|
|
272
|
+
structure['public/'] = 'Static assets';
|
|
273
|
+
}
|
|
274
|
+
if (techStack.includes('FastAPI') || techStack.includes('Express')) {
|
|
275
|
+
structure['src/api/'] = 'API endpoints';
|
|
276
|
+
structure['src/models/'] = 'Data models';
|
|
277
|
+
structure['src/services/'] = 'Business logic';
|
|
278
|
+
}
|
|
279
|
+
return structure;
|
|
280
|
+
}
|
|
281
|
+
identifyDependencies(techStack) {
|
|
282
|
+
const dependencies = {};
|
|
283
|
+
const depMap = {
|
|
284
|
+
'FastAPI': { fastapi: '^0.104.0', uvicorn: '^0.24.0', pydantic: '^2.5.0' },
|
|
285
|
+
'React': { react: '^18.2.0', 'react-dom': '^18.2.0' },
|
|
286
|
+
'Vue.js': { vue: '^3.3.0' },
|
|
287
|
+
'Express': { express: '^4.18.0' },
|
|
288
|
+
'TypeScript': { typescript: '^5.3.0', '@types/node': '^20.10.0' },
|
|
289
|
+
'Commander': { commander: '^12.0.0' },
|
|
290
|
+
};
|
|
291
|
+
for (const tech of techStack) {
|
|
292
|
+
if (tech in depMap) {
|
|
293
|
+
Object.assign(dependencies, depMap[tech]);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return dependencies;
|
|
297
|
+
}
|
|
298
|
+
planTesting(techStack) {
|
|
299
|
+
const isPython = techStack.includes('Python');
|
|
300
|
+
const isJS = techStack.some(t => ['React', 'Node.js', 'Vue.js', 'TypeScript'].includes(t));
|
|
301
|
+
return {
|
|
302
|
+
framework: isPython ? 'pytest' : 'jest',
|
|
303
|
+
coverageTarget: 80,
|
|
304
|
+
types: ['unit', 'integration'],
|
|
305
|
+
tools: isPython
|
|
306
|
+
? ['pytest', 'pytest-cov', 'pytest-asyncio']
|
|
307
|
+
: ['jest', '@testing-library/react', 'supertest'],
|
|
308
|
+
};
|
|
309
|
+
}
|
|
310
|
+
planDeployment(techStack) {
|
|
311
|
+
return {
|
|
312
|
+
platform: 'cloud',
|
|
313
|
+
containerized: techStack.includes('Docker'),
|
|
314
|
+
orchestration: techStack.includes('Kubernetes'),
|
|
315
|
+
ciCd: true,
|
|
316
|
+
};
|
|
317
|
+
}
|
|
318
|
+
generateProjectName(directive) {
|
|
319
|
+
const words = directive.toLowerCase().match(/\b[a-z]+\b/g) || [];
|
|
320
|
+
const meaningful = words.filter(w => w.length > 3 && !['create', 'build', 'make', 'implement', 'that', 'with', 'the'].includes(w));
|
|
321
|
+
return meaningful.slice(0, 2).join('_') || 'generated_project';
|
|
322
|
+
}
|
|
323
|
+
estimateTimeline(requirements, fileStructure) {
|
|
324
|
+
const base = 10;
|
|
325
|
+
const requirementsTime = requirements.length * 5;
|
|
326
|
+
const filesTime = Object.keys(fileStructure).length * 2;
|
|
327
|
+
return base + requirementsTime + filesTime;
|
|
328
|
+
}
|
|
329
|
+
// ========================================================================
|
|
330
|
+
// FORGE EXECUTION
|
|
331
|
+
// ========================================================================
|
|
332
|
+
async forge(blueprint, phases) {
|
|
333
|
+
const startTime = Date.now();
|
|
334
|
+
const bp = blueprint || this.blueprint;
|
|
335
|
+
if (!bp) {
|
|
336
|
+
throw new Error('No blueprint available for forging');
|
|
337
|
+
}
|
|
338
|
+
const result = {
|
|
339
|
+
success: false,
|
|
340
|
+
filesCreated: [],
|
|
341
|
+
filesModified: [],
|
|
342
|
+
testsWritten: 0,
|
|
343
|
+
testCoverage: 0,
|
|
344
|
+
documentationGenerated: false,
|
|
345
|
+
deploymentReady: false,
|
|
346
|
+
errors: [],
|
|
347
|
+
warnings: [],
|
|
348
|
+
duration: 0,
|
|
349
|
+
metrics: {},
|
|
350
|
+
};
|
|
351
|
+
const phasesToExecute = phases || [
|
|
352
|
+
BuildPhase.SCAFFOLDING,
|
|
353
|
+
BuildPhase.IMPLEMENTING,
|
|
354
|
+
BuildPhase.TESTING,
|
|
355
|
+
BuildPhase.VALIDATING,
|
|
356
|
+
BuildPhase.OPTIMIZING,
|
|
357
|
+
BuildPhase.DOCUMENTING,
|
|
358
|
+
];
|
|
359
|
+
try {
|
|
360
|
+
for (const phase of phasesToExecute) {
|
|
361
|
+
switch (phase) {
|
|
362
|
+
case BuildPhase.SCAFFOLDING:
|
|
363
|
+
await this.createProjectStructure(bp, result);
|
|
364
|
+
break;
|
|
365
|
+
case BuildPhase.IMPLEMENTING:
|
|
366
|
+
await this.implementFeatures(bp, result);
|
|
367
|
+
break;
|
|
368
|
+
case BuildPhase.TESTING:
|
|
369
|
+
await this.generateTests(bp, result);
|
|
370
|
+
break;
|
|
371
|
+
case BuildPhase.VALIDATING:
|
|
372
|
+
await this.validateBuild(bp, result);
|
|
373
|
+
break;
|
|
374
|
+
case BuildPhase.OPTIMIZING:
|
|
375
|
+
await this.optimizeCode(bp, result);
|
|
376
|
+
break;
|
|
377
|
+
case BuildPhase.DOCUMENTING:
|
|
378
|
+
await this.generateDocumentation(bp, result);
|
|
379
|
+
break;
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
result.success = true;
|
|
383
|
+
result.deploymentReady = true;
|
|
384
|
+
this.forgeState.totalBuilds++;
|
|
385
|
+
this.forgeState.successfulBuilds++;
|
|
386
|
+
this.forgeState.lastBuild = new Date().toISOString();
|
|
387
|
+
}
|
|
388
|
+
catch (error) {
|
|
389
|
+
result.success = false;
|
|
390
|
+
result.errors.push(error instanceof Error ? error.message : 'Unknown error');
|
|
391
|
+
this.forgeState.failedBuilds++;
|
|
392
|
+
}
|
|
393
|
+
finally {
|
|
394
|
+
result.duration = Date.now() - startTime;
|
|
395
|
+
}
|
|
396
|
+
return result;
|
|
397
|
+
}
|
|
398
|
+
async createProjectStructure(bp, result) {
|
|
399
|
+
for (const [path, purpose] of Object.entries(bp.fileStructure)) {
|
|
400
|
+
const fullPath = join(this.workspace, path);
|
|
401
|
+
if (path.endsWith('/')) {
|
|
402
|
+
if (!existsSync(fullPath)) {
|
|
403
|
+
mkdirSync(fullPath, { recursive: true });
|
|
404
|
+
}
|
|
405
|
+
const readmePath = join(fullPath, 'README.md');
|
|
406
|
+
writeFileSync(readmePath, `# ${path}\n\n${purpose}\n`);
|
|
407
|
+
result.filesCreated.push(readmePath.replace(this.workspace, ''));
|
|
408
|
+
}
|
|
409
|
+
else {
|
|
410
|
+
const dir = fullPath.substring(0, fullPath.lastIndexOf('/') || fullPath.lastIndexOf('\\'));
|
|
411
|
+
if (dir && !existsSync(dir)) {
|
|
412
|
+
mkdirSync(dir, { recursive: true });
|
|
413
|
+
}
|
|
414
|
+
if (!existsSync(fullPath)) {
|
|
415
|
+
writeFileSync(fullPath, `// ${purpose}\n`);
|
|
416
|
+
result.filesCreated.push(path);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
async implementFeatures(bp, result) {
|
|
422
|
+
// Placeholder - actual implementation would generate code
|
|
423
|
+
}
|
|
424
|
+
async generateTests(bp, result) {
|
|
425
|
+
result.testsWritten = bp.requirements.length;
|
|
426
|
+
result.testCoverage = 0;
|
|
427
|
+
}
|
|
428
|
+
async validateBuild(bp, result) {
|
|
429
|
+
// Placeholder - would run validations
|
|
430
|
+
}
|
|
431
|
+
async optimizeCode(bp, result) {
|
|
432
|
+
this.forgeState.optimizationsMade++;
|
|
433
|
+
}
|
|
434
|
+
async generateDocumentation(bp, result) {
|
|
435
|
+
const readmePath = join(this.workspace, 'README.md');
|
|
436
|
+
const content = `# ${bp.name}
|
|
437
|
+
|
|
438
|
+
${bp.description}
|
|
439
|
+
|
|
440
|
+
## Requirements
|
|
441
|
+
|
|
442
|
+
${bp.requirements.map(r => `- ${r}`).join('\n')}
|
|
443
|
+
|
|
444
|
+
## Architecture
|
|
445
|
+
|
|
446
|
+
Type: ${bp.architecture.type}
|
|
447
|
+
Layers: ${bp.architecture.layers.join(', ')}
|
|
448
|
+
|
|
449
|
+
## Tech Stack
|
|
450
|
+
|
|
451
|
+
${bp.techStack.map(t => `- ${t}`).join('\n')}
|
|
452
|
+
|
|
453
|
+
## Installation
|
|
454
|
+
|
|
455
|
+
\`\`\`bash
|
|
456
|
+
npm install
|
|
457
|
+
\`\`\`
|
|
458
|
+
|
|
459
|
+
## Usage
|
|
460
|
+
|
|
461
|
+
[Usage instructions]
|
|
462
|
+
|
|
463
|
+
## Testing
|
|
464
|
+
|
|
465
|
+
\`\`\`bash
|
|
466
|
+
npm test
|
|
467
|
+
\`\`\`
|
|
468
|
+
|
|
469
|
+
## License
|
|
470
|
+
|
|
471
|
+
MIT
|
|
472
|
+
`;
|
|
473
|
+
writeFileSync(readmePath, content);
|
|
474
|
+
result.documentationGenerated = true;
|
|
475
|
+
result.filesCreated.push('README.md');
|
|
476
|
+
}
|
|
477
|
+
// ========================================================================
|
|
478
|
+
// MODE OPERATIONS
|
|
479
|
+
// ========================================================================
|
|
480
|
+
switchMode(mode) {
|
|
481
|
+
const oldMode = this.activeMode;
|
|
482
|
+
this.activeMode = mode;
|
|
483
|
+
console.log(`Switched mode: ${oldMode} → ${mode}`);
|
|
484
|
+
}
|
|
485
|
+
getActiveMode() {
|
|
486
|
+
return this.activeMode;
|
|
487
|
+
}
|
|
488
|
+
async analyzeCodebase() {
|
|
489
|
+
this.switchMode(ForgeMode.ANALYST);
|
|
490
|
+
return {
|
|
491
|
+
filesAnalyzed: 0,
|
|
492
|
+
issuesFound: [],
|
|
493
|
+
suggestions: [],
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
async optimizeProject() {
|
|
497
|
+
this.switchMode(ForgeMode.OPTIMIZER);
|
|
498
|
+
return {
|
|
499
|
+
optimizations: [],
|
|
500
|
+
performanceGain: 0.0,
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
async debugIssue(issue) {
|
|
504
|
+
this.switchMode(ForgeMode.DEBUGGER);
|
|
505
|
+
this.forgeState.bugsFixed++;
|
|
506
|
+
return {
|
|
507
|
+
issue,
|
|
508
|
+
solution: '',
|
|
509
|
+
fixed: false,
|
|
510
|
+
};
|
|
511
|
+
}
|
|
512
|
+
async explainConcept(concept) {
|
|
513
|
+
this.switchMode(ForgeMode.MENTOR);
|
|
514
|
+
return `Explanation of ${concept} would go here`;
|
|
515
|
+
}
|
|
516
|
+
// ========================================================================
|
|
517
|
+
// UTILITY METHODS
|
|
518
|
+
// ========================================================================
|
|
519
|
+
getForgeStats() {
|
|
520
|
+
return {
|
|
521
|
+
...this.forgeState,
|
|
522
|
+
activeMode: this.activeMode,
|
|
523
|
+
currentTask: this.currentTask,
|
|
524
|
+
queuedTasks: this.taskQueue.length,
|
|
525
|
+
completedTasks: this.completedTasks.length,
|
|
526
|
+
failedTasks: this.failedTasks.length,
|
|
527
|
+
};
|
|
528
|
+
}
|
|
529
|
+
getCreatedFiles() {
|
|
530
|
+
const created = [];
|
|
531
|
+
if (existsSync(this.workspace)) {
|
|
532
|
+
const walk = (dir) => {
|
|
533
|
+
const files = readdirSync(dir);
|
|
534
|
+
for (const file of files) {
|
|
535
|
+
const fullPath = join(dir, file);
|
|
536
|
+
const stat = statSync(fullPath);
|
|
537
|
+
if (stat.isDirectory()) {
|
|
538
|
+
walk(fullPath);
|
|
539
|
+
}
|
|
540
|
+
else {
|
|
541
|
+
created.push(fullPath.replace(this.workspace, ''));
|
|
542
|
+
}
|
|
543
|
+
}
|
|
544
|
+
};
|
|
545
|
+
walk(this.workspace);
|
|
546
|
+
}
|
|
547
|
+
return created;
|
|
548
|
+
}
|
|
549
|
+
getBlueprint() {
|
|
550
|
+
return this.blueprint;
|
|
551
|
+
}
|
|
552
|
+
getWorkspace() {
|
|
553
|
+
return this.workspace;
|
|
554
|
+
}
|
|
555
|
+
getProjectName() {
|
|
556
|
+
return this.projectName;
|
|
557
|
+
}
|
|
558
|
+
}
|
|
559
|
+
// ============================================================================
|
|
560
|
+
// FORGE ORCHESTRATOR
|
|
561
|
+
// ============================================================================
|
|
562
|
+
export class ForgeOrchestrator {
|
|
563
|
+
engines;
|
|
564
|
+
activeProject;
|
|
565
|
+
constructor() {
|
|
566
|
+
this.engines = new Map();
|
|
567
|
+
}
|
|
568
|
+
createForge(projectName, workspace) {
|
|
569
|
+
const engine = new ForgeEngine(workspace, projectName);
|
|
570
|
+
this.engines.set(projectName, engine);
|
|
571
|
+
this.activeProject = projectName;
|
|
572
|
+
return engine;
|
|
573
|
+
}
|
|
574
|
+
getForge(projectName) {
|
|
575
|
+
return this.engines.get(projectName);
|
|
576
|
+
}
|
|
577
|
+
getActiveForge() {
|
|
578
|
+
if (this.activeProject) {
|
|
579
|
+
return this.engines.get(this.activeProject);
|
|
580
|
+
}
|
|
581
|
+
return undefined;
|
|
582
|
+
}
|
|
583
|
+
listProjects() {
|
|
584
|
+
return [...this.engines.keys()];
|
|
585
|
+
}
|
|
586
|
+
async buildMultiProject(directives, parallel = false) {
|
|
587
|
+
const results = {};
|
|
588
|
+
if (parallel) {
|
|
589
|
+
const tasks = Object.entries(directives).map(async ([projectName, directive]) => {
|
|
590
|
+
const engine = this.engines.get(projectName);
|
|
591
|
+
if (engine) {
|
|
592
|
+
const blueprint = await engine.processDirective(directive);
|
|
593
|
+
const result = await engine.forge(blueprint);
|
|
594
|
+
return { projectName, result };
|
|
595
|
+
}
|
|
596
|
+
return { projectName, result: null };
|
|
597
|
+
});
|
|
598
|
+
const buildResults = await Promise.all(tasks);
|
|
599
|
+
for (const { projectName, result } of buildResults) {
|
|
600
|
+
if (result) {
|
|
601
|
+
results[projectName] = result;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
else {
|
|
606
|
+
for (const [projectName, directive] of Object.entries(directives)) {
|
|
607
|
+
const engine = this.engines.get(projectName);
|
|
608
|
+
if (engine) {
|
|
609
|
+
const blueprint = await engine.processDirective(directive);
|
|
610
|
+
results[projectName] = await engine.forge(blueprint);
|
|
611
|
+
}
|
|
612
|
+
}
|
|
613
|
+
}
|
|
614
|
+
return results;
|
|
615
|
+
}
|
|
616
|
+
getOrchestratorStats() {
|
|
617
|
+
const projectStats = {};
|
|
618
|
+
for (const [name, engine] of this.engines) {
|
|
619
|
+
projectStats[name] = engine.getForgeStats();
|
|
620
|
+
}
|
|
621
|
+
return {
|
|
622
|
+
totalProjects: this.engines.size,
|
|
623
|
+
activeProject: this.activeProject,
|
|
624
|
+
projects: projectStats,
|
|
625
|
+
};
|
|
626
|
+
}
|
|
627
|
+
}
|
|
628
|
+
// ============================================================================
|
|
629
|
+
// GLOBAL INSTANCES
|
|
630
|
+
// ============================================================================
|
|
631
|
+
let forgeEngineInstance = null;
|
|
632
|
+
let forgeOrchestratorInstance = null;
|
|
633
|
+
export function getForgeEngine(workspace) {
|
|
634
|
+
if (!forgeEngineInstance) {
|
|
635
|
+
forgeEngineInstance = new ForgeEngine(workspace);
|
|
636
|
+
}
|
|
637
|
+
return forgeEngineInstance;
|
|
638
|
+
}
|
|
639
|
+
export function getForgeOrchestrator() {
|
|
640
|
+
if (!forgeOrchestratorInstance) {
|
|
641
|
+
forgeOrchestratorInstance = new ForgeOrchestrator();
|
|
642
|
+
}
|
|
643
|
+
return forgeOrchestratorInstance;
|
|
644
|
+
}
|
|
645
|
+
export function resetForgeEngine() {
|
|
646
|
+
forgeEngineInstance = null;
|
|
647
|
+
}
|
|
648
|
+
// ============================================================================
|
|
649
|
+
// EXPORT
|
|
650
|
+
// ============================================================================
|
|
651
|
+
export default ForgeEngine;
|
|
652
|
+
//# sourceMappingURL=forgeEngine.js.map
|