pixelcrew 0.1.4 → 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 +239 -0
- package/src/orchestrator/oneshot.js +728 -0
- package/src/scaffold/templates.js +65 -1
- package/src/server/server.js +103 -51
package/src/dashboard/styles.css
CHANGED
|
@@ -973,6 +973,7 @@ body:not(.crt-active) .crt-vignette {
|
|
|
973
973
|
line-height: 1.4;
|
|
974
974
|
display: -webkit-box;
|
|
975
975
|
-webkit-line-clamp: 2;
|
|
976
|
+
line-clamp: 2;
|
|
976
977
|
-webkit-box-orient: vertical;
|
|
977
978
|
overflow: hidden;
|
|
978
979
|
}
|
|
@@ -1343,3 +1344,291 @@ body:not(.crt-active) .crt-vignette {
|
|
|
1343
1344
|
.reports-modal-body { flex-direction: column; }
|
|
1344
1345
|
.reports-sidebar { width: 100%; height: 200px; }
|
|
1345
1346
|
}
|
|
1347
|
+
|
|
1348
|
+
/* ==========================================================================
|
|
1349
|
+
PIXEL CREW ONESHOT STUDIO & VISUAL SCORECARD STYLES
|
|
1350
|
+
========================================================================== */
|
|
1351
|
+
|
|
1352
|
+
.oneshot-modal-card {
|
|
1353
|
+
max-width: 1080px;
|
|
1354
|
+
width: 95%;
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
.oneshot-modal-body {
|
|
1358
|
+
padding: 16px;
|
|
1359
|
+
max-height: 80vh;
|
|
1360
|
+
overflow-y: auto;
|
|
1361
|
+
display: flex;
|
|
1362
|
+
flex-direction: column;
|
|
1363
|
+
gap: 16px;
|
|
1364
|
+
}
|
|
1365
|
+
|
|
1366
|
+
.oneshot-top-grid {
|
|
1367
|
+
display: grid;
|
|
1368
|
+
grid-template-columns: 1fr 340px;
|
|
1369
|
+
gap: 16px;
|
|
1370
|
+
}
|
|
1371
|
+
|
|
1372
|
+
.oneshot-prompt-box {
|
|
1373
|
+
background: #0d101d;
|
|
1374
|
+
border: 2px solid var(--border-color);
|
|
1375
|
+
padding: 14px;
|
|
1376
|
+
display: flex;
|
|
1377
|
+
flex-direction: column;
|
|
1378
|
+
gap: 10px;
|
|
1379
|
+
}
|
|
1380
|
+
|
|
1381
|
+
.oneshot-label {
|
|
1382
|
+
font-family: var(--font-pixel);
|
|
1383
|
+
font-size: 8px;
|
|
1384
|
+
color: var(--color-cyan);
|
|
1385
|
+
}
|
|
1386
|
+
|
|
1387
|
+
.oneshot-textarea {
|
|
1388
|
+
width: 100%;
|
|
1389
|
+
resize: vertical;
|
|
1390
|
+
min-height: 70px;
|
|
1391
|
+
font-family: var(--font-terminal);
|
|
1392
|
+
font-size: 16px;
|
|
1393
|
+
line-height: 1.4;
|
|
1394
|
+
}
|
|
1395
|
+
|
|
1396
|
+
.oneshot-controls {
|
|
1397
|
+
display: flex;
|
|
1398
|
+
align-items: center;
|
|
1399
|
+
justify-content: space-between;
|
|
1400
|
+
gap: 12px;
|
|
1401
|
+
}
|
|
1402
|
+
|
|
1403
|
+
.oneshot-framework-selector {
|
|
1404
|
+
display: flex;
|
|
1405
|
+
align-items: center;
|
|
1406
|
+
gap: 10px;
|
|
1407
|
+
font-family: var(--font-pixel);
|
|
1408
|
+
font-size: 8px;
|
|
1409
|
+
color: var(--text-dim);
|
|
1410
|
+
}
|
|
1411
|
+
|
|
1412
|
+
.radio-label {
|
|
1413
|
+
display: flex;
|
|
1414
|
+
align-items: center;
|
|
1415
|
+
gap: 4px;
|
|
1416
|
+
cursor: pointer;
|
|
1417
|
+
color: var(--text-main);
|
|
1418
|
+
}
|
|
1419
|
+
|
|
1420
|
+
/* Cross-IDE Token Saver Card */
|
|
1421
|
+
.oneshot-token-card {
|
|
1422
|
+
background: #081418;
|
|
1423
|
+
border: 2px solid #00f0ff44;
|
|
1424
|
+
padding: 14px;
|
|
1425
|
+
display: flex;
|
|
1426
|
+
flex-direction: column;
|
|
1427
|
+
justify-content: space-between;
|
|
1428
|
+
gap: 10px;
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
.token-card-header {
|
|
1432
|
+
display: flex;
|
|
1433
|
+
align-items: center;
|
|
1434
|
+
gap: 6px;
|
|
1435
|
+
}
|
|
1436
|
+
|
|
1437
|
+
.token-icon { font-size: 14px; }
|
|
1438
|
+
.token-title { font-family: var(--font-pixel); font-size: 9px; color: var(--color-cyan); }
|
|
1439
|
+
|
|
1440
|
+
.token-stats-grid {
|
|
1441
|
+
display: flex;
|
|
1442
|
+
flex-direction: column;
|
|
1443
|
+
gap: 4px;
|
|
1444
|
+
}
|
|
1445
|
+
|
|
1446
|
+
.token-stat-item {
|
|
1447
|
+
display: flex;
|
|
1448
|
+
justify-content: space-between;
|
|
1449
|
+
font-family: var(--font-pixel);
|
|
1450
|
+
font-size: 8px;
|
|
1451
|
+
}
|
|
1452
|
+
|
|
1453
|
+
.token-stat-label { color: var(--text-dim); }
|
|
1454
|
+
.token-stat-val { color: var(--text-main); }
|
|
1455
|
+
.token-stat-val.text-green { color: var(--color-green); font-weight: bold; }
|
|
1456
|
+
.token-stat-item.highlight {
|
|
1457
|
+
border-top: 1px solid #165b38;
|
|
1458
|
+
padding-top: 4px;
|
|
1459
|
+
margin-top: 2px;
|
|
1460
|
+
}
|
|
1461
|
+
|
|
1462
|
+
.token-strategies {
|
|
1463
|
+
display: flex;
|
|
1464
|
+
flex-wrap: wrap;
|
|
1465
|
+
gap: 4px;
|
|
1466
|
+
}
|
|
1467
|
+
|
|
1468
|
+
.strat-pill {
|
|
1469
|
+
font-family: var(--font-pixel);
|
|
1470
|
+
font-size: 7px;
|
|
1471
|
+
background: #00f0ff15;
|
|
1472
|
+
color: #00f0ff;
|
|
1473
|
+
padding: 2px 6px;
|
|
1474
|
+
border: 1px solid #00f0ff33;
|
|
1475
|
+
}
|
|
1476
|
+
|
|
1477
|
+
/* Pipeline Progress Section */
|
|
1478
|
+
.oneshot-pipeline-section {
|
|
1479
|
+
background: #0b0e1b;
|
|
1480
|
+
border: 2px solid var(--border-color);
|
|
1481
|
+
padding: 12px 14px;
|
|
1482
|
+
}
|
|
1483
|
+
|
|
1484
|
+
.pipeline-header {
|
|
1485
|
+
display: flex;
|
|
1486
|
+
justify-content: space-between;
|
|
1487
|
+
align-items: center;
|
|
1488
|
+
margin-bottom: 12px;
|
|
1489
|
+
}
|
|
1490
|
+
|
|
1491
|
+
.pipeline-title {
|
|
1492
|
+
font-family: var(--font-pixel);
|
|
1493
|
+
font-size: 9px;
|
|
1494
|
+
color: var(--color-gold);
|
|
1495
|
+
}
|
|
1496
|
+
|
|
1497
|
+
.pipeline-status {
|
|
1498
|
+
font-family: var(--font-pixel);
|
|
1499
|
+
font-size: 8px;
|
|
1500
|
+
color: var(--color-cyan);
|
|
1501
|
+
}
|
|
1502
|
+
|
|
1503
|
+
.pipeline-steps {
|
|
1504
|
+
display: flex;
|
|
1505
|
+
align-items: center;
|
|
1506
|
+
justify-content: space-between;
|
|
1507
|
+
gap: 6px;
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
.pipeline-step {
|
|
1511
|
+
flex: 1;
|
|
1512
|
+
background: #111526;
|
|
1513
|
+
border: 1px solid var(--border-color);
|
|
1514
|
+
padding: 8px 6px;
|
|
1515
|
+
text-align: center;
|
|
1516
|
+
transition: all 0.3s ease;
|
|
1517
|
+
}
|
|
1518
|
+
|
|
1519
|
+
.pipeline-step.active {
|
|
1520
|
+
border-color: var(--color-gold);
|
|
1521
|
+
background: #1a1e36;
|
|
1522
|
+
box-shadow: 0 0 10px rgba(255, 215, 0, 0.2);
|
|
1523
|
+
}
|
|
1524
|
+
|
|
1525
|
+
.pipeline-step.completed {
|
|
1526
|
+
border-color: var(--color-green);
|
|
1527
|
+
background: #0d1e16;
|
|
1528
|
+
}
|
|
1529
|
+
|
|
1530
|
+
.step-icon { font-size: 16px; margin-bottom: 4px; }
|
|
1531
|
+
.step-label { font-family: var(--font-pixel); font-size: 7px; color: var(--text-main); margin-bottom: 2px; }
|
|
1532
|
+
.step-desc { font-family: var(--font-terminal); font-size: 11px; color: var(--text-dim); }
|
|
1533
|
+
|
|
1534
|
+
.pipeline-arrow {
|
|
1535
|
+
color: var(--text-dim);
|
|
1536
|
+
font-family: var(--font-pixel);
|
|
1537
|
+
font-size: 10px;
|
|
1538
|
+
}
|
|
1539
|
+
|
|
1540
|
+
/* Results & Scorecard */
|
|
1541
|
+
.oneshot-results-grid {
|
|
1542
|
+
display: grid;
|
|
1543
|
+
grid-template-columns: 360px 1fr;
|
|
1544
|
+
gap: 16px;
|
|
1545
|
+
}
|
|
1546
|
+
|
|
1547
|
+
.visual-scorecard-panel {
|
|
1548
|
+
background: #080a14;
|
|
1549
|
+
border: 2px solid var(--color-magenta);
|
|
1550
|
+
padding: 14px;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
.scorecard-header {
|
|
1554
|
+
display: flex;
|
|
1555
|
+
justify-content: space-between;
|
|
1556
|
+
align-items: center;
|
|
1557
|
+
margin-bottom: 14px;
|
|
1558
|
+
border-bottom: 1px solid #ff007f33;
|
|
1559
|
+
padding-bottom: 8px;
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
.score-title { font-family: var(--font-pixel); font-size: 9px; color: var(--color-magenta); }
|
|
1563
|
+
.score-badge { font-family: var(--font-pixel); font-size: 11px; color: var(--color-green); background: #0c1a14; padding: 3px 8px; border: 1px solid var(--color-green); }
|
|
1564
|
+
|
|
1565
|
+
.rubric-meters {
|
|
1566
|
+
display: flex;
|
|
1567
|
+
flex-direction: column;
|
|
1568
|
+
gap: 8px;
|
|
1569
|
+
}
|
|
1570
|
+
|
|
1571
|
+
.rubric-row {
|
|
1572
|
+
display: flex;
|
|
1573
|
+
flex-direction: column;
|
|
1574
|
+
gap: 2px;
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
.rubric-label-bar {
|
|
1578
|
+
display: flex;
|
|
1579
|
+
justify-content: space-between;
|
|
1580
|
+
font-family: var(--font-pixel);
|
|
1581
|
+
font-size: 7px;
|
|
1582
|
+
color: var(--text-dim);
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
.rubric-bar-bg {
|
|
1586
|
+
width: 100%;
|
|
1587
|
+
height: 6px;
|
|
1588
|
+
background: #15192c;
|
|
1589
|
+
border: 1px solid #000;
|
|
1590
|
+
}
|
|
1591
|
+
|
|
1592
|
+
.rubric-bar-fill {
|
|
1593
|
+
height: 100%;
|
|
1594
|
+
background: var(--color-cyan);
|
|
1595
|
+
}
|
|
1596
|
+
|
|
1597
|
+
.oneshot-preview-panel {
|
|
1598
|
+
background: #080a14;
|
|
1599
|
+
border: 2px solid var(--border-color);
|
|
1600
|
+
display: flex;
|
|
1601
|
+
flex-direction: column;
|
|
1602
|
+
}
|
|
1603
|
+
|
|
1604
|
+
.preview-header {
|
|
1605
|
+
display: flex;
|
|
1606
|
+
justify-content: space-between;
|
|
1607
|
+
align-items: center;
|
|
1608
|
+
padding: 8px 12px;
|
|
1609
|
+
background: #111526;
|
|
1610
|
+
border-bottom: 1px solid var(--border-color);
|
|
1611
|
+
}
|
|
1612
|
+
|
|
1613
|
+
.preview-title { font-family: var(--font-pixel); font-size: 8px; color: var(--text-main); }
|
|
1614
|
+
|
|
1615
|
+
.preview-iframe-wrapper {
|
|
1616
|
+
flex: 1;
|
|
1617
|
+
min-height: 280px;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
.site-preview-iframe {
|
|
1621
|
+
width: 100%;
|
|
1622
|
+
height: 100%;
|
|
1623
|
+
min-height: 280px;
|
|
1624
|
+
border: none;
|
|
1625
|
+
background: #0b0c10;
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
@media (max-width: 900px) {
|
|
1629
|
+
.oneshot-top-grid { grid-template-columns: 1fr; }
|
|
1630
|
+
.oneshot-results-grid { grid-template-columns: 1fr; }
|
|
1631
|
+
.pipeline-steps { flex-direction: column; }
|
|
1632
|
+
.pipeline-arrow { transform: rotate(90deg); }
|
|
1633
|
+
}
|
|
1634
|
+
|
|
@@ -2,6 +2,7 @@ import { EventEmitter } from 'node:events';
|
|
|
2
2
|
import fs from 'node:fs/promises';
|
|
3
3
|
import path from 'node:path';
|
|
4
4
|
import { auditCodebaseForTask } from '../scaffold/analyzer.js';
|
|
5
|
+
import { OneShotEngine } from './oneshot.js';
|
|
5
6
|
|
|
6
7
|
export const AGENT_STATES = {
|
|
7
8
|
IDLE: 'IDLE',
|
|
@@ -599,6 +600,244 @@ export class OrchestratorEngine extends EventEmitter {
|
|
|
599
600
|
}
|
|
600
601
|
}
|
|
601
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
|
+
|
|
602
841
|
/**
|
|
603
842
|
* Compiles structured audit report with both user-friendly JSON and Markdown formats
|
|
604
843
|
*/
|