@kapeta/local-cluster-service 0.52.3 → 0.53.0
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/CHANGELOG.md +7 -0
- package/dist/cjs/src/storm/codegen.d.ts +1 -0
- package/dist/cjs/src/storm/codegen.js +100 -94
- package/dist/cjs/src/storm/event-parser.js +3 -1
- package/dist/cjs/src/storm/events.d.ts +23 -5
- package/dist/cjs/src/storm/events.js +10 -1
- package/dist/cjs/src/storm/routes.js +1 -0
- package/dist/cjs/src/storm/stormClient.js +6 -1
- package/dist/cjs/src/storm/stream.d.ts +1 -0
- package/dist/cjs/src/storm/stream.js +8 -2
- package/dist/esm/src/storm/codegen.d.ts +1 -0
- package/dist/esm/src/storm/codegen.js +100 -94
- package/dist/esm/src/storm/event-parser.js +3 -1
- package/dist/esm/src/storm/events.d.ts +23 -5
- package/dist/esm/src/storm/events.js +10 -1
- package/dist/esm/src/storm/routes.js +1 -0
- package/dist/esm/src/storm/stormClient.js +6 -1
- package/dist/esm/src/storm/stream.d.ts +1 -0
- package/dist/esm/src/storm/stream.js +8 -2
- package/package.json +1 -1
- package/src/storm/codegen.ts +180 -117
- package/src/storm/event-parser.ts +5 -2
- package/src/storm/events.ts +26 -5
- package/src/storm/routes.ts +1 -0
- package/src/storm/stormClient.ts +10 -2
- package/src/storm/stream.ts +8 -2
package/CHANGELOG.md
CHANGED
@@ -1,3 +1,10 @@
|
|
1
|
+
# [0.53.0](https://github.com/kapetacom/local-cluster-service/compare/v0.52.3...v0.53.0) (2024-06-12)
|
2
|
+
|
3
|
+
|
4
|
+
### Features
|
5
|
+
|
6
|
+
* Emit code fixing events to UI ([#172](https://github.com/kapetacom/local-cluster-service/issues/172)) ([c10f5d0](https://github.com/kapetacom/local-cluster-service/commit/c10f5d03fdcf696085b2114aae45510a46ee6ec3))
|
7
|
+
|
1
8
|
## [0.52.3](https://github.com/kapetacom/local-cluster-service/compare/v0.52.2...v0.52.3) (2024-06-12)
|
2
9
|
|
3
10
|
|
@@ -34,6 +34,7 @@ exports.StormCodegen = void 0;
|
|
34
34
|
const codegen_1 = require("@kapeta/codegen");
|
35
35
|
const codeGeneratorManager_1 = require("../codeGeneratorManager");
|
36
36
|
const stormClient_1 = require("./stormClient");
|
37
|
+
const events_1 = require("./events");
|
37
38
|
const event_parser_1 = require("./event-parser");
|
38
39
|
const stream_1 = require("./stream");
|
39
40
|
const nodejs_utils_1 = require("@kapeta/nodejs-utils");
|
@@ -44,8 +45,8 @@ const node_os_1 = __importDefault(require("node:os"));
|
|
44
45
|
const fs_1 = require("fs");
|
45
46
|
const yaml_1 = __importDefault(require("yaml"));
|
46
47
|
const fs = __importStar(require("node:fs"));
|
47
|
-
const uuid_1 = require("uuid");
|
48
48
|
const SIMULATED_DELAY = 1000;
|
49
|
+
const ENABLE_SIMULATED_DELAY = false;
|
49
50
|
class SimulatedFileDelay {
|
50
51
|
file;
|
51
52
|
stream;
|
@@ -149,43 +150,8 @@ class StormCodegen {
|
|
149
150
|
},
|
150
151
|
});
|
151
152
|
break;
|
152
|
-
case 'FILE_START':
|
153
|
-
case 'FILE_CHUNK_RESET':
|
154
|
-
this.out.emit('data', {
|
155
|
-
...data,
|
156
|
-
payload: {
|
157
|
-
...data.payload,
|
158
|
-
blockName,
|
159
|
-
blockRef,
|
160
|
-
instanceId,
|
161
|
-
},
|
162
|
-
});
|
163
|
-
break;
|
164
|
-
case 'FILE_CHUNK':
|
165
|
-
this.out.emit('data', {
|
166
|
-
...data,
|
167
|
-
payload: {
|
168
|
-
...data.payload,
|
169
|
-
blockName,
|
170
|
-
blockRef,
|
171
|
-
instanceId,
|
172
|
-
},
|
173
|
-
});
|
174
|
-
break;
|
175
|
-
case 'FILE_STATE':
|
176
|
-
this.out.emit('data', {
|
177
|
-
...data,
|
178
|
-
payload: {
|
179
|
-
...data.payload,
|
180
|
-
blockName,
|
181
|
-
blockRef,
|
182
|
-
instanceId,
|
183
|
-
},
|
184
|
-
});
|
185
|
-
break;
|
186
153
|
case 'FILE_DONE':
|
187
154
|
return this.handleFileDoneOutput(blockUri, blockName, data);
|
188
|
-
break;
|
189
155
|
}
|
190
156
|
}
|
191
157
|
handleFileEvents(blockUri, blockName, data) {
|
@@ -299,10 +265,11 @@ class StormCodegen {
|
|
299
265
|
}
|
300
266
|
// Gather the context files for implementation. These will be all be passed to the AI
|
301
267
|
const contextFiles = relevantFiles.filter((file) => ![codegen_1.AIFileTypes.SERVICE, codegen_1.AIFileTypes.WEB_SCREEN].includes(file.type));
|
268
|
+
const blockUri = (0, nodejs_utils_1.parseKapetaUri)(block.uri);
|
302
269
|
// Send the service and UI templates to the AI. These will be sent one-by-one in addition to the context files
|
303
270
|
const serviceFiles = allFiles.filter((file) => file.type === codegen_1.AIFileTypes.SERVICE);
|
304
271
|
if (serviceFiles.length > 0) {
|
305
|
-
await this.processTemplates(
|
272
|
+
await this.processTemplates(blockUri, block.aiName, stormClient_1.stormClient.createServiceImplementation.bind(stormClient_1.stormClient), serviceFiles, contextFiles);
|
306
273
|
}
|
307
274
|
const basePath = this.getBasePath(block.content.metadata.name);
|
308
275
|
if (this.isAborted()) {
|
@@ -322,7 +289,7 @@ class StormCodegen {
|
|
322
289
|
const filePath = (0, path_2.join)(basePath, screenFile.payload.filename);
|
323
290
|
await (0, promises_1.writeFile)(filePath, screenFile.payload.content);
|
324
291
|
}
|
325
|
-
const screenFilesConverted = screenFiles.map(screenFile => {
|
292
|
+
const screenFilesConverted = screenFiles.map((screenFile) => {
|
326
293
|
return {
|
327
294
|
filename: screenFile.payload.filename,
|
328
295
|
content: screenFile.payload.content,
|
@@ -332,10 +299,12 @@ class StormCodegen {
|
|
332
299
|
};
|
333
300
|
});
|
334
301
|
allFiles.push(...screenFilesConverted);
|
302
|
+
const blockRef = block.uri;
|
303
|
+
this.emitBlockStatus(blockUri, block.aiName, events_1.StormEventBlockStatusType.QA);
|
335
304
|
const filesToBeFixed = serviceFiles.concat(contextFiles).concat(screenFilesConverted);
|
336
305
|
const codeGenerator = new codegen_1.BlockCodeGenerator(block.content);
|
337
|
-
|
338
|
-
|
306
|
+
this.emitBlockStatus(blockUri, block.aiName, events_1.StormEventBlockStatusType.BUILDING);
|
307
|
+
await this.verifyAndFixCode(blockUri, block.aiName, codeGenerator, basePath, filesToBeFixed, allFiles);
|
339
308
|
this.out.emit('data', {
|
340
309
|
type: 'BLOCK_READY',
|
341
310
|
reason: 'Block ready',
|
@@ -348,7 +317,20 @@ class StormCodegen {
|
|
348
317
|
},
|
349
318
|
});
|
350
319
|
}
|
351
|
-
|
320
|
+
emitBlockStatus(blockUri, blockName, status) {
|
321
|
+
this.out.emit('data', {
|
322
|
+
type: 'BLOCK_STATUS',
|
323
|
+
reason: status,
|
324
|
+
created: Date.now(),
|
325
|
+
payload: {
|
326
|
+
status,
|
327
|
+
blockName,
|
328
|
+
blockRef: blockUri.toNormalizedString(),
|
329
|
+
instanceId: event_parser_1.StormEventParser.toInstanceIdFromRef(blockUri.toNormalizedString()),
|
330
|
+
},
|
331
|
+
});
|
332
|
+
}
|
333
|
+
async verifyAndFixCode(blockUri, blockName, codeGenerator, basePath, filesToBeFixed, allFiles) {
|
352
334
|
let attempts = 0;
|
353
335
|
let validCode = false;
|
354
336
|
for (let i = 0; i <= 3; i++) {
|
@@ -362,11 +344,17 @@ class StormCodegen {
|
|
362
344
|
}
|
363
345
|
if (result && !result.valid) {
|
364
346
|
console.debug('Validation error:', result);
|
347
|
+
this.emitBlockStatus(blockUri, blockName, events_1.StormEventBlockStatusType.PLANNING_FIX);
|
365
348
|
const errors = await this.classifyErrors(result.error, basePath);
|
366
|
-
|
367
|
-
|
368
|
-
|
349
|
+
if (errors.size > 0) {
|
350
|
+
this.emitBlockStatus(blockUri, blockName, events_1.StormEventBlockStatusType.FIXING);
|
351
|
+
const promises = Array.from(errors.entries()).map(([filename, fileErrors]) => {
|
352
|
+
// todo: only try to fix file if it is part of filesToBeFixed
|
353
|
+
return this.tryToFixFile(blockUri, blockName, basePath, filename, fileErrors, allFiles, codeGenerator);
|
354
|
+
});
|
355
|
+
await Promise.all(promises);
|
369
356
|
}
|
357
|
+
this.emitBlockStatus(blockUri, blockName, events_1.StormEventBlockStatusType.FIX_DONE);
|
370
358
|
}
|
371
359
|
}
|
372
360
|
catch (e) {
|
@@ -380,10 +368,10 @@ class StormCodegen {
|
|
380
368
|
console.error(`Validation failed for ${basePath} after ${attempts} attempts`);
|
381
369
|
}
|
382
370
|
}
|
383
|
-
async tryToFixFile(basePath, filename, fileErrors, allFiles, codeGenerator) {
|
371
|
+
async tryToFixFile(blockUri, blockName, basePath, filename, fileErrors, allFiles, codeGenerator) {
|
384
372
|
console.log(`Processing ${filename}`);
|
385
373
|
const language = await codeGenerator.language();
|
386
|
-
const relevantFiles = allFiles.filter(file => file.type != codegen_1.AIFileTypes.IGNORE);
|
374
|
+
const relevantFiles = allFiles.filter((file) => file.type != codegen_1.AIFileTypes.IGNORE);
|
387
375
|
for (let attempts = 1; attempts <= 5; attempts++) {
|
388
376
|
if (fileErrors.length == 0) {
|
389
377
|
console.log(`No more errors for ${filename}`);
|
@@ -393,17 +381,17 @@ class StormCodegen {
|
|
393
381
|
const filesForContext = await this.getErrorDetailsForFile(basePath, filename, fileErrors[0], relevantFiles, language);
|
394
382
|
console.log(`Get error details for ${filename} requesting code fixes`);
|
395
383
|
const fix = this.createFixRequestForFile(basePath, filename, fileErrors[0], filesForContext, relevantFiles, language);
|
396
|
-
const
|
384
|
+
const codeFixFile = await this.codeFix(blockUri, blockName, fix);
|
397
385
|
console.log(`Got fixed code for ${filename}`);
|
398
|
-
|
399
|
-
|
400
|
-
|
401
|
-
|
402
|
-
|
403
|
-
|
404
|
-
|
405
|
-
(0, fs_1.writeFileSync)(filePath, codeFixFile.content);
|
386
|
+
const filePath = codeFixFile.filename.indexOf(basePath) > -1
|
387
|
+
? codeFixFile.filename
|
388
|
+
: (0, path_2.join)(basePath, codeFixFile.filename);
|
389
|
+
const existing = (0, fs_1.readFileSync)(filePath);
|
390
|
+
if (existing.toString().replace(/(\r\n|\r|\n)+$/, '') == codeFixFile.content.replace(/(\r\n|\r|\n)+$/, '')) {
|
391
|
+
console.log(`${filename} not changed by gemini`);
|
392
|
+
continue;
|
406
393
|
}
|
394
|
+
(0, fs_1.writeFileSync)(filePath, codeFixFile.content);
|
407
395
|
const result = await codeGenerator.validateForTarget(basePath);
|
408
396
|
if (result && result.valid) {
|
409
397
|
return;
|
@@ -421,7 +409,11 @@ class StormCodegen {
|
|
421
409
|
errorStream.on('data', (evt) => {
|
422
410
|
if (evt.type === 'ERROR_CLASSIFIER') {
|
423
411
|
const eventFileName = this.removePrefix(basePath + '/', evt.payload.filename);
|
424
|
-
const fix = {
|
412
|
+
const fix = {
|
413
|
+
error: evt.payload.error,
|
414
|
+
lineNumber: evt.payload.lineNumber,
|
415
|
+
column: evt.payload.column,
|
416
|
+
};
|
425
417
|
let existingFixes = fixes.get(eventFileName);
|
426
418
|
if (existingFixes) {
|
427
419
|
existingFixes.push(fix);
|
@@ -438,24 +430,24 @@ class StormCodegen {
|
|
438
430
|
const filePath = filename.indexOf(basePath) > -1 ? filename : (0, path_2.join)(basePath, filename); // to compensate when compiler returns absolute path
|
439
431
|
return new Promise(async (resolve, reject) => {
|
440
432
|
const request = {
|
441
|
-
|
442
|
-
|
443
|
-
|
444
|
-
|
433
|
+
language: language,
|
434
|
+
sourceFile: {
|
435
|
+
filename: filename,
|
436
|
+
content: (0, fs_1.readFileSync)(filePath, 'utf8'),
|
445
437
|
},
|
446
|
-
|
447
|
-
|
438
|
+
error: error,
|
439
|
+
projectFiles: allFiles.map((f) => f.filename),
|
448
440
|
};
|
449
441
|
const detailsStream = await stormClient_1.stormClient.createErrorDetails(JSON.stringify(request), []);
|
450
442
|
detailsStream.on('data', (evt) => {
|
451
443
|
if (evt.type === 'ERROR_DETAILS') {
|
452
444
|
resolve(evt.payload.files);
|
453
445
|
}
|
454
|
-
reject(new Error(
|
446
|
+
reject(new Error('Error details: Unexpected event [' + evt.type + ']'));
|
455
447
|
});
|
456
448
|
this.out.on('aborted', () => {
|
457
449
|
detailsStream.abort();
|
458
|
-
reject(
|
450
|
+
reject(new Error('aborted'));
|
459
451
|
});
|
460
452
|
detailsStream.on('error', (err) => {
|
461
453
|
reject(err);
|
@@ -466,31 +458,27 @@ class StormCodegen {
|
|
466
458
|
createFixRequestForFile(basePath, filename, error, filesForContext, allFiles, language) {
|
467
459
|
const files = new Set(filesForContext);
|
468
460
|
files.add(filename);
|
469
|
-
const requestedFiles = Array.from(files).flatMap(file => {
|
461
|
+
const requestedFiles = Array.from(files).flatMap((file) => {
|
470
462
|
if (fs.existsSync(file)) {
|
471
463
|
return file;
|
472
464
|
}
|
473
465
|
// file does not exist - look for similar
|
474
466
|
const candidateName = file.split('/').pop();
|
475
|
-
return allFiles
|
476
|
-
.filter(file => file.filename.split('/').pop() === candidateName)
|
477
|
-
.map(f => f.filename);
|
467
|
+
return allFiles.filter((file) => file.filename.split('/').pop() === candidateName).map((f) => f.filename);
|
478
468
|
});
|
479
469
|
const filePath = filename.indexOf(basePath) > -1 ? filename : (0, path_2.join)(basePath, filename);
|
480
470
|
const content = (0, fs_1.readFileSync)(filePath, 'utf8');
|
481
471
|
const affectedLine = this.getErrorLine(error, content);
|
482
472
|
const fixRequest = {
|
483
|
-
|
484
|
-
|
485
|
-
|
486
|
-
|
487
|
-
|
473
|
+
language: language,
|
474
|
+
filename: filename,
|
475
|
+
error: error.error,
|
476
|
+
affectedLine: affectedLine,
|
477
|
+
projectFiles: requestedFiles.map((filename) => {
|
488
478
|
const filePath = filename.indexOf(basePath) > -1 ? filename : (0, path_2.join)(basePath, filename);
|
489
479
|
const content = (0, fs_1.readFileSync)(filePath, 'utf8');
|
490
480
|
return { filename: filename, content: content };
|
491
481
|
}),
|
492
|
-
"conversationId": this.conversationId,
|
493
|
-
"sessionId": (0, uuid_1.v4)()
|
494
482
|
};
|
495
483
|
return JSON.stringify(fixRequest);
|
496
484
|
}
|
@@ -498,7 +486,7 @@ class StormCodegen {
|
|
498
486
|
const lines = sourceCode.split('\n');
|
499
487
|
const errorLine = lines[errorDetails.lineNumber - 1];
|
500
488
|
if (!errorLine) {
|
501
|
-
return
|
489
|
+
return 'Error: Line number out of range.';
|
502
490
|
}
|
503
491
|
return errorLine;
|
504
492
|
}
|
@@ -511,24 +499,36 @@ class StormCodegen {
|
|
511
499
|
/**
|
512
500
|
* Sends the code to the AI for a fix
|
513
501
|
*/
|
514
|
-
async codeFix(fix, history) {
|
502
|
+
async codeFix(blockUri, blockName, fix, history) {
|
515
503
|
return new Promise(async (resolve, reject) => {
|
516
|
-
|
517
|
-
|
518
|
-
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
|
524
|
-
|
525
|
-
|
526
|
-
|
527
|
-
|
528
|
-
|
529
|
-
|
530
|
-
|
531
|
-
|
504
|
+
try {
|
505
|
+
const fixStream = await stormClient_1.stormClient.createCodeFix(fix, history, this.conversationId);
|
506
|
+
let resolved = false;
|
507
|
+
fixStream.on('data', (evt) => {
|
508
|
+
if (this.handleFileEvents(blockUri, blockName, evt)) {
|
509
|
+
return;
|
510
|
+
}
|
511
|
+
if (evt.type === 'CODE_FIX') {
|
512
|
+
resolved = true;
|
513
|
+
resolve(evt.payload);
|
514
|
+
}
|
515
|
+
});
|
516
|
+
this.out.on('aborted', () => {
|
517
|
+
fixStream.abort();
|
518
|
+
reject(new Error('aborted'));
|
519
|
+
});
|
520
|
+
fixStream.on('error', (err) => {
|
521
|
+
reject(err);
|
522
|
+
});
|
523
|
+
fixStream.on('end', () => {
|
524
|
+
if (!resolved) {
|
525
|
+
reject(new Error('Code fix never returned a valid event'));
|
526
|
+
}
|
527
|
+
});
|
528
|
+
}
|
529
|
+
catch (e) {
|
530
|
+
reject(e);
|
531
|
+
}
|
532
532
|
});
|
533
533
|
}
|
534
534
|
/**
|
@@ -564,7 +564,13 @@ class StormCodegen {
|
|
564
564
|
instanceId: event_parser_1.StormEventParser.toInstanceIdFromRef(ref),
|
565
565
|
},
|
566
566
|
};
|
567
|
-
|
567
|
+
if (ENABLE_SIMULATED_DELAY) {
|
568
|
+
// Simulate a delay when sending the file
|
569
|
+
return new SimulatedFileDelay(fileEvent, this.out).start();
|
570
|
+
}
|
571
|
+
else {
|
572
|
+
this.out.emit('data', fileEvent);
|
573
|
+
}
|
568
574
|
});
|
569
575
|
return Promise.all(promises);
|
570
576
|
}
|
@@ -292,7 +292,9 @@ class StormEventParser {
|
|
292
292
|
};
|
293
293
|
}
|
294
294
|
const clientTypes = kaplang_core_1.DSLDataTypeParser.parse(clientConsumerBlock.content.spec.entities.source.value, { ignoreSemantics: true });
|
295
|
-
const apiTypes = kaplang_core_1.DSLDataTypeParser.parse(apiProviderBlock.content.spec.entities?.source?.value, {
|
295
|
+
const apiTypes = kaplang_core_1.DSLDataTypeParser.parse(apiProviderBlock.content.spec.entities?.source?.value, {
|
296
|
+
ignoreSemantics: true,
|
297
|
+
});
|
296
298
|
apiTypes.forEach((apiType) => {
|
297
299
|
if (clientTypes.some((clientType) => clientType.name === apiType.name)) {
|
298
300
|
// Already exists
|
@@ -111,9 +111,8 @@ export interface StormEventCodeFix {
|
|
111
111
|
reason: string;
|
112
112
|
created: number;
|
113
113
|
payload: {
|
114
|
-
|
115
|
-
|
116
|
-
};
|
114
|
+
filename: string;
|
115
|
+
content: string;
|
117
116
|
};
|
118
117
|
}
|
119
118
|
export interface StormEventErrorClassifierInfo {
|
@@ -210,6 +209,24 @@ export interface StormEventBlockReady {
|
|
210
209
|
instanceId: string;
|
211
210
|
};
|
212
211
|
}
|
212
|
+
export declare enum StormEventBlockStatusType {
|
213
|
+
QA = "QA",
|
214
|
+
FIXING = "FIXING",
|
215
|
+
PLANNING_FIX = "PLANNING_FIX",
|
216
|
+
FIX_DONE = "FIX_DONE",
|
217
|
+
BUILDING = "BUILDING"
|
218
|
+
}
|
219
|
+
export interface StormEventBlockStatus {
|
220
|
+
type: 'BLOCK_STATUS';
|
221
|
+
reason: string;
|
222
|
+
created: number;
|
223
|
+
payload: {
|
224
|
+
status: StormEventBlockStatusType;
|
225
|
+
blockName: string;
|
226
|
+
blockRef: string;
|
227
|
+
instanceId: string;
|
228
|
+
};
|
229
|
+
}
|
213
230
|
export interface StormEventDone {
|
214
231
|
type: 'DONE';
|
215
232
|
created: number;
|
@@ -223,7 +240,8 @@ export interface StormEventDefinitionChange {
|
|
223
240
|
export declare enum StormEventPhaseType {
|
224
241
|
META = "META",
|
225
242
|
DEFINITIONS = "DEFINITIONS",
|
226
|
-
IMPLEMENTATION = "IMPLEMENTATION"
|
243
|
+
IMPLEMENTATION = "IMPLEMENTATION",
|
244
|
+
QA = "QA"
|
227
245
|
}
|
228
246
|
export interface StormEventPhases {
|
229
247
|
type: 'PHASE_START' | 'PHASE_END';
|
@@ -232,4 +250,4 @@ export interface StormEventPhases {
|
|
232
250
|
phaseType: StormEventPhaseType;
|
233
251
|
};
|
234
252
|
}
|
235
|
-
export type StormEvent = StormEventCreateBlock | StormEventCreateConnection | StormEventCreatePlanProperties | StormEventInvalidResponse | StormEventPlanRetry | StormEventCreateDSL | StormEventCreateDSLResource | StormEventError | StormEventScreen | StormEventScreenCandidate | StormEventFileLogical | StormEventFileState | StormEventFileDone | StormEventFileChunk | StormEventDone | StormEventDefinitionChange | StormEventErrorClassifier | StormEventCodeFix | StormEventErrorDetails | StormEventBlockReady | StormEventPhases;
|
253
|
+
export type StormEvent = StormEventCreateBlock | StormEventCreateConnection | StormEventCreatePlanProperties | StormEventInvalidResponse | StormEventPlanRetry | StormEventCreateDSL | StormEventCreateDSLResource | StormEventError | StormEventScreen | StormEventScreenCandidate | StormEventFileLogical | StormEventFileState | StormEventFileDone | StormEventFileChunk | StormEventDone | StormEventDefinitionChange | StormEventErrorClassifier | StormEventCodeFix | StormEventErrorDetails | StormEventBlockReady | StormEventPhases | StormEventBlockStatus;
|
@@ -1,9 +1,18 @@
|
|
1
1
|
"use strict";
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
3
|
-
exports.StormEventPhaseType = void 0;
|
3
|
+
exports.StormEventPhaseType = exports.StormEventBlockStatusType = void 0;
|
4
|
+
var StormEventBlockStatusType;
|
5
|
+
(function (StormEventBlockStatusType) {
|
6
|
+
StormEventBlockStatusType["QA"] = "QA";
|
7
|
+
StormEventBlockStatusType["FIXING"] = "FIXING";
|
8
|
+
StormEventBlockStatusType["PLANNING_FIX"] = "PLANNING_FIX";
|
9
|
+
StormEventBlockStatusType["FIX_DONE"] = "FIX_DONE";
|
10
|
+
StormEventBlockStatusType["BUILDING"] = "BUILDING";
|
11
|
+
})(StormEventBlockStatusType || (exports.StormEventBlockStatusType = StormEventBlockStatusType = {}));
|
4
12
|
var StormEventPhaseType;
|
5
13
|
(function (StormEventPhaseType) {
|
6
14
|
StormEventPhaseType["META"] = "META";
|
7
15
|
StormEventPhaseType["DEFINITIONS"] = "DEFINITIONS";
|
8
16
|
StormEventPhaseType["IMPLEMENTATION"] = "IMPLEMENTATION";
|
17
|
+
StormEventPhaseType["QA"] = "QA";
|
9
18
|
})(StormEventPhaseType || (exports.StormEventPhaseType = StormEventPhaseType = {}));
|
@@ -10,6 +10,7 @@ class StormStream extends node_events_1.EventEmitter {
|
|
10
10
|
conversationId = '';
|
11
11
|
lines = [];
|
12
12
|
aborted = false;
|
13
|
+
done = false;
|
13
14
|
constructor(prompt = '', conversationId) {
|
14
15
|
super();
|
15
16
|
this.conversationId = conversationId || '';
|
@@ -34,6 +35,7 @@ class StormStream extends node_events_1.EventEmitter {
|
|
34
35
|
}
|
35
36
|
}
|
36
37
|
end() {
|
38
|
+
this.done = true;
|
37
39
|
this.emit('end');
|
38
40
|
}
|
39
41
|
on(event, listener) {
|
@@ -43,6 +45,9 @@ class StormStream extends node_events_1.EventEmitter {
|
|
43
45
|
return super.emit(eventName, ...args);
|
44
46
|
}
|
45
47
|
waitForDone() {
|
48
|
+
if (this.done) {
|
49
|
+
return Promise.resolve();
|
50
|
+
}
|
46
51
|
return new Promise((resolve, reject) => {
|
47
52
|
const errorHandler = (err) => {
|
48
53
|
this.removeListener('error', errorHandler);
|
@@ -54,8 +59,8 @@ class StormStream extends node_events_1.EventEmitter {
|
|
54
59
|
this.removeListener('end', endHandler);
|
55
60
|
resolve();
|
56
61
|
};
|
57
|
-
this.
|
58
|
-
this.
|
62
|
+
this.on('error', errorHandler);
|
63
|
+
this.on('end', endHandler);
|
59
64
|
});
|
60
65
|
}
|
61
66
|
abort() {
|
@@ -63,6 +68,7 @@ class StormStream extends node_events_1.EventEmitter {
|
|
63
68
|
return;
|
64
69
|
}
|
65
70
|
this.aborted = true;
|
71
|
+
this.done = true;
|
66
72
|
this.emit('aborted');
|
67
73
|
}
|
68
74
|
}
|