@yemi33/minions 0.1.35 → 0.1.37
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/CHANGELOG.md +11 -0
- package/dashboard/js/refresh.js +6 -0
- package/dashboard.js +44 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/dashboard/js/refresh.js
CHANGED
|
@@ -58,3 +58,9 @@ document.querySelectorAll('.sidebar-link').forEach(link => {
|
|
|
58
58
|
link.addEventListener('click', e => { e.preventDefault(); switchPage(link.dataset.page); });
|
|
59
59
|
});
|
|
60
60
|
switchPage(currentPage);
|
|
61
|
+
|
|
62
|
+
// Hot-reload: auto-refresh browser when dashboard files change
|
|
63
|
+
try {
|
|
64
|
+
const _hotReload = new EventSource('/api/hot-reload');
|
|
65
|
+
_hotReload.onmessage = (e) => { if (e.data === 'reload') location.reload(); };
|
|
66
|
+
} catch {}
|
package/dashboard.js
CHANGED
|
@@ -92,11 +92,45 @@ function buildDashboardHtml() {
|
|
|
92
92
|
.replace('/* __JS__ */', () => jsHtml);
|
|
93
93
|
}
|
|
94
94
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
95
|
+
let HTML_RAW = buildDashboardHtml();
|
|
96
|
+
let HTML = HTML_RAW.replace('Minions Mission Control', `Minions Mission Control — ${projectNames}`);
|
|
97
|
+
let HTML_GZ = zlib.gzipSync(HTML);
|
|
98
|
+
let HTML_ETAG = '"' + require('crypto').createHash('md5').update(HTML).digest('hex') + '"';
|
|
99
99
|
|
|
100
|
+
// Hot-reload: watch dashboard/ directory for changes, rebuild, and push reload to browsers
|
|
101
|
+
const _hotReloadClients = new Set();
|
|
102
|
+
|
|
103
|
+
function rebuildDashboardHtml() {
|
|
104
|
+
try {
|
|
105
|
+
const newRaw = buildDashboardHtml();
|
|
106
|
+
if (newRaw === HTML_RAW) return; // no changes
|
|
107
|
+
HTML_RAW = newRaw;
|
|
108
|
+
HTML = HTML_RAW.replace('Minions Mission Control', `Minions Mission Control — ${projectNames}`);
|
|
109
|
+
HTML_GZ = zlib.gzipSync(HTML);
|
|
110
|
+
HTML_ETAG = '"' + require('crypto').createHash('md5').update(HTML).digest('hex') + '"';
|
|
111
|
+
console.log(' Dashboard hot-reloaded');
|
|
112
|
+
// Push reload to all connected browsers
|
|
113
|
+
for (const res of _hotReloadClients) {
|
|
114
|
+
try { res.write('data: reload\n\n'); } catch { _hotReloadClients.delete(res); }
|
|
115
|
+
}
|
|
116
|
+
} catch (e) { console.error(' Hot-reload error:', e.message); }
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
const dashDir = path.join(MINIONS_DIR, 'dashboard');
|
|
120
|
+
if (fs.existsSync(dashDir)) {
|
|
121
|
+
let _reloadTimer = null;
|
|
122
|
+
const scheduleReload = () => {
|
|
123
|
+
if (_reloadTimer) clearTimeout(_reloadTimer);
|
|
124
|
+
_reloadTimer = setTimeout(rebuildDashboardHtml, 300); // debounce 300ms
|
|
125
|
+
};
|
|
126
|
+
// Watch top-level files (styles.css, layout.html)
|
|
127
|
+
try { fs.watch(dashDir, scheduleReload); } catch {}
|
|
128
|
+
// Watch subdirectories (pages/, js/)
|
|
129
|
+
for (const sub of ['pages', 'js']) {
|
|
130
|
+
const subDir = path.join(dashDir, sub);
|
|
131
|
+
if (fs.existsSync(subDir)) try { fs.watch(subDir, scheduleReload); } catch {}
|
|
132
|
+
}
|
|
133
|
+
}
|
|
100
134
|
|
|
101
135
|
// -- Data Collectors (most moved to engine/queries.js) --
|
|
102
136
|
|
|
@@ -2783,6 +2817,12 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
2783
2817
|
// Status & health
|
|
2784
2818
|
{ method: 'GET', path: '/api/status', desc: 'Full dashboard status snapshot (agents, PRDs, work items, dispatch, etc.)', handler: handleStatus },
|
|
2785
2819
|
{ method: 'GET', path: '/api/health', desc: 'Lightweight health check for monitoring', handler: handleHealth },
|
|
2820
|
+
{ method: 'GET', path: '/api/hot-reload', desc: 'SSE stream for dashboard hot-reload notifications', handler: (req, res) => {
|
|
2821
|
+
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' });
|
|
2822
|
+
res.write('data: connected\n\n');
|
|
2823
|
+
_hotReloadClients.add(res);
|
|
2824
|
+
req.on('close', () => _hotReloadClients.delete(res));
|
|
2825
|
+
}},
|
|
2786
2826
|
|
|
2787
2827
|
// Work items
|
|
2788
2828
|
{ method: 'POST', path: '/api/work-items', desc: 'Create a new work item', params: 'title, type?, description?, priority?, project?, agent?, agents?, scope?, references?, acceptanceCriteria?', handler: handleWorkItemsCreate },
|
package/package.json
CHANGED