orchestrix-yuri 4.2.3 → 4.2.4
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/lib/gateway/router.js +43 -0
- package/package.json +1 -1
package/lib/gateway/router.js
CHANGED
|
@@ -69,6 +69,48 @@ class Router {
|
|
|
69
69
|
if (projectRoot) {
|
|
70
70
|
this.orchestrator.tryRecover(projectRoot);
|
|
71
71
|
}
|
|
72
|
+
|
|
73
|
+
// Independent progress reporter: sends periodic status card
|
|
74
|
+
// when dev phase is active (detected from focus.yaml + tmux),
|
|
75
|
+
// regardless of whether orchestrator is tracking it.
|
|
76
|
+
this._reportTimer = null;
|
|
77
|
+
this._startAutoReporter(config);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* Start an independent timer that checks if dev phase is running
|
|
82
|
+
* and sends a progress card periodically.
|
|
83
|
+
*/
|
|
84
|
+
_startAutoReporter(config) {
|
|
85
|
+
const interval = (config.engine && config.engine.report_interval) || 1800000; // 30 min
|
|
86
|
+
this._reportTimer = setInterval(() => {
|
|
87
|
+
// Skip if orchestrator is already reporting (avoid duplicates)
|
|
88
|
+
if (this.orchestrator.isRunning()) return;
|
|
89
|
+
|
|
90
|
+
// Check if dev phase is active
|
|
91
|
+
const projectRoot = engine.resolveProjectRoot();
|
|
92
|
+
if (!projectRoot) return;
|
|
93
|
+
|
|
94
|
+
const focusPath = path.join(projectRoot, '.yuri', 'focus.yaml');
|
|
95
|
+
if (!fs.existsSync(focusPath)) return;
|
|
96
|
+
|
|
97
|
+
try {
|
|
98
|
+
const focus = yaml.load(fs.readFileSync(focusPath, 'utf8')) || {};
|
|
99
|
+
if (parseInt(focus.phase, 10) !== 3) return;
|
|
100
|
+
|
|
101
|
+
// Check tmux session is alive
|
|
102
|
+
const { execSync } = require('child_process');
|
|
103
|
+
const sessions = execSync('tmux list-sessions -F "#{session_name}" 2>/dev/null', { encoding: 'utf8' }).trim();
|
|
104
|
+
if (!sessions.split('\n').some((s) => s.startsWith('orchestrix-'))) return;
|
|
105
|
+
|
|
106
|
+
// Generate and send progress card
|
|
107
|
+
const card = this._buildStatusCard(projectRoot, focus);
|
|
108
|
+
if (card) {
|
|
109
|
+
log.router('Auto-reporting dev progress');
|
|
110
|
+
this._sendProactive(card);
|
|
111
|
+
}
|
|
112
|
+
} catch { /* silent */ }
|
|
113
|
+
}, interval);
|
|
72
114
|
}
|
|
73
115
|
|
|
74
116
|
/**
|
|
@@ -725,6 +767,7 @@ class Router {
|
|
|
725
767
|
* Graceful shutdown.
|
|
726
768
|
*/
|
|
727
769
|
async shutdown() {
|
|
770
|
+
if (this._reportTimer) clearInterval(this._reportTimer);
|
|
728
771
|
this.orchestrator.shutdown();
|
|
729
772
|
if (engine.destroySession) engine.destroySession();
|
|
730
773
|
}
|