orchestrix-yuri 4.8.5 → 4.8.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.
@@ -679,10 +679,17 @@ class PhaseOrchestrator {
679
679
  this._lastActiveAgent = progress.currentAgent;
680
680
  }
681
681
 
682
- // Check if all stories done
682
+ // Check if all stories done — but ONLY if no agent is actively working.
683
+ // If an agent is busy (e.g., SM drafting new stories), story counts are stale.
683
684
  if (progress.totalStories > 0 && progress.doneStories >= progress.totalStories) {
684
- this._completeDev();
685
- return;
685
+ if (progress.currentAgent) {
686
+ // Agent still working — stories may be in flux (new ones being created)
687
+ log.engine(`All ${progress.doneStories}/${progress.totalStories} stories done but ${progress.currentAgent} is still active — waiting`);
688
+ } else {
689
+ // No active agent + all stories done → truly complete
690
+ this._completeDev();
691
+ return;
692
+ }
686
693
  }
687
694
 
688
695
  // Periodic progress report
@@ -38,7 +38,7 @@ const META_COMMANDS = {
38
38
  // All natural language ("怎么样了", "进度如何") goes through dispatcher
39
39
  // so Claude's understanding ability decides the routing.
40
40
  const STATUS_PATTERNS = [
41
- /^\*status\b/i,
41
+ /^[*/]status\b/i,
42
42
  ];
43
43
 
44
44
  /**
@@ -652,10 +652,24 @@ Reply with ONLY one word: small, medium, or large. Nothing else.`;
652
652
  try {
653
653
  const focus = yaml.load(fs.readFileSync(focusPath, 'utf8')) || {};
654
654
 
655
- const phaseNum = parseInt(focus.phase, 10);
655
+ // Always check for live dev session first — it's the ground truth.
656
+ // focus.yaml may be stale (e.g., still says phase 4 after dev restarted).
657
+ let hasLiveDevSession = false;
658
+ try {
659
+ const { execSync } = require('child_process');
660
+ const sessions = execSync('tmux list-sessions -F "#{session_name}" 2>/dev/null', { encoding: 'utf8' }).trim();
661
+ const projectName = path.basename(projectRoot).toLowerCase();
662
+ const devSession = sessions.split('\n').find((s) =>
663
+ s.startsWith('orchestrix-') && s.toLowerCase().includes(projectName)
664
+ ) || sessions.split('\n').find((s) => s.startsWith('orchestrix-'));
665
+ if (devSession) {
666
+ const tmx = require('./engine/tmux-utils');
667
+ hasLiveDevSession = tmx.hasSession(devSession);
668
+ }
669
+ } catch { /* no tmux */ }
656
670
 
657
- // Dev phase: generate progress card (no phase3.yaml dependency)
658
- if (phaseNum === 3) {
671
+ // If live dev session exists, show dev progress card regardless of focus.yaml phase
672
+ if (hasLiveDevSession) {
659
673
  try {
660
674
  const card = this._buildStatusCard(projectRoot, focus);
661
675
  if (card) parts.push(card);
@@ -664,8 +678,10 @@ Reply with ONLY one word: small, medium, or large. Nothing else.`;
664
678
  }
665
679
  }
666
680
 
667
- // Test phase: generate test progress card from phase4.yaml
668
- if (phaseNum === 4 && parts.length === 0) {
681
+ const phaseNum = parseInt(focus.phase, 10);
682
+
683
+ // Test phase: only show if no live dev session and no card yet
684
+ if (phaseNum === 4 && parts.length === 0 && !hasLiveDevSession) {
669
685
  try {
670
686
  const card = this._buildTestStatusCard(projectRoot);
671
687
  if (card) parts.push(card);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orchestrix-yuri",
3
- "version": "4.8.5",
3
+ "version": "4.8.6",
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": {