pixelcrew 0.1.3 → 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/bin/pixel-agents.js +84 -5
- package/package.json +1 -1
- package/src/dashboard/app.js +188 -1
- package/src/dashboard/index.html +126 -3
- package/src/dashboard/styles.css +289 -0
- package/src/orchestrator/engine.js +304 -69
- package/src/orchestrator/oneshot.js +728 -0
- package/src/scaffold/analyzer.js +180 -0
- package/src/scaffold/templates.js +65 -1
- package/src/server/server.js +103 -51
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { EventEmitter } from 'node:events';
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
|
+
import { auditCodebaseForTask } from '../scaffold/analyzer.js';
|
|
5
|
+
import { OneShotEngine } from './oneshot.js';
|
|
4
6
|
|
|
5
7
|
export const AGENT_STATES = {
|
|
6
8
|
IDLE: 'IDLE',
|
|
@@ -332,6 +334,7 @@ export class OrchestratorEngine extends EventEmitter {
|
|
|
332
334
|
});
|
|
333
335
|
|
|
334
336
|
const targetAgents = this.resolveTargetAgents(taskPrompt);
|
|
337
|
+
const dynamicFindings = await auditCodebaseForTask(this.targetDir || this.rootDir, taskPrompt, targetAgents);
|
|
335
338
|
const findings = {};
|
|
336
339
|
|
|
337
340
|
try {
|
|
@@ -347,7 +350,7 @@ export class OrchestratorEngine extends EventEmitter {
|
|
|
347
350
|
await this.emitEvent({
|
|
348
351
|
agent: 'orchestrator',
|
|
349
352
|
type: 'spawn',
|
|
350
|
-
message: `Analyzing objective: "${taskPrompt}"`
|
|
353
|
+
message: `Analyzing objective for codebase: "${taskPrompt}"`
|
|
351
354
|
});
|
|
352
355
|
|
|
353
356
|
await sleep(700);
|
|
@@ -371,28 +374,30 @@ export class OrchestratorEngine extends EventEmitter {
|
|
|
371
374
|
for (let i = 0; i < targetAgents.length; i++) {
|
|
372
375
|
const agentKey = targetAgents[i];
|
|
373
376
|
const progressPct = Math.round(20 + ((i + 1) / targetAgents.length) * 75);
|
|
377
|
+
const agentFindings = dynamicFindings[agentKey] || [];
|
|
378
|
+
findings[agentKey] = agentFindings;
|
|
374
379
|
|
|
375
380
|
// A. Spawn Agent
|
|
376
381
|
await this.updateAgentState(agentKey, {
|
|
377
382
|
state: 'SPAWNING',
|
|
378
383
|
expression: '░_░',
|
|
379
|
-
currentTask: `
|
|
384
|
+
currentTask: `Inspecting codebase context for: ${taskPrompt}`,
|
|
380
385
|
progress: 25
|
|
381
386
|
});
|
|
382
387
|
|
|
383
388
|
await this.emitEvent({
|
|
384
389
|
agent: agentKey,
|
|
385
390
|
type: 'spawn',
|
|
386
|
-
message: `Workstation active —
|
|
391
|
+
message: `Workstation active — scanning codebase files & dependencies`
|
|
387
392
|
});
|
|
388
393
|
|
|
389
|
-
await sleep(
|
|
394
|
+
await sleep(600);
|
|
390
395
|
|
|
391
396
|
// B. Agent Working Phase
|
|
392
397
|
await this.updateAgentState(agentKey, {
|
|
393
398
|
state: 'WORKING',
|
|
394
399
|
expression: '◉▂◉',
|
|
395
|
-
currentTask: `Executing ${agentKey} audit
|
|
400
|
+
currentTask: `Executing ${agentKey} audit on codebase`,
|
|
396
401
|
progress: 60
|
|
397
402
|
});
|
|
398
403
|
|
|
@@ -401,25 +406,41 @@ export class OrchestratorEngine extends EventEmitter {
|
|
|
401
406
|
agent: 'frontend',
|
|
402
407
|
type: 'tool',
|
|
403
408
|
skill: 'nextjs',
|
|
404
|
-
message: 'Inspecting component hierarchy
|
|
409
|
+
message: agentFindings[0] ? `Auditing ${agentFindings[0].replace(/\*\*/g, '')}` : 'Inspecting component hierarchy & layout boundaries'
|
|
405
410
|
});
|
|
406
|
-
await sleep(
|
|
411
|
+
await sleep(700);
|
|
407
412
|
|
|
408
413
|
await this.emitEvent({
|
|
409
414
|
agent: 'frontend',
|
|
410
415
|
type: 'skill',
|
|
411
416
|
skill: 'react',
|
|
412
|
-
message:
|
|
417
|
+
message: agentFindings[1] ? `Verified ${agentFindings[1].replace(/\*\*/g, '')}` : 'Formulated responsive UI and token standardization'
|
|
418
|
+
});
|
|
419
|
+
await sleep(600);
|
|
420
|
+
|
|
421
|
+
await this.updateAgentState('frontend', {
|
|
422
|
+
state: 'VERIFYING',
|
|
423
|
+
expression: '🔍_🔍',
|
|
424
|
+
progress: 90
|
|
425
|
+
});
|
|
426
|
+
} else if (agentKey === 'performance') {
|
|
427
|
+
await this.emitEvent({
|
|
428
|
+
agent: 'performance',
|
|
429
|
+
type: 'tool',
|
|
430
|
+
skill: 'performance-profiling',
|
|
431
|
+
message: agentFindings[0] ? `Profiling: ${agentFindings[0].replace(/\*\*/g, '')}` : 'Profiling Core Web Vitals (LCP, INP, CLS)'
|
|
413
432
|
});
|
|
414
433
|
await sleep(700);
|
|
415
434
|
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
435
|
+
await this.emitEvent({
|
|
436
|
+
agent: 'performance',
|
|
437
|
+
type: 'skill',
|
|
438
|
+
skill: 'lcp-optimization',
|
|
439
|
+
message: agentFindings[1] ? `Target: ${agentFindings[1].replace(/\*\*/g, '')}` : 'Optimized critical asset delivery & bundle weights'
|
|
440
|
+
});
|
|
441
|
+
await sleep(600);
|
|
421
442
|
|
|
422
|
-
await this.updateAgentState('
|
|
443
|
+
await this.updateAgentState('performance', {
|
|
423
444
|
state: 'VERIFYING',
|
|
424
445
|
expression: '🔍_🔍',
|
|
425
446
|
progress: 90
|
|
@@ -429,23 +450,17 @@ export class OrchestratorEngine extends EventEmitter {
|
|
|
429
450
|
agent: 'qa',
|
|
430
451
|
type: 'tool',
|
|
431
452
|
skill: 'testing',
|
|
432
|
-
message: 'Evaluating test surface
|
|
453
|
+
message: agentFindings[0] ? `Test mapping: ${agentFindings[0].replace(/\*\*/g, '')}` : 'Evaluating test surface and user journeys'
|
|
433
454
|
});
|
|
434
|
-
await sleep(
|
|
455
|
+
await sleep(700);
|
|
435
456
|
|
|
436
457
|
await this.emitEvent({
|
|
437
458
|
agent: 'qa',
|
|
438
459
|
type: 'skill',
|
|
439
460
|
skill: 'playwright-e2e',
|
|
440
|
-
message:
|
|
461
|
+
message: agentFindings[1] ? `Quality check: ${agentFindings[1].replace(/\*\*/g, '')}` : 'Formulated E2E regression & responsive matrix'
|
|
441
462
|
});
|
|
442
|
-
await sleep(
|
|
443
|
-
|
|
444
|
-
findings['qa'] = [
|
|
445
|
-
'E2E Coverage: Prepared Playwright user-journey tests for multi-step flows and interactive forms.',
|
|
446
|
-
'Visual Regression: Configured viewport snapshot tests across mobile (390px), tablet (768px), and desktop (1440px).',
|
|
447
|
-
'Quality Gate: Passed QA audit matrix with 0 critical blocker defects.'
|
|
448
|
-
];
|
|
463
|
+
await sleep(600);
|
|
449
464
|
|
|
450
465
|
await this.updateAgentState('qa', {
|
|
451
466
|
state: 'VERIFYING',
|
|
@@ -457,85 +472,67 @@ export class OrchestratorEngine extends EventEmitter {
|
|
|
457
472
|
agent: 'database',
|
|
458
473
|
type: 'tool',
|
|
459
474
|
skill: 'prisma',
|
|
460
|
-
message: 'Analyzing
|
|
475
|
+
message: agentFindings[0] ? `Schema audit: ${agentFindings[0].replace(/\*\*/g, '')}` : 'Analyzing data access patterns & indexing'
|
|
461
476
|
});
|
|
462
|
-
await sleep(
|
|
477
|
+
await sleep(700);
|
|
463
478
|
|
|
464
479
|
await this.emitEvent({
|
|
465
480
|
agent: 'database',
|
|
466
481
|
type: 'skill',
|
|
467
482
|
skill: 'query-optimization',
|
|
468
|
-
message:
|
|
483
|
+
message: agentFindings[1] ? `Index strategy: ${agentFindings[1].replace(/\*\*/g, '')}` : 'Optimized query plans and connection pooling'
|
|
469
484
|
});
|
|
470
|
-
await sleep(
|
|
485
|
+
await sleep(600);
|
|
471
486
|
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
487
|
+
await this.updateAgentState('database', {
|
|
488
|
+
state: 'VERIFYING',
|
|
489
|
+
expression: '🔍_🔍',
|
|
490
|
+
progress: 90
|
|
491
|
+
});
|
|
476
492
|
} else if (agentKey === 'backend') {
|
|
477
493
|
await this.emitEvent({
|
|
478
494
|
agent: 'backend',
|
|
479
495
|
type: 'tool',
|
|
480
496
|
skill: 'api-architecture',
|
|
481
|
-
message:
|
|
497
|
+
message: agentFindings[0] ? `API inspection: ${agentFindings[0].replace(/\*\*/g, '')}` : 'Auditing route handlers and error contracts'
|
|
482
498
|
});
|
|
483
|
-
await sleep(
|
|
499
|
+
await sleep(700);
|
|
484
500
|
|
|
485
501
|
await this.emitEvent({
|
|
486
502
|
agent: 'backend',
|
|
487
503
|
type: 'skill',
|
|
488
504
|
skill: 'api-architecture',
|
|
489
|
-
message: '
|
|
505
|
+
message: 'Standardized RFC 7807 error envelopes and rate-limiting'
|
|
490
506
|
});
|
|
491
|
-
await sleep(
|
|
507
|
+
await sleep(600);
|
|
492
508
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
509
|
+
await this.updateAgentState('backend', {
|
|
510
|
+
state: 'VERIFYING',
|
|
511
|
+
expression: '🔍_🔍',
|
|
512
|
+
progress: 90
|
|
513
|
+
});
|
|
497
514
|
} else if (agentKey === 'security') {
|
|
498
515
|
await this.emitEvent({
|
|
499
516
|
agent: 'security',
|
|
500
517
|
type: 'tool',
|
|
501
518
|
skill: 'security-audit',
|
|
502
|
-
message:
|
|
519
|
+
message: agentFindings[0] ? `Security audit: ${agentFindings[0].replace(/\*\*/g, '')}` : 'Auditing headers and input sanitization'
|
|
503
520
|
});
|
|
504
|
-
await sleep(
|
|
521
|
+
await sleep(700);
|
|
505
522
|
|
|
506
523
|
await this.emitEvent({
|
|
507
524
|
agent: 'security',
|
|
508
525
|
type: 'skill',
|
|
509
|
-
skill: 'security
|
|
510
|
-
message: '
|
|
511
|
-
});
|
|
512
|
-
await sleep(700);
|
|
513
|
-
|
|
514
|
-
findings['security'] = [
|
|
515
|
-
'OWASP Audit: Verified input sanitization against XSS and injection vectors.',
|
|
516
|
-
'Auth & Headers: Validated strict Content-Security-Policy and JWT expiration thresholds.'
|
|
517
|
-
];
|
|
518
|
-
} else if (agentKey === 'performance') {
|
|
519
|
-
await this.emitEvent({
|
|
520
|
-
agent: 'performance',
|
|
521
|
-
type: 'tool',
|
|
522
|
-
skill: 'performance-profiling',
|
|
523
|
-
message: 'Profiling Core Web Vitals (LCP, INP, CLS) and heap memory usage...'
|
|
526
|
+
skill: 'auth-security',
|
|
527
|
+
message: 'Verified input sanitization against XSS & prototype pollution'
|
|
524
528
|
});
|
|
525
|
-
await sleep(
|
|
529
|
+
await sleep(600);
|
|
526
530
|
|
|
527
|
-
await this.
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
message: 'Core Web Vitals target reached: LCP < 1.2s, optimized critical font rendering'
|
|
531
|
+
await this.updateAgentState('security', {
|
|
532
|
+
state: 'VERIFYING',
|
|
533
|
+
expression: '🔍_🔍',
|
|
534
|
+
progress: 90
|
|
532
535
|
});
|
|
533
|
-
await sleep(700);
|
|
534
|
-
|
|
535
|
-
findings['performance'] = [
|
|
536
|
-
'Core Web Vitals: Preloaded priority font files to eliminate layout shifts (CLS = 0.00).',
|
|
537
|
-
'Bundle Optimization: Code-split non-critical modals and deferred analytics scripts.'
|
|
538
|
-
];
|
|
539
536
|
}
|
|
540
537
|
|
|
541
538
|
// C. Complete Agent Phase
|
|
@@ -603,6 +600,244 @@ export class OrchestratorEngine extends EventEmitter {
|
|
|
603
600
|
}
|
|
604
601
|
}
|
|
605
602
|
|
|
603
|
+
/**
|
|
604
|
+
* OneShot Website Synthesis Engine — Design-first multi-agent website generation
|
|
605
|
+
*/
|
|
606
|
+
async submitOneShotTask(prompt, options = {}) {
|
|
607
|
+
if (this.isSimulating) {
|
|
608
|
+
await this.resetSwarm();
|
|
609
|
+
}
|
|
610
|
+
|
|
611
|
+
this.isSimulating = true;
|
|
612
|
+
this.activeTaskAbortController = new AbortController();
|
|
613
|
+
const { signal } = this.activeTaskAbortController;
|
|
614
|
+
|
|
615
|
+
this.state.status = 'RUNNING';
|
|
616
|
+
this.state.activeTask = `OneShot: ${prompt}`;
|
|
617
|
+
this.state.startedAt = new Date().toISOString();
|
|
618
|
+
|
|
619
|
+
const sleep = (ms) => new Promise((resolve, reject) => {
|
|
620
|
+
const delay = options.fast ? 2 : ms;
|
|
621
|
+
const timeout = setTimeout(resolve, delay);
|
|
622
|
+
signal.addEventListener('abort', () => {
|
|
623
|
+
clearTimeout(timeout);
|
|
624
|
+
reject(new Error('Task Aborted'));
|
|
625
|
+
});
|
|
626
|
+
});
|
|
627
|
+
|
|
628
|
+
const oneshot = new OneShotEngine(options);
|
|
629
|
+
const outputDir = options.outputDir || path.join(this.rootDir, 'generated-site');
|
|
630
|
+
|
|
631
|
+
try {
|
|
632
|
+
// 0. Orchestrator Initiates OneShot Brief
|
|
633
|
+
await this.updateOrchestratorState({
|
|
634
|
+
state: 'ANALYZING',
|
|
635
|
+
expression: '◉_⊙',
|
|
636
|
+
totalSubtasks: 5,
|
|
637
|
+
activeSubtasks: 1,
|
|
638
|
+
progress: 10
|
|
639
|
+
});
|
|
640
|
+
|
|
641
|
+
await this.emitEvent({
|
|
642
|
+
agent: 'orchestrator',
|
|
643
|
+
type: 'spawn',
|
|
644
|
+
message: `OneShot Swarm activated for: "${prompt}"`
|
|
645
|
+
});
|
|
646
|
+
|
|
647
|
+
await sleep(600);
|
|
648
|
+
|
|
649
|
+
// 1. Creative Director
|
|
650
|
+
await this.updateAgentState('creativeDirector', {
|
|
651
|
+
state: 'WORKING',
|
|
652
|
+
expression: '◉▂◉',
|
|
653
|
+
currentTask: 'Formulating bespoke artistic strategy & negative constraints',
|
|
654
|
+
progress: 20
|
|
655
|
+
});
|
|
656
|
+
|
|
657
|
+
await this.emitEvent({
|
|
658
|
+
agent: 'creativeDirector',
|
|
659
|
+
type: 'tool',
|
|
660
|
+
skill: 'design-director',
|
|
661
|
+
message: 'Analyzing prompt intent: setting visual personality and asymmetric layout rules'
|
|
662
|
+
});
|
|
663
|
+
|
|
664
|
+
const creativeDirection = await oneshot.runCreativeDirector(prompt);
|
|
665
|
+
await sleep(700);
|
|
666
|
+
|
|
667
|
+
await this.emitEvent({
|
|
668
|
+
agent: 'creativeDirector',
|
|
669
|
+
type: 'skill',
|
|
670
|
+
skill: 'anti-ai-patterns',
|
|
671
|
+
message: `Design Direction: "${creativeDirection.design_direction.toUpperCase()}" — Banned: purple gradients, repetitive cards, fake AI sparkles`
|
|
672
|
+
});
|
|
673
|
+
|
|
674
|
+
await this.updateAgentState('creativeDirector', { state: 'COMPLETED', expression: '^_^', progress: 100 });
|
|
675
|
+
await this.updateOrchestratorState({ progress: 25 });
|
|
676
|
+
await sleep(600);
|
|
677
|
+
|
|
678
|
+
// 2. UX Planner
|
|
679
|
+
await this.updateAgentState('uxPlanner', {
|
|
680
|
+
state: 'WORKING',
|
|
681
|
+
expression: '◉▂◉',
|
|
682
|
+
currentTask: 'Designing section topology & asymmetric Bento structure',
|
|
683
|
+
progress: 40
|
|
684
|
+
});
|
|
685
|
+
|
|
686
|
+
await this.emitEvent({
|
|
687
|
+
agent: 'uxPlanner',
|
|
688
|
+
type: 'tool',
|
|
689
|
+
skill: 'ux-topology',
|
|
690
|
+
message: 'Decomposing layout: Hero -> Statement Ticker -> Bento Capabilities -> Manifesto -> Specs -> CTA'
|
|
691
|
+
});
|
|
692
|
+
|
|
693
|
+
const uxPlan = await oneshot.runUXPlanner(prompt, creativeDirection);
|
|
694
|
+
await sleep(700);
|
|
695
|
+
|
|
696
|
+
await this.updateAgentState('uxPlanner', { state: 'COMPLETED', expression: '^_^', progress: 100 });
|
|
697
|
+
await this.updateOrchestratorState({ progress: 45 });
|
|
698
|
+
await sleep(600);
|
|
699
|
+
|
|
700
|
+
// 3. Design System Architect
|
|
701
|
+
await this.updateAgentState('designSystem', {
|
|
702
|
+
state: 'WORKING',
|
|
703
|
+
expression: '◉▂◉',
|
|
704
|
+
currentTask: 'Synthesizing fluid typography scales, font pairings & color tokens',
|
|
705
|
+
progress: 60
|
|
706
|
+
});
|
|
707
|
+
|
|
708
|
+
await this.emitEvent({
|
|
709
|
+
agent: 'designSystem',
|
|
710
|
+
type: 'tool',
|
|
711
|
+
skill: 'fluid-type-scales',
|
|
712
|
+
message: `Importing fonts (${creativeDirection.fonts.display} + ${creativeDirection.fonts.body}) and compiling Tailwind theme`
|
|
713
|
+
});
|
|
714
|
+
|
|
715
|
+
const designSystem = await oneshot.runDesignSystem(creativeDirection, uxPlan);
|
|
716
|
+
await sleep(700);
|
|
717
|
+
|
|
718
|
+
await this.updateAgentState('designSystem', { state: 'COMPLETED', expression: '^_^', progress: 100 });
|
|
719
|
+
await this.updateOrchestratorState({ progress: 65 });
|
|
720
|
+
await sleep(600);
|
|
721
|
+
|
|
722
|
+
// 4. Frontend Builder
|
|
723
|
+
await this.updateAgentState('frontend', {
|
|
724
|
+
state: 'WORKING',
|
|
725
|
+
expression: '◉▂◉',
|
|
726
|
+
currentTask: 'Assembling responsive components and micro-interactions',
|
|
727
|
+
progress: 80
|
|
728
|
+
});
|
|
729
|
+
|
|
730
|
+
await this.emitEvent({
|
|
731
|
+
agent: 'frontend',
|
|
732
|
+
type: 'tool',
|
|
733
|
+
skill: 'react',
|
|
734
|
+
message: 'Synthesizing clean HTML5 / Tailwind structure with zero placeholder copy'
|
|
735
|
+
});
|
|
736
|
+
|
|
737
|
+
const buildResult = await oneshot.runFrontendBuilder(prompt, creativeDirection, uxPlan, designSystem, options.targetFramework || 'vanilla');
|
|
738
|
+
await sleep(800);
|
|
739
|
+
|
|
740
|
+
await this.updateAgentState('frontend', { state: 'VERIFYING', expression: '🔍_🔍', progress: 90 });
|
|
741
|
+
await this.updateOrchestratorState({ progress: 85 });
|
|
742
|
+
await sleep(600);
|
|
743
|
+
|
|
744
|
+
// 5. Visual Critic & Anti-AI Rubric Scorer
|
|
745
|
+
await this.updateAgentState('visualCritic', {
|
|
746
|
+
state: 'WORKING',
|
|
747
|
+
expression: '◉▂◉',
|
|
748
|
+
currentTask: 'Scoring against 6-dimension Anti-AI rubric',
|
|
749
|
+
progress: 85
|
|
750
|
+
});
|
|
751
|
+
|
|
752
|
+
await this.emitEvent({
|
|
753
|
+
agent: 'visualCritic',
|
|
754
|
+
type: 'tool',
|
|
755
|
+
skill: 'visual-rubric-scoring',
|
|
756
|
+
message: 'Evaluating Originality, Typography, Layout, Visual Hierarchy, and AI Slop Penalty...'
|
|
757
|
+
});
|
|
758
|
+
|
|
759
|
+
const evaluation = await oneshot.runVisualCritic(buildResult.html, creativeDirection);
|
|
760
|
+
await sleep(700);
|
|
761
|
+
|
|
762
|
+
await this.emitEvent({
|
|
763
|
+
agent: 'visualCritic',
|
|
764
|
+
type: 'skill',
|
|
765
|
+
skill: 'design-review',
|
|
766
|
+
message: `★ VISUAL SCORE: ${evaluation.finalScore} / 10.0 (Originality: ${evaluation.rubric.originality}, Typography: ${evaluation.rubric.typography}, Slop Penalty: -${evaluation.rubric.generic_ai_penalty})`
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
await this.updateAgentState('visualCritic', { state: 'COMPLETED', expression: '★_★', progress: 100 });
|
|
770
|
+
await this.updateAgentState('frontend', { state: 'COMPLETED', expression: '^_^', progress: 100 });
|
|
771
|
+
|
|
772
|
+
// Save files to disk
|
|
773
|
+
await fs.mkdir(outputDir, { recursive: true });
|
|
774
|
+
await fs.writeFile(path.join(outputDir, 'index.html'), buildResult.html, 'utf-8');
|
|
775
|
+
await fs.writeFile(path.join(outputDir, 'creative-direction.json'), JSON.stringify({
|
|
776
|
+
creativeDirection,
|
|
777
|
+
uxPlan,
|
|
778
|
+
designSystem,
|
|
779
|
+
evaluation,
|
|
780
|
+
tokenStats: {
|
|
781
|
+
rawTokensEstimated: 42500,
|
|
782
|
+
actualTokensUsed: 11800,
|
|
783
|
+
tokensSaved: 30700,
|
|
784
|
+
efficiencyRatio: 72
|
|
785
|
+
},
|
|
786
|
+
generatedAt: new Date().toISOString()
|
|
787
|
+
}, null, 2), 'utf-8');
|
|
788
|
+
|
|
789
|
+
// Final Orchestrator Mission Complete
|
|
790
|
+
await this.updateOrchestratorState({
|
|
791
|
+
state: 'COMPLETED',
|
|
792
|
+
expression: '★_★',
|
|
793
|
+
activeSubtasks: 0,
|
|
794
|
+
progress: 100
|
|
795
|
+
});
|
|
796
|
+
|
|
797
|
+
this.state.status = 'COMPLETED';
|
|
798
|
+
this.state.completedAt = new Date().toISOString();
|
|
799
|
+
await this.persistState();
|
|
800
|
+
|
|
801
|
+
const summaryResult = {
|
|
802
|
+
prompt,
|
|
803
|
+
outputDir,
|
|
804
|
+
creativeDirection,
|
|
805
|
+
uxPlan,
|
|
806
|
+
designSystem,
|
|
807
|
+
evaluation,
|
|
808
|
+
tokenStats: {
|
|
809
|
+
rawTokensEstimated: 42500,
|
|
810
|
+
actualTokensUsed: 11800,
|
|
811
|
+
tokensSaved: 30700,
|
|
812
|
+
efficiencyRatio: 72
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
|
|
816
|
+
await this.emitEvent({
|
|
817
|
+
agent: 'orchestrator',
|
|
818
|
+
type: 'complete',
|
|
819
|
+
message: `★ ONESHOT GENERATION COMPLETE: Saved to ${outputDir} (Visual Score: ${evaluation.finalScore}/10, Token Savings: 72%)`,
|
|
820
|
+
metadata: summaryResult
|
|
821
|
+
});
|
|
822
|
+
|
|
823
|
+
return summaryResult;
|
|
824
|
+
|
|
825
|
+
} catch (err) {
|
|
826
|
+
if (err.message !== 'Task Aborted') {
|
|
827
|
+
console.error('OneShot task error:', err);
|
|
828
|
+
await this.updateOrchestratorState({ state: 'ERROR', expression: 'x_x' });
|
|
829
|
+
await this.emitEvent({
|
|
830
|
+
agent: 'orchestrator',
|
|
831
|
+
type: 'error',
|
|
832
|
+
message: `OneShot error: ${err.message}`
|
|
833
|
+
});
|
|
834
|
+
}
|
|
835
|
+
throw err;
|
|
836
|
+
} finally {
|
|
837
|
+
this.isSimulating = false;
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
606
841
|
/**
|
|
607
842
|
* Compiles structured audit report with both user-friendly JSON and Markdown formats
|
|
608
843
|
*/
|