gameforge-cli 0.1.0 ā 0.2.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/README.md +81 -41
- package/dist/agents/base/BaseAgent.d.ts +31 -0
- package/dist/agents/base/BaseAgent.d.ts.map +1 -1
- package/dist/agents/base/BaseAgent.js +57 -0
- package/dist/agents/base/BaseAgent.js.map +1 -1
- package/dist/agents/core/Architect.d.ts +17 -5
- package/dist/agents/core/Architect.d.ts.map +1 -1
- package/dist/agents/core/Architect.js +263 -150
- package/dist/agents/core/Architect.js.map +1 -1
- package/dist/agents/core/Chaos.d.ts +4 -0
- package/dist/agents/core/Chaos.d.ts.map +1 -1
- package/dist/agents/core/Chaos.js +46 -11
- package/dist/agents/core/Chaos.js.map +1 -1
- package/dist/agents/core/Consistency.d.ts +1 -0
- package/dist/agents/core/Consistency.d.ts.map +1 -1
- package/dist/agents/core/Consistency.js +86 -11
- package/dist/agents/core/Consistency.js.map +1 -1
- package/dist/agents/core/Modifier.d.ts +13 -0
- package/dist/agents/core/Modifier.d.ts.map +1 -0
- package/dist/agents/core/Modifier.js +141 -0
- package/dist/agents/core/Modifier.js.map +1 -0
- package/dist/agents/core/Remediation.d.ts +3 -1
- package/dist/agents/core/Remediation.d.ts.map +1 -1
- package/dist/agents/core/Remediation.js +63 -3
- package/dist/agents/core/Remediation.js.map +1 -1
- package/dist/agents/specialists/CreativeSpecialist.d.ts.map +1 -1
- package/dist/agents/specialists/CreativeSpecialist.js +94 -25
- package/dist/agents/specialists/CreativeSpecialist.js.map +1 -1
- package/dist/agents/specialists/EntitySpecialist.d.ts.map +1 -1
- package/dist/agents/specialists/EntitySpecialist.js +63 -25
- package/dist/agents/specialists/EntitySpecialist.js.map +1 -1
- package/dist/agents/specialists/FeatureSpecialist.d.ts.map +1 -1
- package/dist/agents/specialists/FeatureSpecialist.js +53 -39
- package/dist/agents/specialists/FeatureSpecialist.js.map +1 -1
- package/dist/agents/specialists/TechSpecialist.d.ts.map +1 -1
- package/dist/agents/specialists/TechSpecialist.js +69 -32
- package/dist/agents/specialists/TechSpecialist.js.map +1 -1
- package/dist/config/schema.d.ts +1319 -709
- package/dist/config/schema.d.ts.map +1 -1
- package/dist/config/schema.js +142 -52
- package/dist/config/schema.js.map +1 -1
- package/dist/config/templates.d.ts.map +1 -1
- package/dist/config/templates.js +6 -66
- package/dist/config/templates.js.map +1 -1
- package/dist/core/Orchestrator.d.ts +17 -3
- package/dist/core/Orchestrator.d.ts.map +1 -1
- package/dist/core/Orchestrator.js +46 -16
- package/dist/core/Orchestrator.js.map +1 -1
- package/dist/index.js +335 -195
- package/dist/index.js.map +1 -1
- package/dist/types/issueReview.d.ts +19 -0
- package/dist/types/issueReview.d.ts.map +1 -0
- package/dist/types/issueReview.js +3 -0
- package/dist/types/issueReview.js.map +1 -0
- package/dist/utils/costTracker.d.ts +28 -0
- package/dist/utils/costTracker.d.ts.map +1 -1
- package/dist/utils/costTracker.js +71 -1
- package/dist/utils/costTracker.js.map +1 -1
- package/dist/utils/disambiguationHelper.d.ts +54 -0
- package/dist/utils/disambiguationHelper.d.ts.map +1 -0
- package/dist/utils/disambiguationHelper.js +252 -0
- package/dist/utils/disambiguationHelper.js.map +1 -0
- package/dist/utils/issueReviewer.d.ts +6 -0
- package/dist/utils/issueReviewer.d.ts.map +1 -0
- package/dist/utils/issueReviewer.js +159 -0
- package/dist/utils/issueReviewer.js.map +1 -0
- package/dist/utils/issueSelector.d.ts +26 -0
- package/dist/utils/issueSelector.d.ts.map +1 -0
- package/dist/utils/issueSelector.js +132 -0
- package/dist/utils/issueSelector.js.map +1 -0
- package/package.json +1 -1
- package/dist/core/CheckpointManager.d.ts +0 -16
- package/dist/core/CheckpointManager.d.ts.map +0 -1
- package/dist/core/CheckpointManager.js +0 -52
- package/dist/core/CheckpointManager.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -29,6 +29,8 @@ const TechSpecialist_1 = require("./agents/specialists/TechSpecialist");
|
|
|
29
29
|
const CreativeSpecialist_1 = require("./agents/specialists/CreativeSpecialist");
|
|
30
30
|
const Orchestrator_1 = require("./core/Orchestrator");
|
|
31
31
|
const debugLogger_1 = require("./utils/debugLogger");
|
|
32
|
+
const issueReviewer_1 = require("./utils/issueReviewer");
|
|
33
|
+
const Modifier_1 = require("./agents/core/Modifier");
|
|
32
34
|
dotenv_1.default.config();
|
|
33
35
|
const program = new commander_1.Command();
|
|
34
36
|
program
|
|
@@ -77,6 +79,13 @@ program
|
|
|
77
79
|
});
|
|
78
80
|
console.log(picocolors_1.default.dim('Usage: gameforge create --template <id>\n'));
|
|
79
81
|
});
|
|
82
|
+
program
|
|
83
|
+
.command('modify <sessionId>')
|
|
84
|
+
.description('Modify an existing game design document')
|
|
85
|
+
.option('-d, --debug', 'Enable debug logging to file')
|
|
86
|
+
.action(async (sessionId, options) => {
|
|
87
|
+
await runModifyFlow(sessionId, options);
|
|
88
|
+
});
|
|
80
89
|
program.parse();
|
|
81
90
|
async function runCreationFlow(options) {
|
|
82
91
|
console.clear();
|
|
@@ -142,12 +151,19 @@ async function runCreationFlow(options) {
|
|
|
142
151
|
// Phase 1: Discovery
|
|
143
152
|
console.log(picocolors_1.default.cyan('\nš Phase 1: Discovery\n'));
|
|
144
153
|
stateMachine.transition(StateMachine_1.GameForgePhase.DISCOVERY);
|
|
154
|
+
costTracker.startPhase('discovery');
|
|
145
155
|
const inquisitor = new Inquisitor_1.Inquisitor(apiKey, costTracker, modelSelector);
|
|
146
156
|
const questions = getInquisitorQuestions(options.template);
|
|
147
157
|
const transcript = await inquisitor.execute(questions);
|
|
148
158
|
transcript.forEach(entry => {
|
|
149
159
|
stateMachine.addTranscriptEntry(entry.question, entry.answer, entry.autoGenerated);
|
|
150
160
|
});
|
|
161
|
+
// End discovery phase and show cost
|
|
162
|
+
const discoveryCost = costTracker.endPhase();
|
|
163
|
+
if (discoveryCost && discoveryCost.operations > 0) {
|
|
164
|
+
console.log(picocolors_1.default.green('\nā Discovery complete'));
|
|
165
|
+
costTracker.printPhaseSummary(discoveryCost);
|
|
166
|
+
}
|
|
151
167
|
// Gate 1: Review Concept
|
|
152
168
|
console.log(picocolors_1.default.cyan('\nš Concept Review\n'));
|
|
153
169
|
stateMachine.transition(StateMachine_1.GameForgePhase.REVIEW_CONCEPT);
|
|
@@ -161,6 +177,7 @@ async function runCreationFlow(options) {
|
|
|
161
177
|
// Phase 2: Architecture
|
|
162
178
|
console.log(picocolors_1.default.cyan('\nšļø Phase 2: Architecture\n'));
|
|
163
179
|
stateMachine.transition(StateMachine_1.GameForgePhase.ARCHITECTURE);
|
|
180
|
+
costTracker.startPhase('architecture');
|
|
164
181
|
const spinner = (0, ora_1.default)('Generating Game Bible...').start();
|
|
165
182
|
const architect = new Architect_1.Architect(apiKey, costTracker, modelSelector);
|
|
166
183
|
let bible = await architect.execute(transcript, (message) => {
|
|
@@ -173,6 +190,11 @@ async function runCreationFlow(options) {
|
|
|
173
190
|
}
|
|
174
191
|
stateMachine.updateBible(bible);
|
|
175
192
|
spinner.succeed('Game Bible generated');
|
|
193
|
+
// End architecture phase and show cost
|
|
194
|
+
const architectureCost = costTracker.endPhase();
|
|
195
|
+
if (architectureCost) {
|
|
196
|
+
costTracker.printPhaseSummary(architectureCost);
|
|
197
|
+
}
|
|
176
198
|
// Save checkpoint
|
|
177
199
|
await sessionManager.saveCheckpoint(sessionId, stateMachine.getState(), 'after_architecture');
|
|
178
200
|
// Gate 2: Review Data
|
|
@@ -188,7 +210,8 @@ async function runCreationFlow(options) {
|
|
|
188
210
|
// Phase 3: Production (Specialists)
|
|
189
211
|
console.log(picocolors_1.default.cyan('\nšØ Phase 3: Production\n'));
|
|
190
212
|
stateMachine.transition(StateMachine_1.GameForgePhase.PRODUCTION);
|
|
191
|
-
|
|
213
|
+
costTracker.startPhase('production');
|
|
214
|
+
const orchestrator = new Orchestrator_1.SpecialistOrchestrator();
|
|
192
215
|
const specialists = [
|
|
193
216
|
{ name: 'Creative Direction', agent: new CreativeSpecialist_1.CreativeSpecialist(apiKey, costTracker, modelSelector) },
|
|
194
217
|
{ name: 'Feature Specifications', agent: new FeatureSpecialist_1.FeatureSpecialist(apiKey, costTracker, modelSelector) },
|
|
@@ -196,9 +219,16 @@ async function runCreationFlow(options) {
|
|
|
196
219
|
{ name: 'Technical Specifications', agent: new TechSpecialist_1.TechSpecialist(apiKey, costTracker, modelSelector) }
|
|
197
220
|
];
|
|
198
221
|
let markdownSections = await orchestrator.runAllSpecialists(bible, specialists);
|
|
222
|
+
// End production phase and show cost
|
|
223
|
+
const productionCost = costTracker.endPhase();
|
|
224
|
+
if (productionCost) {
|
|
225
|
+
console.log(picocolors_1.default.green('\nā Production complete'));
|
|
226
|
+
costTracker.printPhaseSummary(productionCost);
|
|
227
|
+
}
|
|
199
228
|
// Phase 4: Validation
|
|
200
229
|
console.log(picocolors_1.default.cyan('\nā
Phase 4: Validation\n'));
|
|
201
230
|
stateMachine.transition(StateMachine_1.GameForgePhase.VALIDATION);
|
|
231
|
+
costTracker.startPhase('validation');
|
|
202
232
|
// Run consistency check
|
|
203
233
|
const consistencyAgent = new Consistency_1.ConsistencyAgent();
|
|
204
234
|
let currentConsistencyIssues = consistencyAgent.validate(bible);
|
|
@@ -210,106 +240,86 @@ async function runCreationFlow(options) {
|
|
|
210
240
|
chaosSpinner.text = `Chaos Agent: ${message}`;
|
|
211
241
|
});
|
|
212
242
|
chaosSpinner.succeed(`Found ${currentChaosIssues.length} design issues`);
|
|
213
|
-
//
|
|
214
|
-
const
|
|
215
|
-
|
|
243
|
+
// End validation phase and show cost
|
|
244
|
+
const validationCost = costTracker.endPhase();
|
|
245
|
+
if (validationCost) {
|
|
246
|
+
costTracker.printPhaseSummary(validationCost);
|
|
247
|
+
}
|
|
248
|
+
// Gate 3: Review Issues One by One
|
|
249
|
+
stateMachine.transition(StateMachine_1.GameForgePhase.REVIEW_ISSUES);
|
|
216
250
|
let fixesApplied = false;
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
});
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
251
|
+
const totalIssues = currentConsistencyIssues.length + currentChaosIssues.length;
|
|
252
|
+
if (totalIssues > 0) {
|
|
253
|
+
console.log(picocolors_1.default.yellow(`\nā ļø ${totalIssues} issues found. Let's review them one by one.\n`));
|
|
254
|
+
// Review each issue one by one
|
|
255
|
+
const reviewed = await (0, issueReviewer_1.reviewIssuesOneByOne)(currentConsistencyIssues, currentChaosIssues);
|
|
256
|
+
// If user selected any issues to fix
|
|
257
|
+
if (reviewed.toFix.length > 0) {
|
|
258
|
+
const proceed = await confirmGate(`Fix ${reviewed.toFix.length} selected issue(s)?`);
|
|
259
|
+
if (proceed) {
|
|
260
|
+
fixesApplied = true;
|
|
261
|
+
console.log(picocolors_1.default.cyan(`\nš§ Fixing ${reviewed.toFix.length} issues...\n`));
|
|
262
|
+
costTracker.startPhase('remediation');
|
|
263
|
+
const remediationSpinner = (0, ora_1.default)('Running Remediation Agent...').start();
|
|
264
|
+
const remediationAgent = new Remediation_1.Remediation(apiKey, costTracker, modelSelector);
|
|
265
|
+
try {
|
|
266
|
+
// Convert to IssueWithNotes format for Remediation
|
|
267
|
+
const issuesToFix = (0, issueReviewer_1.convertToIssuesWithNotes)(reviewed);
|
|
268
|
+
const result = await remediationAgent.execute(bible, issuesToFix, (message) => {
|
|
269
|
+
remediationSpinner.text = `Remediation: ${message}`;
|
|
270
|
+
});
|
|
271
|
+
remediationSpinner.succeed(`Fixed ${result.fixedIssues.length} issues`);
|
|
272
|
+
// End remediation phase and show cost
|
|
273
|
+
const remediationCost = costTracker.endPhase();
|
|
274
|
+
if (remediationCost) {
|
|
275
|
+
costTracker.printPhaseSummary(remediationCost);
|
|
276
|
+
}
|
|
277
|
+
if (result.fixedIssues.length > 0) {
|
|
278
|
+
console.log(picocolors_1.default.green('\nFixes applied:'));
|
|
279
|
+
result.fixedIssues.forEach((fix) => {
|
|
280
|
+
console.log(picocolors_1.default.dim(` ā ${fix}`));
|
|
281
|
+
});
|
|
282
|
+
}
|
|
283
|
+
if (result.unfixableIssues.length > 0) {
|
|
284
|
+
console.log(picocolors_1.default.yellow('\nCould not fix:'));
|
|
285
|
+
result.unfixableIssues.forEach((issue) => {
|
|
286
|
+
console.log(picocolors_1.default.dim(` ā ${issue}`));
|
|
287
|
+
});
|
|
288
|
+
}
|
|
289
|
+
// Update bible
|
|
290
|
+
bible = result.updatedBible;
|
|
291
|
+
stateMachine.updateBible(bible);
|
|
292
|
+
}
|
|
293
|
+
catch (error) {
|
|
294
|
+
remediationSpinner.fail('Remediation failed');
|
|
295
|
+
console.error(picocolors_1.default.red('Error during remediation:'), error);
|
|
296
|
+
const continueAnyway = await confirmGate('Continue to save despite remediation failure?');
|
|
297
|
+
if (!continueAnyway) {
|
|
298
|
+
console.log(picocolors_1.default.yellow('Exiting...'));
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
}
|
|
233
302
|
}
|
|
234
303
|
}
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
// Determine action based on state
|
|
239
|
-
let action;
|
|
240
|
-
if (totalIssues === 0) {
|
|
241
|
-
const proceed = await confirmGate('Save and export GDD?');
|
|
242
|
-
action = proceed ? 'save' : 'exit';
|
|
243
|
-
}
|
|
244
|
-
else if (fixAttempts >= MAX_FIX_ATTEMPTS) {
|
|
245
|
-
console.log(picocolors_1.default.yellow(`\nMaximum fix attempts (${MAX_FIX_ATTEMPTS}) reached.`));
|
|
246
|
-
const proceed = await confirmGate('Save and export GDD with remaining issues?');
|
|
247
|
-
action = proceed ? 'save' : 'exit';
|
|
248
|
-
}
|
|
249
|
-
else {
|
|
250
|
-
action = await selectReviewAction();
|
|
251
|
-
}
|
|
252
|
-
if (action === 'exit') {
|
|
304
|
+
// Final confirmation to save
|
|
305
|
+
const saveConfirm = await confirmGate('Save and export GDD?');
|
|
306
|
+
if (!saveConfirm) {
|
|
253
307
|
console.log(picocolors_1.default.yellow('Exiting...'));
|
|
254
308
|
return;
|
|
255
309
|
}
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
const remediationSpinner = (0, ora_1.default)('Running Remediation Agent...').start();
|
|
264
|
-
const remediationAgent = new Remediation_1.Remediation(apiKey, costTracker, modelSelector);
|
|
265
|
-
try {
|
|
266
|
-
const result = await remediationAgent.execute(bible, currentConsistencyIssues, currentChaosIssues, (message) => { remediationSpinner.text = `Remediation: ${message}`; });
|
|
267
|
-
remediationSpinner.succeed(`Fixed ${result.fixedIssues.length} issues`);
|
|
268
|
-
if (result.fixedIssues.length > 0) {
|
|
269
|
-
console.log(picocolors_1.default.green('\nFixes applied:'));
|
|
270
|
-
result.fixedIssues.forEach(fix => {
|
|
271
|
-
console.log(picocolors_1.default.dim(` ā ${fix}`));
|
|
272
|
-
});
|
|
273
|
-
}
|
|
274
|
-
if (result.unfixableIssues.length > 0) {
|
|
275
|
-
console.log(picocolors_1.default.yellow('\nCould not fix:'));
|
|
276
|
-
result.unfixableIssues.forEach(issue => {
|
|
277
|
-
console.log(picocolors_1.default.dim(` ā ${issue}`));
|
|
278
|
-
});
|
|
279
|
-
}
|
|
280
|
-
// Update bible
|
|
281
|
-
bible = result.updatedBible;
|
|
282
|
-
stateMachine.updateBible(bible);
|
|
283
|
-
// Transition back to production for re-validation
|
|
284
|
-
stateMachine.transition(StateMachine_1.GameForgePhase.PRODUCTION);
|
|
285
|
-
// Re-run validation
|
|
286
|
-
console.log(picocolors_1.default.cyan('\nš Re-validating...\n'));
|
|
287
|
-
stateMachine.transition(StateMachine_1.GameForgePhase.VALIDATION);
|
|
288
|
-
const newConsistencyAgent = new Consistency_1.ConsistencyAgent();
|
|
289
|
-
currentConsistencyIssues = newConsistencyAgent.validate(bible);
|
|
290
|
-
console.log(picocolors_1.default.yellow(`Found ${currentConsistencyIssues.length} consistency issues`));
|
|
291
|
-
chaosSpinner = (0, ora_1.default)('Re-running Chaos Agent...').start();
|
|
292
|
-
const newChaosAgent = new Chaos_1.Chaos(apiKey, costTracker, modelSelector);
|
|
293
|
-
currentChaosIssues = await newChaosAgent.execute(bible, (message) => {
|
|
294
|
-
chaosSpinner.text = `Chaos Agent: ${message}`;
|
|
295
|
-
});
|
|
296
|
-
chaosSpinner.succeed(`Found ${currentChaosIssues.length} design issues`);
|
|
297
|
-
}
|
|
298
|
-
catch (error) {
|
|
299
|
-
remediationSpinner.fail('Remediation failed');
|
|
300
|
-
console.error(picocolors_1.default.red('Error during remediation:'), error);
|
|
301
|
-
const continueAnyway = await confirmGate('Continue to save despite remediation failure?');
|
|
302
|
-
if (!continueAnyway) {
|
|
303
|
-
console.log(picocolors_1.default.yellow('Exiting...'));
|
|
304
|
-
return;
|
|
305
|
-
}
|
|
306
|
-
break;
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
console.log(picocolors_1.default.green('\nā No issues found!'));
|
|
313
|
+
const proceed = await confirmGate('Save and export GDD?');
|
|
314
|
+
if (!proceed) {
|
|
315
|
+
console.log(picocolors_1.default.yellow('Exiting...'));
|
|
316
|
+
return;
|
|
307
317
|
}
|
|
308
318
|
}
|
|
309
319
|
// If fixes were applied, re-run specialists to regenerate markdown
|
|
310
320
|
if (fixesApplied) {
|
|
311
321
|
console.log(picocolors_1.default.cyan('\nš Regenerating documentation with fixed Bible...\n'));
|
|
312
|
-
markdownSections = await orchestrator.runAllSpecialists(bible, specialists);
|
|
322
|
+
markdownSections = await orchestrator.runAllSpecialists(bible, specialists, { skipDisambiguation: true });
|
|
313
323
|
}
|
|
314
324
|
// Save all outputs
|
|
315
325
|
console.log(picocolors_1.default.cyan('\nš¾ Saving outputs...\n'));
|
|
@@ -333,7 +343,9 @@ async function runCreationFlow(options) {
|
|
|
333
343
|
console.log(picocolors_1.default.green('\nā
Complete!\n'));
|
|
334
344
|
console.log(picocolors_1.default.dim(`Session ID: ${sessionId}`));
|
|
335
345
|
console.log(picocolors_1.default.dim(`Output directory: ${projectDir}`));
|
|
336
|
-
|
|
346
|
+
// Show per-phase cost breakdown
|
|
347
|
+
costTracker.printFinalBreakdown();
|
|
348
|
+
console.log(picocolors_1.default.dim(`Total cost: $${report.total.toFixed(4)} (${report.operations} operations)`));
|
|
337
349
|
console.log(picocolors_1.default.dim(`Budget remaining: $${report.remaining.toFixed(2)}\n`));
|
|
338
350
|
if (debugLogger_1.debugLogger.isEnabled()) {
|
|
339
351
|
console.log(picocolors_1.default.yellow(`š Debug log saved to: ${debugLogger_1.debugLogger.getLogFilePath()}\n`));
|
|
@@ -441,19 +453,6 @@ async function confirmGate(message) {
|
|
|
441
453
|
});
|
|
442
454
|
return response.confirm;
|
|
443
455
|
}
|
|
444
|
-
async function selectReviewAction() {
|
|
445
|
-
const response = await enquirer_1.default.prompt({
|
|
446
|
-
type: 'select',
|
|
447
|
-
name: 'action',
|
|
448
|
-
message: 'What would you like to do?',
|
|
449
|
-
choices: [
|
|
450
|
-
{ name: 'save', message: 'Save and export GDD' },
|
|
451
|
-
{ name: 'fix', message: 'Fix issues and re-validate' },
|
|
452
|
-
{ name: 'exit', message: 'Exit without saving' }
|
|
453
|
-
]
|
|
454
|
-
});
|
|
455
|
-
return response.action;
|
|
456
|
-
}
|
|
457
456
|
async function listSessions() {
|
|
458
457
|
console.log(picocolors_1.default.cyan('\nš Saved Sessions\n'));
|
|
459
458
|
const sessionManager = new SessionManager_1.SessionManager();
|
|
@@ -678,9 +677,10 @@ async function resumeFlow(idOrCheckpoint, options = {}) {
|
|
|
678
677
|
async function continueToProduction(stateMachine, bible, apiKey, costTracker, modelSelector, fileManager, sessionId, sessionManager) {
|
|
679
678
|
// Phase 3: Production (Specialists)
|
|
680
679
|
console.log(picocolors_1.default.cyan('\nšØ Phase 3: Production\n'));
|
|
680
|
+
costTracker.startPhase('production');
|
|
681
681
|
// Note: Caller should have already transitioned to PRODUCTION phase
|
|
682
682
|
const projectId = sessionId;
|
|
683
|
-
const orchestrator = new Orchestrator_1.SpecialistOrchestrator(
|
|
683
|
+
const orchestrator = new Orchestrator_1.SpecialistOrchestrator();
|
|
684
684
|
const specialists = [
|
|
685
685
|
{ name: 'Creative Direction', agent: new CreativeSpecialist_1.CreativeSpecialist(apiKey, costTracker, modelSelector) },
|
|
686
686
|
{ name: 'Feature Specifications', agent: new FeatureSpecialist_1.FeatureSpecialist(apiKey, costTracker, modelSelector) },
|
|
@@ -688,9 +688,16 @@ async function continueToProduction(stateMachine, bible, apiKey, costTracker, mo
|
|
|
688
688
|
{ name: 'Technical Specifications', agent: new TechSpecialist_1.TechSpecialist(apiKey, costTracker, modelSelector) }
|
|
689
689
|
];
|
|
690
690
|
let markdownSections = await orchestrator.runAllSpecialists(bible, specialists);
|
|
691
|
+
// End production phase and show cost
|
|
692
|
+
const productionCost = costTracker.endPhase();
|
|
693
|
+
if (productionCost) {
|
|
694
|
+
console.log(picocolors_1.default.green('\nā Production complete'));
|
|
695
|
+
costTracker.printPhaseSummary(productionCost);
|
|
696
|
+
}
|
|
691
697
|
// Phase 4: Validation
|
|
692
698
|
console.log(picocolors_1.default.cyan('\nā
Phase 4: Validation\n'));
|
|
693
699
|
stateMachine.transition(StateMachine_1.GameForgePhase.VALIDATION);
|
|
700
|
+
costTracker.startPhase('validation');
|
|
694
701
|
const consistencyAgent = new Consistency_1.ConsistencyAgent();
|
|
695
702
|
let currentConsistencyIssues = consistencyAgent.validate(bible);
|
|
696
703
|
console.log(picocolors_1.default.yellow(`Found ${currentConsistencyIssues.length} consistency issues`));
|
|
@@ -698,106 +705,86 @@ async function continueToProduction(stateMachine, bible, apiKey, costTracker, mo
|
|
|
698
705
|
const chaosAgent = new Chaos_1.Chaos(apiKey, costTracker, modelSelector);
|
|
699
706
|
let currentChaosIssues = await chaosAgent.execute(bible);
|
|
700
707
|
chaosSpinner.succeed(`Found ${currentChaosIssues.length} design issues`);
|
|
701
|
-
//
|
|
702
|
-
const
|
|
703
|
-
|
|
708
|
+
// End validation phase and show cost
|
|
709
|
+
const validationCost = costTracker.endPhase();
|
|
710
|
+
if (validationCost) {
|
|
711
|
+
costTracker.printPhaseSummary(validationCost);
|
|
712
|
+
}
|
|
713
|
+
// Gate 3: Review Issues One by One
|
|
714
|
+
stateMachine.transition(StateMachine_1.GameForgePhase.REVIEW_ISSUES);
|
|
704
715
|
let fixesApplied = false;
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
});
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
716
|
+
const totalIssues = currentConsistencyIssues.length + currentChaosIssues.length;
|
|
717
|
+
if (totalIssues > 0) {
|
|
718
|
+
console.log(picocolors_1.default.yellow(`\nā ļø ${totalIssues} issues found. Let's review them one by one.\n`));
|
|
719
|
+
// Review each issue one by one
|
|
720
|
+
const reviewed = await (0, issueReviewer_1.reviewIssuesOneByOne)(currentConsistencyIssues, currentChaosIssues);
|
|
721
|
+
// If user selected any issues to fix
|
|
722
|
+
if (reviewed.toFix.length > 0) {
|
|
723
|
+
const proceed = await confirmGate(`Fix ${reviewed.toFix.length} selected issue(s)?`);
|
|
724
|
+
if (proceed) {
|
|
725
|
+
fixesApplied = true;
|
|
726
|
+
console.log(picocolors_1.default.cyan(`\nš§ Fixing ${reviewed.toFix.length} issues...\n`));
|
|
727
|
+
costTracker.startPhase('remediation');
|
|
728
|
+
const remediationSpinner = (0, ora_1.default)('Running Remediation Agent...').start();
|
|
729
|
+
const remediationAgent = new Remediation_1.Remediation(apiKey, costTracker, modelSelector);
|
|
730
|
+
try {
|
|
731
|
+
// Convert to IssueWithNotes format for Remediation
|
|
732
|
+
const issuesToFix = (0, issueReviewer_1.convertToIssuesWithNotes)(reviewed);
|
|
733
|
+
const result = await remediationAgent.execute(bible, issuesToFix, (message) => {
|
|
734
|
+
remediationSpinner.text = `Remediation: ${message}`;
|
|
735
|
+
});
|
|
736
|
+
remediationSpinner.succeed(`Fixed ${result.fixedIssues.length} issues`);
|
|
737
|
+
// End remediation phase and show cost
|
|
738
|
+
const remediationCost = costTracker.endPhase();
|
|
739
|
+
if (remediationCost) {
|
|
740
|
+
costTracker.printPhaseSummary(remediationCost);
|
|
741
|
+
}
|
|
742
|
+
if (result.fixedIssues.length > 0) {
|
|
743
|
+
console.log(picocolors_1.default.green('\nFixes applied:'));
|
|
744
|
+
result.fixedIssues.forEach((fix) => {
|
|
745
|
+
console.log(picocolors_1.default.dim(` ā ${fix}`));
|
|
746
|
+
});
|
|
747
|
+
}
|
|
748
|
+
if (result.unfixableIssues.length > 0) {
|
|
749
|
+
console.log(picocolors_1.default.yellow('\nCould not fix:'));
|
|
750
|
+
result.unfixableIssues.forEach((issue) => {
|
|
751
|
+
console.log(picocolors_1.default.dim(` ā ${issue}`));
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
// Update bible
|
|
755
|
+
bible = result.updatedBible;
|
|
756
|
+
stateMachine.updateBible(bible);
|
|
757
|
+
}
|
|
758
|
+
catch (error) {
|
|
759
|
+
remediationSpinner.fail('Remediation failed');
|
|
760
|
+
console.error(picocolors_1.default.red('Error during remediation:'), error);
|
|
761
|
+
const continueAnyway = await confirmGate('Continue to save despite remediation failure?');
|
|
762
|
+
if (!continueAnyway) {
|
|
763
|
+
console.log(picocolors_1.default.yellow('Exiting...'));
|
|
764
|
+
return;
|
|
765
|
+
}
|
|
766
|
+
}
|
|
721
767
|
}
|
|
722
768
|
}
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
// Determine action based on state
|
|
727
|
-
let action;
|
|
728
|
-
if (totalIssues === 0) {
|
|
729
|
-
const proceed = await confirmGate('Save and export GDD?');
|
|
730
|
-
action = proceed ? 'save' : 'exit';
|
|
731
|
-
}
|
|
732
|
-
else if (fixAttempts >= MAX_FIX_ATTEMPTS) {
|
|
733
|
-
console.log(picocolors_1.default.yellow(`\nMaximum fix attempts (${MAX_FIX_ATTEMPTS}) reached.`));
|
|
734
|
-
const proceed = await confirmGate('Save and export GDD with remaining issues?');
|
|
735
|
-
action = proceed ? 'save' : 'exit';
|
|
736
|
-
}
|
|
737
|
-
else {
|
|
738
|
-
action = await selectReviewAction();
|
|
739
|
-
}
|
|
740
|
-
if (action === 'exit') {
|
|
769
|
+
// Final confirmation to save
|
|
770
|
+
const saveConfirm = await confirmGate('Save and export GDD?');
|
|
771
|
+
if (!saveConfirm) {
|
|
741
772
|
console.log(picocolors_1.default.yellow('Exiting...'));
|
|
742
773
|
return;
|
|
743
774
|
}
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
const remediationSpinner = (0, ora_1.default)('Running Remediation Agent...').start();
|
|
752
|
-
const remediationAgent = new Remediation_1.Remediation(apiKey, costTracker, modelSelector);
|
|
753
|
-
try {
|
|
754
|
-
const result = await remediationAgent.execute(bible, currentConsistencyIssues, currentChaosIssues, (message) => { remediationSpinner.text = `Remediation: ${message}`; });
|
|
755
|
-
remediationSpinner.succeed(`Fixed ${result.fixedIssues.length} issues`);
|
|
756
|
-
if (result.fixedIssues.length > 0) {
|
|
757
|
-
console.log(picocolors_1.default.green('\nFixes applied:'));
|
|
758
|
-
result.fixedIssues.forEach(fix => {
|
|
759
|
-
console.log(picocolors_1.default.dim(` ā ${fix}`));
|
|
760
|
-
});
|
|
761
|
-
}
|
|
762
|
-
if (result.unfixableIssues.length > 0) {
|
|
763
|
-
console.log(picocolors_1.default.yellow('\nCould not fix:'));
|
|
764
|
-
result.unfixableIssues.forEach(issue => {
|
|
765
|
-
console.log(picocolors_1.default.dim(` ā ${issue}`));
|
|
766
|
-
});
|
|
767
|
-
}
|
|
768
|
-
// Update bible
|
|
769
|
-
bible = result.updatedBible;
|
|
770
|
-
stateMachine.updateBible(bible);
|
|
771
|
-
// Transition back to production for re-validation
|
|
772
|
-
stateMachine.transition(StateMachine_1.GameForgePhase.PRODUCTION);
|
|
773
|
-
// Re-run validation
|
|
774
|
-
console.log(picocolors_1.default.cyan('\nš Re-validating...\n'));
|
|
775
|
-
stateMachine.transition(StateMachine_1.GameForgePhase.VALIDATION);
|
|
776
|
-
const newConsistencyAgent = new Consistency_1.ConsistencyAgent();
|
|
777
|
-
currentConsistencyIssues = newConsistencyAgent.validate(bible);
|
|
778
|
-
console.log(picocolors_1.default.yellow(`Found ${currentConsistencyIssues.length} consistency issues`));
|
|
779
|
-
chaosSpinner = (0, ora_1.default)('Re-running Chaos Agent...').start();
|
|
780
|
-
const newChaosAgent = new Chaos_1.Chaos(apiKey, costTracker, modelSelector);
|
|
781
|
-
currentChaosIssues = await newChaosAgent.execute(bible, (message) => {
|
|
782
|
-
chaosSpinner.text = `Chaos Agent: ${message}`;
|
|
783
|
-
});
|
|
784
|
-
chaosSpinner.succeed(`Found ${currentChaosIssues.length} design issues`);
|
|
785
|
-
}
|
|
786
|
-
catch (error) {
|
|
787
|
-
remediationSpinner.fail('Remediation failed');
|
|
788
|
-
console.error(picocolors_1.default.red('Error during remediation:'), error);
|
|
789
|
-
const continueAnyway = await confirmGate('Continue to save despite remediation failure?');
|
|
790
|
-
if (!continueAnyway) {
|
|
791
|
-
console.log(picocolors_1.default.yellow('Exiting...'));
|
|
792
|
-
return;
|
|
793
|
-
}
|
|
794
|
-
break;
|
|
775
|
+
}
|
|
776
|
+
else {
|
|
777
|
+
console.log(picocolors_1.default.green('\nā No issues found!'));
|
|
778
|
+
const proceed = await confirmGate('Save and export GDD?');
|
|
779
|
+
if (!proceed) {
|
|
780
|
+
console.log(picocolors_1.default.yellow('Exiting...'));
|
|
781
|
+
return;
|
|
795
782
|
}
|
|
796
783
|
}
|
|
797
784
|
// If fixes were applied, re-run specialists to regenerate markdown
|
|
798
785
|
if (fixesApplied) {
|
|
799
786
|
console.log(picocolors_1.default.cyan('\nš Regenerating documentation with fixed Bible...\n'));
|
|
800
|
-
markdownSections = await orchestrator.runAllSpecialists(bible, specialists);
|
|
787
|
+
markdownSections = await orchestrator.runAllSpecialists(bible, specialists, { skipDisambiguation: true });
|
|
801
788
|
}
|
|
802
789
|
// Save all outputs
|
|
803
790
|
console.log(picocolors_1.default.cyan('\nš¾ Saving outputs...\n'));
|
|
@@ -818,7 +805,9 @@ async function continueToProduction(stateMachine, bible, apiKey, costTracker, mo
|
|
|
818
805
|
console.log(picocolors_1.default.green('\nā
Complete!\n'));
|
|
819
806
|
console.log(picocolors_1.default.dim(`Session ID: ${sessionId}`));
|
|
820
807
|
console.log(picocolors_1.default.dim(`Output directory: ${projectDir}`));
|
|
821
|
-
|
|
808
|
+
// Show per-phase cost breakdown
|
|
809
|
+
costTracker.printFinalBreakdown();
|
|
810
|
+
console.log(picocolors_1.default.dim(`Total cost: $${report.total.toFixed(4)} (${report.operations} operations)`));
|
|
822
811
|
console.log(picocolors_1.default.dim(`Budget remaining: $${report.remaining.toFixed(2)}\n`));
|
|
823
812
|
if (debugLogger_1.debugLogger.isEnabled()) {
|
|
824
813
|
console.log(picocolors_1.default.yellow(`š Debug log saved to: ${debugLogger_1.debugLogger.getLogFilePath()}\n`));
|
|
@@ -827,4 +816,155 @@ async function continueToProduction(stateMachine, bible, apiKey, costTracker, mo
|
|
|
827
816
|
console.log(picocolors_1.default.dim('View this session anytime with:'));
|
|
828
817
|
console.log(picocolors_1.default.dim(` gameforge session ${sessionId}\n`));
|
|
829
818
|
}
|
|
819
|
+
async function runModifyFlow(sessionId, options) {
|
|
820
|
+
console.clear();
|
|
821
|
+
console.log(picocolors_1.default.cyan('\nāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā'));
|
|
822
|
+
console.log(picocolors_1.default.cyan('ā GameForge CLI - Modify Document ā'));
|
|
823
|
+
console.log(picocolors_1.default.cyan('āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā\n'));
|
|
824
|
+
// Enable debug logging if requested
|
|
825
|
+
if (options.debug) {
|
|
826
|
+
debugLogger_1.debugLogger.enable();
|
|
827
|
+
debugLogger_1.debugLogger.log('Starting modify flow for session: ' + sessionId);
|
|
828
|
+
}
|
|
829
|
+
const apiKey = process.env.ANTHROPIC_API_KEY;
|
|
830
|
+
if (!apiKey) {
|
|
831
|
+
console.error(picocolors_1.default.red('Error: ANTHROPIC_API_KEY environment variable is not set'));
|
|
832
|
+
console.log(picocolors_1.default.dim('\nSet your API key:'));
|
|
833
|
+
console.log(picocolors_1.default.dim(' export ANTHROPIC_API_KEY=your-key-here\n'));
|
|
834
|
+
return;
|
|
835
|
+
}
|
|
836
|
+
const sessionManager = new SessionManager_1.SessionManager();
|
|
837
|
+
const fileManager = new fileManager_1.FileManager();
|
|
838
|
+
// Load latest checkpoint for this session
|
|
839
|
+
console.log(picocolors_1.default.cyan('Loading session...\n'));
|
|
840
|
+
try {
|
|
841
|
+
const latest = await sessionManager.getLatestCheckpoint(sessionId);
|
|
842
|
+
if (!latest || !latest.state.bible) {
|
|
843
|
+
console.error(picocolors_1.default.red(`No existing GDD found for session: ${sessionId}`));
|
|
844
|
+
console.log(picocolors_1.default.dim('\nList all sessions with: gameforge sessions\n'));
|
|
845
|
+
return;
|
|
846
|
+
}
|
|
847
|
+
let bible = latest.state.bible;
|
|
848
|
+
console.log(picocolors_1.default.green(`ā Loaded GDD: ${bible.meta?.title || 'Untitled'}`));
|
|
849
|
+
console.log(picocolors_1.default.dim(` Genre: ${bible.meta?.genre || 'Unknown'}`));
|
|
850
|
+
console.log(picocolors_1.default.dim(` Features: ${bible.features?.length || 0}`));
|
|
851
|
+
console.log(picocolors_1.default.dim(` Session: ${sessionId}\n`));
|
|
852
|
+
// Set up cost tracking with remaining budget from checkpoint
|
|
853
|
+
const budgetLimit = latest.state.budgetLimit || 5.0;
|
|
854
|
+
const costTracker = new costTracker_1.CostTracker(budgetLimit);
|
|
855
|
+
const modelSelector = new modelSelector_1.ModelSelector();
|
|
856
|
+
// Prompt for modification description
|
|
857
|
+
const response = await enquirer_1.default.prompt({
|
|
858
|
+
type: 'input',
|
|
859
|
+
name: 'modification',
|
|
860
|
+
message: 'Describe the changes you want to make:'
|
|
861
|
+
});
|
|
862
|
+
const modification = response.modification.trim();
|
|
863
|
+
if (!modification) {
|
|
864
|
+
console.log(picocolors_1.default.yellow('\nNo modification provided. Exiting.'));
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
// Apply modification via Modifier agent
|
|
868
|
+
console.log(picocolors_1.default.cyan('\nš§ Applying modifications...\n'));
|
|
869
|
+
costTracker.startPhase('remediation'); // Use 'remediation' as closest phase type
|
|
870
|
+
const modifier = new Modifier_1.Modifier(apiKey, costTracker, modelSelector);
|
|
871
|
+
const modifySpinner = (0, ora_1.default)('Processing modification request...').start();
|
|
872
|
+
const result = await modifier.execute(bible, modification, (message) => {
|
|
873
|
+
modifySpinner.text = `Modifier: ${message}`;
|
|
874
|
+
});
|
|
875
|
+
modifySpinner.succeed('Modifications applied');
|
|
876
|
+
// End modification phase and show cost
|
|
877
|
+
const modificationCost = costTracker.endPhase();
|
|
878
|
+
if (modificationCost) {
|
|
879
|
+
costTracker.printPhaseSummary(modificationCost);
|
|
880
|
+
}
|
|
881
|
+
// Show summary of changes
|
|
882
|
+
if (result.changesSummary.length > 0) {
|
|
883
|
+
console.log(picocolors_1.default.green('\nChanges made:'));
|
|
884
|
+
result.changesSummary.forEach((change) => {
|
|
885
|
+
console.log(picocolors_1.default.dim(` ā ${change}`));
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
if (result.errors.length > 0) {
|
|
889
|
+
console.log(picocolors_1.default.yellow('\nWarnings/Errors:'));
|
|
890
|
+
result.errors.forEach((err) => {
|
|
891
|
+
console.log(picocolors_1.default.dim(` ā ${err}`));
|
|
892
|
+
});
|
|
893
|
+
}
|
|
894
|
+
bible = result.updatedBible;
|
|
895
|
+
// Confirm and regenerate documentation
|
|
896
|
+
const proceed = await confirmGate('\nRegenerate documentation with these changes?');
|
|
897
|
+
if (!proceed) {
|
|
898
|
+
console.log(picocolors_1.default.yellow('Changes discarded.'));
|
|
899
|
+
return;
|
|
900
|
+
}
|
|
901
|
+
// Run specialists to regenerate markdown
|
|
902
|
+
console.log(picocolors_1.default.cyan('\nšØ Regenerating documentation...\n'));
|
|
903
|
+
costTracker.startPhase('production');
|
|
904
|
+
const orchestrator = new Orchestrator_1.SpecialistOrchestrator();
|
|
905
|
+
const specialists = [
|
|
906
|
+
{ name: 'Creative Direction', agent: new CreativeSpecialist_1.CreativeSpecialist(apiKey, costTracker, modelSelector) },
|
|
907
|
+
{ name: 'Feature Specifications', agent: new FeatureSpecialist_1.FeatureSpecialist(apiKey, costTracker, modelSelector) },
|
|
908
|
+
{ name: 'Entity Specifications', agent: new EntitySpecialist_1.EntitySpecialist(apiKey, costTracker, modelSelector) },
|
|
909
|
+
{ name: 'Technical Specifications', agent: new TechSpecialist_1.TechSpecialist(apiKey, costTracker, modelSelector) }
|
|
910
|
+
];
|
|
911
|
+
const markdownSections = await orchestrator.runAllSpecialists(bible, specialists, {
|
|
912
|
+
skipDisambiguation: true
|
|
913
|
+
});
|
|
914
|
+
// End specialists phase
|
|
915
|
+
const specialistsCost = costTracker.endPhase();
|
|
916
|
+
if (specialistsCost) {
|
|
917
|
+
costTracker.printPhaseSummary(specialistsCost);
|
|
918
|
+
}
|
|
919
|
+
// Run validation for gap analysis
|
|
920
|
+
console.log(picocolors_1.default.cyan('\nš Running validation...\n'));
|
|
921
|
+
costTracker.startPhase('validation');
|
|
922
|
+
const consistencyAgent = new Consistency_1.ConsistencyAgent();
|
|
923
|
+
const consistencyIssues = consistencyAgent.validate(bible);
|
|
924
|
+
const chaosSpinner = (0, ora_1.default)('Running Chaos Agent...').start();
|
|
925
|
+
const chaosAgent = new Chaos_1.Chaos(apiKey, costTracker, modelSelector);
|
|
926
|
+
const chaosIssues = await chaosAgent.execute(bible, (message) => {
|
|
927
|
+
chaosSpinner.text = `Chaos Agent: ${message}`;
|
|
928
|
+
});
|
|
929
|
+
chaosSpinner.succeed(`Found ${chaosIssues.length} design issues`);
|
|
930
|
+
const validationCost = costTracker.endPhase();
|
|
931
|
+
if (validationCost) {
|
|
932
|
+
costTracker.printPhaseSummary(validationCost);
|
|
933
|
+
}
|
|
934
|
+
// Save outputs
|
|
935
|
+
console.log(picocolors_1.default.cyan('\nš¾ Saving outputs...\n'));
|
|
936
|
+
const projectDir = await fileManager.initialize(sessionId);
|
|
937
|
+
await fileManager.saveGameBible(projectDir, bible);
|
|
938
|
+
await fileManager.saveCoverPage(projectDir, bible);
|
|
939
|
+
for (const [sectionName, content] of markdownSections) {
|
|
940
|
+
await fileManager.saveMarkdown(projectDir, sectionName, content);
|
|
941
|
+
}
|
|
942
|
+
await fileManager.saveGapAnalysis(projectDir, chaosIssues, consistencyIssues);
|
|
943
|
+
await fileManager.saveCombinedGDD(projectDir, bible, markdownSections, chaosIssues, consistencyIssues);
|
|
944
|
+
// Save checkpoint
|
|
945
|
+
const stateMachine = new StateMachine_1.StateMachine(budgetLimit);
|
|
946
|
+
stateMachine.restoreState(latest.state);
|
|
947
|
+
stateMachine.updateBible(bible);
|
|
948
|
+
await sessionManager.saveCheckpoint(sessionId, stateMachine.getState(), 'after_modification');
|
|
949
|
+
// Final output
|
|
950
|
+
const report = costTracker.getReport();
|
|
951
|
+
console.log(picocolors_1.default.green('\nā
Modification complete!\n'));
|
|
952
|
+
console.log(picocolors_1.default.dim(`Session ID: ${sessionId}`));
|
|
953
|
+
console.log(picocolors_1.default.dim(`Output directory: ${projectDir}`));
|
|
954
|
+
costTracker.printFinalBreakdown();
|
|
955
|
+
console.log(picocolors_1.default.dim(`Total cost: $${report.total.toFixed(4)} (${report.operations} operations)`));
|
|
956
|
+
console.log(picocolors_1.default.dim(`Budget remaining: $${report.remaining.toFixed(2)}\n`));
|
|
957
|
+
if (debugLogger_1.debugLogger.isEnabled()) {
|
|
958
|
+
console.log(picocolors_1.default.yellow(`š Debug log saved to: ${debugLogger_1.debugLogger.getLogFilePath()}\n`));
|
|
959
|
+
debugLogger_1.debugLogger.disable();
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
catch (error) {
|
|
963
|
+
console.error(picocolors_1.default.red('Error during modification:'), error);
|
|
964
|
+
if (debugLogger_1.debugLogger.isEnabled()) {
|
|
965
|
+
debugLogger_1.debugLogger.log('Modification flow failed: ' + String(error));
|
|
966
|
+
debugLogger_1.debugLogger.disable();
|
|
967
|
+
}
|
|
968
|
+
}
|
|
969
|
+
}
|
|
830
970
|
//# sourceMappingURL=index.js.map
|