orchestrix-yuri 4.7.4 → 4.7.5

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
- return { phase: 'iterate', message: `šŸ”„ Iteration in progress. Current: ${ctx.iteratePhase || 'starting'}` };
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
- return { phase: 'change', message: `šŸ”§ Change in progress (${ctx.scope || '?'}). Step ${this._step + 1}` };
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();
@@ -1394,14 +1415,32 @@ class PhaseOrchestrator {
1394
1415
 
1395
1416
  _completeIterate(devSession) {
1396
1417
  if (this._timer) { clearInterval(this._timer); this._timer = null; }
1397
- // Kill planning session
1418
+ // Kill planning session (no longer needed)
1398
1419
  if (this._session && tmx.hasSession(this._session)) {
1399
1420
  tmx.killSession(this._session);
1400
1421
  }
1401
- this._phase = null;
1422
+
1402
1423
  this._changeContext = null;
1403
1424
  log.engine('Iterate complete — dev automation started');
1404
1425
  this.onComplete('iterate', `šŸ”„ New iteration launched!\n\nSM is drafting stories in dev session: ${devSession}\nAgents will chain automatically via handoff-detector.`);
1426
+
1427
+ // Transition to dev monitoring so SM → Architect → Dev → QA cycle is tracked.
1428
+ // Without this, the entire dev cycle runs unmonitored after iterate completes.
1429
+ if (devSession && tmx.hasSession(devSession)) {
1430
+ this._phase = 'develop';
1431
+ this._session = devSession;
1432
+ this._devStartedAt = Date.now();
1433
+ this._lastReportTime = Date.now();
1434
+ this._lastActiveAgent = null;
1435
+ this._stableCount = 0;
1436
+ this._lastHash = '';
1437
+ const pollInterval = this.config.dev_poll_interval || 300000;
1438
+ this._timer = setInterval(() => this._pollDevSession(), pollInterval);
1439
+ log.engine(`Iterate → dev monitoring: session=${devSession}, poll every ${Math.round(pollInterval / 60000)}min`);
1440
+ this.onProgress('šŸ”„ Now monitoring dev cycle (SM → Architect → Dev → QA). I\'ll report agent handoffs and progress.');
1441
+ } else {
1442
+ this._phase = null;
1443
+ }
1405
1444
  }
1406
1445
 
1407
1446
  // ── Quick Fix ───────────────────────────────────────────────────────────────
@@ -1609,8 +1648,8 @@ class PhaseOrchestrator {
1609
1648
  execSync('sleep 12');
1610
1649
  tmx.sendKeysWithEnter(this._session, 1, '*draft');
1611
1650
 
1612
- // Now poll dev session SM window
1613
- this._changeContext._pollDevSM = true;
1651
+ // Planning window 0 (Architect) is already stable — next 3 stable polls
1652
+ // will trigger step 3 → _completeChange → transition to dev monitoring.
1614
1653
  } catch (err) {
1615
1654
  this._handleError('change', `Failed to apply in dev session: ${err.message}`);
1616
1655
  }
@@ -1629,10 +1668,28 @@ class PhaseOrchestrator {
1629
1668
  clearInterval(this._timer);
1630
1669
  this._timer = null;
1631
1670
  }
1632
- this._phase = null;
1633
- this._changeContext = null;
1671
+
1634
1672
  log.engine(`Change management complete: ${summary}`);
1635
1673
  this.onComplete('change', `āœ… Change management complete.\n\n${summary}`);
1674
+
1675
+ // Transition to dev monitoring if SM was started in a dev session.
1676
+ // Without this, the SM → Architect → Dev → QA cycle runs unmonitored.
1677
+ if (this._session && tmx.hasSession(this._session)) {
1678
+ this._phase = 'develop';
1679
+ this._changeContext = null;
1680
+ this._devStartedAt = Date.now();
1681
+ this._lastReportTime = Date.now();
1682
+ this._lastActiveAgent = null;
1683
+ this._stableCount = 0;
1684
+ this._lastHash = '';
1685
+ const pollInterval = this.config.dev_poll_interval || 300000;
1686
+ this._timer = setInterval(() => this._pollDevSession(), pollInterval);
1687
+ log.engine(`Change → dev monitoring: session=${this._session}, poll every ${Math.round(pollInterval / 60000)}min`);
1688
+ this.onProgress('šŸ”„ Now monitoring dev cycle (SM → Architect → Dev → QA). I\'ll report agent handoffs and progress.');
1689
+ } else {
1690
+ this._phase = null;
1691
+ this._changeContext = null;
1692
+ }
1636
1693
  }
1637
1694
 
1638
1695
  // ── Shared ─────────────────────────────────────────────────────────────────
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orchestrix-yuri",
3
- "version": "4.7.4",
3
+ "version": "4.7.5",
4
4
  "description": "Yuri — Meta-Orchestrator for Orchestrix. Drive your entire project lifecycle with natural language.",
5
5
  "main": "lib/installer.js",
6
6
  "bin": {