orchestrix-yuri 4.7.4 โ 4.7.6
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.
|
@@ -108,6 +108,7 @@ class PhaseOrchestrator {
|
|
|
108
108
|
this._session = phase3.tmux.session;
|
|
109
109
|
this._devStartedAt = phase3.started_at ? new Date(phase3.started_at).getTime() : Date.now();
|
|
110
110
|
this._lastReportTime = Date.now(); // don't send report immediately on recover
|
|
111
|
+
this._lastActiveAgent = null;
|
|
111
112
|
|
|
112
113
|
const pollInterval = this.config.dev_poll_interval || 300000;
|
|
113
114
|
this._timer = setInterval(() => this._pollDevSession(), pollInterval);
|
|
@@ -244,12 +245,19 @@ class PhaseOrchestrator {
|
|
|
244
245
|
|
|
245
246
|
if (this._phase === 'iterate') {
|
|
246
247
|
const ctx = this._changeContext || {};
|
|
247
|
-
|
|
248
|
+
const agentLabels = { pm: 'PM generating next-steps', architect: 'Architect resolving changes' };
|
|
249
|
+
const label = agentLabels[ctx.iteratePhase] || ctx.iteratePhase || 'starting';
|
|
250
|
+
return { phase: 'iterate', message: `๐ Iteration in progress\n๐ ${label} (${this._step + 1}/2)` };
|
|
248
251
|
}
|
|
249
252
|
|
|
250
253
|
if (this._phase === 'change') {
|
|
251
254
|
const ctx = this._changeContext || {};
|
|
252
|
-
|
|
255
|
+
const stepLabels = ['PO routing change', 'Architect resolving', 'SM applying proposal'];
|
|
256
|
+
const stepLabel = stepLabels[this._step] || `Step ${this._step + 1}`;
|
|
257
|
+
return {
|
|
258
|
+
phase: 'change',
|
|
259
|
+
message: `๐ง Change in progress (${ctx.scope || '?'})\n๐ ${stepLabel} (${this._step + 1}/3)`,
|
|
260
|
+
};
|
|
253
261
|
}
|
|
254
262
|
|
|
255
263
|
return { phase: this._phase, message: `Phase ${this._phase} is running.` };
|
|
@@ -630,6 +638,7 @@ class PhaseOrchestrator {
|
|
|
630
638
|
this._timer = setInterval(() => this._pollDevSession(), pollInterval);
|
|
631
639
|
this._devStartedAt = Date.now();
|
|
632
640
|
this._lastReportTime = Date.now();
|
|
641
|
+
this._lastActiveAgent = null;
|
|
633
642
|
|
|
634
643
|
const reportMin = Math.round(this._reportInterval / 60000);
|
|
635
644
|
log.engine(`Dev phase started: session=${this._session}, report every ${reportMin}min`);
|
|
@@ -647,6 +656,18 @@ class PhaseOrchestrator {
|
|
|
647
656
|
// Gather progress data
|
|
648
657
|
const progress = this._gatherDevProgress();
|
|
649
658
|
|
|
659
|
+
// Detect agent handoff and notify user
|
|
660
|
+
if (progress.currentAgent && progress.currentAgent !== this._lastActiveAgent) {
|
|
661
|
+
const prev = this._lastActiveAgent;
|
|
662
|
+
this._lastActiveAgent = progress.currentAgent;
|
|
663
|
+
if (prev) {
|
|
664
|
+
const storyInfo = progress.currentStory ? ` โ working on ${progress.currentStory}` : '';
|
|
665
|
+
this.onProgress(`๐ ${prev} โ **${progress.currentAgent}**${storyInfo}`);
|
|
666
|
+
}
|
|
667
|
+
} else if (progress.currentAgent) {
|
|
668
|
+
this._lastActiveAgent = progress.currentAgent;
|
|
669
|
+
}
|
|
670
|
+
|
|
650
671
|
// Check if all stories done
|
|
651
672
|
if (progress.totalStories > 0 && progress.doneStories >= progress.totalStories) {
|
|
652
673
|
this._completeDev();
|
|
@@ -684,17 +705,26 @@ class PhaseOrchestrator {
|
|
|
684
705
|
|
|
685
706
|
if (output && output !== 'NO_STORIES_DIR') {
|
|
686
707
|
for (const line of output.split('\n')) {
|
|
687
|
-
|
|
688
|
-
const
|
|
689
|
-
|
|
690
|
-
|
|
708
|
+
if (!line.includes(':')) continue;
|
|
709
|
+
const colonIdx = line.indexOf(':');
|
|
710
|
+
const key = line.slice(0, colonIdx);
|
|
711
|
+
const value = line.slice(colonIdx + 1);
|
|
712
|
+
|
|
713
|
+
if (key === 'Total') {
|
|
714
|
+
result.totalStories = parseInt(value, 10) || 0;
|
|
715
|
+
} else if (key === 'Epics') {
|
|
716
|
+
result.totalEpics = parseInt(value, 10) || 0;
|
|
691
717
|
} else if (key === 'CurrentEpic') {
|
|
692
|
-
result.currentEpic =
|
|
693
|
-
} else if (key
|
|
694
|
-
result.
|
|
695
|
-
|
|
696
|
-
|
|
718
|
+
result.currentEpic = parseInt(value, 10) || 0;
|
|
719
|
+
} else if (key === 'CurrentStory') {
|
|
720
|
+
if (!result.currentStory) result.currentStory = value;
|
|
721
|
+
} else if (key.startsWith('Status')) {
|
|
722
|
+
// Per-file status: StatusDone:1.1-name โ count as 'Done'
|
|
723
|
+
const statusName = key.slice(6); // strip 'Status' prefix
|
|
724
|
+
result.byStatus[statusName] = (result.byStatus[statusName] || 0) + 1;
|
|
725
|
+
if (statusName === 'Done') result.doneStories++;
|
|
697
726
|
}
|
|
727
|
+
// 'Created' is metadata โ skip (Total is the authoritative count)
|
|
698
728
|
}
|
|
699
729
|
}
|
|
700
730
|
} catch { /* fallback to phase3.yaml */ }
|
|
@@ -777,7 +807,8 @@ class PhaseOrchestrator {
|
|
|
777
807
|
if (statusEntries.length > 0) {
|
|
778
808
|
const statusIcons = {
|
|
779
809
|
Done: 'โ
', InProgress: '๐', Review: '๐', Blocked: '๐ซ',
|
|
780
|
-
Approved: '
|
|
810
|
+
Approved: '๐', Draft: '๐', NoStatus: 'โ',
|
|
811
|
+
AwaitingArchReview: '๐๏ธ', RequiresRevision: '๐ง', Escalated: 'โ ๏ธ',
|
|
781
812
|
};
|
|
782
813
|
for (const [status, count] of statusEntries) {
|
|
783
814
|
lines.push(`${statusIcons[status] || 'ยท'} ${status}: ${count}`);
|
|
@@ -1394,14 +1425,32 @@ class PhaseOrchestrator {
|
|
|
1394
1425
|
|
|
1395
1426
|
_completeIterate(devSession) {
|
|
1396
1427
|
if (this._timer) { clearInterval(this._timer); this._timer = null; }
|
|
1397
|
-
// Kill planning session
|
|
1428
|
+
// Kill planning session (no longer needed)
|
|
1398
1429
|
if (this._session && tmx.hasSession(this._session)) {
|
|
1399
1430
|
tmx.killSession(this._session);
|
|
1400
1431
|
}
|
|
1401
|
-
|
|
1432
|
+
|
|
1402
1433
|
this._changeContext = null;
|
|
1403
1434
|
log.engine('Iterate complete โ dev automation started');
|
|
1404
1435
|
this.onComplete('iterate', `๐ New iteration launched!\n\nSM is drafting stories in dev session: ${devSession}\nAgents will chain automatically via handoff-detector.`);
|
|
1436
|
+
|
|
1437
|
+
// Transition to dev monitoring so SM โ Architect โ Dev โ QA cycle is tracked.
|
|
1438
|
+
// Without this, the entire dev cycle runs unmonitored after iterate completes.
|
|
1439
|
+
if (devSession && tmx.hasSession(devSession)) {
|
|
1440
|
+
this._phase = 'develop';
|
|
1441
|
+
this._session = devSession;
|
|
1442
|
+
this._devStartedAt = Date.now();
|
|
1443
|
+
this._lastReportTime = Date.now();
|
|
1444
|
+
this._lastActiveAgent = null;
|
|
1445
|
+
this._stableCount = 0;
|
|
1446
|
+
this._lastHash = '';
|
|
1447
|
+
const pollInterval = this.config.dev_poll_interval || 300000;
|
|
1448
|
+
this._timer = setInterval(() => this._pollDevSession(), pollInterval);
|
|
1449
|
+
log.engine(`Iterate โ dev monitoring: session=${devSession}, poll every ${Math.round(pollInterval / 60000)}min`);
|
|
1450
|
+
this.onProgress('๐ Now monitoring dev cycle (SM โ Architect โ Dev โ QA). I\'ll report agent handoffs and progress.');
|
|
1451
|
+
} else {
|
|
1452
|
+
this._phase = null;
|
|
1453
|
+
}
|
|
1405
1454
|
}
|
|
1406
1455
|
|
|
1407
1456
|
// โโ Quick Fix โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|
|
@@ -1609,8 +1658,8 @@ class PhaseOrchestrator {
|
|
|
1609
1658
|
execSync('sleep 12');
|
|
1610
1659
|
tmx.sendKeysWithEnter(this._session, 1, '*draft');
|
|
1611
1660
|
|
|
1612
|
-
//
|
|
1613
|
-
|
|
1661
|
+
// Planning window 0 (Architect) is already stable โ next 3 stable polls
|
|
1662
|
+
// will trigger step 3 โ _completeChange โ transition to dev monitoring.
|
|
1614
1663
|
} catch (err) {
|
|
1615
1664
|
this._handleError('change', `Failed to apply in dev session: ${err.message}`);
|
|
1616
1665
|
}
|
|
@@ -1629,10 +1678,28 @@ class PhaseOrchestrator {
|
|
|
1629
1678
|
clearInterval(this._timer);
|
|
1630
1679
|
this._timer = null;
|
|
1631
1680
|
}
|
|
1632
|
-
|
|
1633
|
-
this._changeContext = null;
|
|
1681
|
+
|
|
1634
1682
|
log.engine(`Change management complete: ${summary}`);
|
|
1635
1683
|
this.onComplete('change', `โ
Change management complete.\n\n${summary}`);
|
|
1684
|
+
|
|
1685
|
+
// Transition to dev monitoring if SM was started in a dev session.
|
|
1686
|
+
// Without this, the SM โ Architect โ Dev โ QA cycle runs unmonitored.
|
|
1687
|
+
if (this._session && tmx.hasSession(this._session)) {
|
|
1688
|
+
this._phase = 'develop';
|
|
1689
|
+
this._changeContext = null;
|
|
1690
|
+
this._devStartedAt = Date.now();
|
|
1691
|
+
this._lastReportTime = Date.now();
|
|
1692
|
+
this._lastActiveAgent = null;
|
|
1693
|
+
this._stableCount = 0;
|
|
1694
|
+
this._lastHash = '';
|
|
1695
|
+
const pollInterval = this.config.dev_poll_interval || 300000;
|
|
1696
|
+
this._timer = setInterval(() => this._pollDevSession(), pollInterval);
|
|
1697
|
+
log.engine(`Change โ dev monitoring: session=${this._session}, poll every ${Math.round(pollInterval / 60000)}min`);
|
|
1698
|
+
this.onProgress('๐ Now monitoring dev cycle (SM โ Architect โ Dev โ QA). I\'ll report agent handoffs and progress.');
|
|
1699
|
+
} else {
|
|
1700
|
+
this._phase = null;
|
|
1701
|
+
this._changeContext = null;
|
|
1702
|
+
}
|
|
1636
1703
|
}
|
|
1637
1704
|
|
|
1638
1705
|
// โโ Shared โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
|