@yemi33/minions 0.1.71 → 0.1.73
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 +12 -0
- package/dashboard/js/live-stream.js +3 -24
- package/dashboard/js/refresh.js +35 -0
- package/dashboard/js/state.js +5 -1
- package/dashboard/styles.css +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.73 (2026-03-31)
|
|
4
|
+
|
|
5
|
+
### Dashboard
|
|
6
|
+
- dashboard/js/refresh.js
|
|
7
|
+
- dashboard/js/state.js
|
|
8
|
+
- dashboard/styles.css
|
|
9
|
+
|
|
10
|
+
## 0.1.72 (2026-03-31)
|
|
11
|
+
|
|
12
|
+
### Dashboard
|
|
13
|
+
- dashboard/js/live-stream.js
|
|
14
|
+
|
|
3
15
|
## 0.1.71 (2026-03-31)
|
|
4
16
|
|
|
5
17
|
### Dashboard
|
|
@@ -82,30 +82,9 @@ function startLiveStream(agentId) {
|
|
|
82
82
|
const msgEl = document.getElementById('live-messages');
|
|
83
83
|
if (msgEl) msgEl.innerHTML = '';
|
|
84
84
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
try {
|
|
89
|
-
const chunk = JSON.parse(e.data);
|
|
90
|
-
renderLiveChatMessage(chunk);
|
|
91
|
-
} catch (e) { console.error('live-stream:', e.message); }
|
|
92
|
-
};
|
|
93
|
-
|
|
94
|
-
liveEventSource.addEventListener('done', function() {
|
|
95
|
-
stopLiveStream();
|
|
96
|
-
const steerBar = document.getElementById('live-steer-bar');
|
|
97
|
-
if (steerBar) steerBar.style.display = 'none';
|
|
98
|
-
const statusLabel = document.getElementById('live-status-label');
|
|
99
|
-
if (statusLabel) { statusLabel.textContent = 'Completed'; statusLabel.style.color = 'var(--muted)'; }
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
liveEventSource.onerror = function() {
|
|
103
|
-
// Fall back to polling on SSE error
|
|
104
|
-
stopLiveStream();
|
|
105
|
-
startLivePolling();
|
|
106
|
-
const label = document.getElementById('live-status-label');
|
|
107
|
-
if (label) label.textContent = 'Auto-refreshing every 3s';
|
|
108
|
-
};
|
|
85
|
+
// Use polling instead of SSE to avoid HTTP/1.1 connection exhaustion
|
|
86
|
+
// (SSE holds a persistent connection, blocking CC and other API calls)
|
|
87
|
+
startLivePolling();
|
|
109
88
|
}
|
|
110
89
|
|
|
111
90
|
function stopLiveStream() {
|
package/dashboard/js/refresh.js
CHANGED
|
@@ -1,5 +1,30 @@
|
|
|
1
1
|
// refresh.js — Main refresh loop and initialization extracted from dashboard.html
|
|
2
2
|
|
|
3
|
+
// Sidebar activity indicators — detect changes between refreshes
|
|
4
|
+
let _prevCounts = {};
|
|
5
|
+
function _detectPageChanges(data) {
|
|
6
|
+
const counts = {
|
|
7
|
+
completions: (data.dispatch?.completed || []).length,
|
|
8
|
+
workDone: (data.workItems || []).filter(w => w.status === 'done' || w.status === 'failed').length,
|
|
9
|
+
workTotal: (data.workItems || []).length,
|
|
10
|
+
prdComplete: data.prdProgress?.complete || 0,
|
|
11
|
+
prsMerged: (data.pullRequests || []).filter(p => p.status === 'merged').length,
|
|
12
|
+
inbox: (data.inbox?.items || []).length,
|
|
13
|
+
meetingRounds: (data.meetings || []).reduce((s, m) => s + (m.round || 0), 0),
|
|
14
|
+
};
|
|
15
|
+
const changes = {};
|
|
16
|
+
if (_prevCounts.completions !== undefined) {
|
|
17
|
+
if (counts.completions > _prevCounts.completions) changes.home = true;
|
|
18
|
+
if (counts.workDone > _prevCounts.workDone || counts.workTotal > _prevCounts.workTotal) changes.work = true;
|
|
19
|
+
if (counts.prdComplete > _prevCounts.prdComplete) changes.plans = true;
|
|
20
|
+
if (counts.prsMerged > _prevCounts.prsMerged) changes.prs = true;
|
|
21
|
+
if (counts.inbox > _prevCounts.inbox) changes.inbox = true;
|
|
22
|
+
if (counts.meetingRounds > _prevCounts.meetingRounds) changes.meetings = true;
|
|
23
|
+
}
|
|
24
|
+
_prevCounts = counts;
|
|
25
|
+
return changes;
|
|
26
|
+
}
|
|
27
|
+
|
|
3
28
|
function _processStatusUpdate(data) {
|
|
4
29
|
// Detect fresh install — clear stale browser state if install ID changed
|
|
5
30
|
if (data.installId) {
|
|
@@ -46,6 +71,16 @@ function _processStatusUpdate(data) {
|
|
|
46
71
|
// Refresh KB and plans less frequently (every 3rd cycle = ~12s)
|
|
47
72
|
if (!window._kbRefreshCount) window._kbRefreshCount = 0;
|
|
48
73
|
if (window._kbRefreshCount++ % 3 === 0) { refreshKnowledgeBase(); refreshPlans(); }
|
|
74
|
+
|
|
75
|
+
// Sidebar activity indicators — show red dot on pages with new activity
|
|
76
|
+
try {
|
|
77
|
+
const changes = _detectPageChanges(data);
|
|
78
|
+
for (const page of Object.keys(changes)) {
|
|
79
|
+
if (currentPage === page) continue; // don't badge the active page
|
|
80
|
+
const link = document.querySelector('.sidebar-link[data-page="' + page + '"]');
|
|
81
|
+
if (link && !link.querySelector('.notif-badge')) showNotifBadge(link, 'done');
|
|
82
|
+
}
|
|
83
|
+
} catch { /* expected on first load */ }
|
|
49
84
|
}
|
|
50
85
|
|
|
51
86
|
async function refresh() {
|
package/dashboard/js/state.js
CHANGED
|
@@ -21,7 +21,11 @@ function switchPage(page, pushState) {
|
|
|
21
21
|
if (target) target.classList.add('active');
|
|
22
22
|
document.querySelectorAll('.sidebar-link').forEach(l => l.classList.remove('active'));
|
|
23
23
|
const link = document.querySelector('.sidebar-link[data-page="' + page + '"]');
|
|
24
|
-
if (link)
|
|
24
|
+
if (link) {
|
|
25
|
+
link.classList.add('active');
|
|
26
|
+
// Clear notification badge when visiting a page
|
|
27
|
+
try { clearNotifBadge(link); } catch { /* clearNotifBadge may not be loaded yet */ }
|
|
28
|
+
}
|
|
25
29
|
if (pushState !== false) {
|
|
26
30
|
const url = page === 'home' ? '/' : '/' + page;
|
|
27
31
|
history.pushState({ page }, '', url);
|
package/dashboard/styles.css
CHANGED
|
@@ -43,7 +43,8 @@
|
|
|
43
43
|
/* Sidebar navigation */
|
|
44
44
|
.page-layout { display: flex; height: calc(100vh - 44px); overflow: hidden; }
|
|
45
45
|
.sidebar { width: 150px; min-width: 150px; background: var(--surface); border-right: 1px solid var(--border); padding: var(--space-4) 0; overflow-y: auto; position: sticky; top: 0; }
|
|
46
|
-
.sidebar-link { display: flex; align-items: center; justify-content: space-between; padding: 8px 14px; color: var(--muted); text-decoration: none; font-size: var(--text-sm); border-left: 3px solid transparent; transition: all var(--transition-fast); cursor: pointer; }
|
|
46
|
+
.sidebar-link { display: flex; align-items: center; justify-content: space-between; padding: 8px 14px; color: var(--muted); text-decoration: none; font-size: var(--text-sm); border-left: 3px solid transparent; transition: all var(--transition-fast); cursor: pointer; position: relative; }
|
|
47
|
+
.sidebar-link .notif-badge.done { top: 50%; right: 6px; transform: translateY(-50%); width: 6px; height: 6px; }
|
|
47
48
|
.sidebar-link:hover { color: var(--text); background: var(--surface2); }
|
|
48
49
|
.sidebar-link.active { color: var(--blue); border-left-color: var(--blue); background: var(--surface2); font-weight: 600; }
|
|
49
50
|
.sidebar-count { font-size: 9px; color: var(--muted); background: var(--surface2); padding: 1px 5px; border-radius: 8px; min-width: 16px; text-align: center; }
|
package/package.json
CHANGED