@yemi33/minions 0.1.173 → 0.1.175
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 +17 -0
- package/dashboard/js/refresh.js +35 -8
- package/dashboard/layout.html +8 -5
- package/engine/cli.js +10 -6
- package/minions.js +9 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,22 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.1.175 (2026-04-02)
|
|
4
|
+
|
|
5
|
+
### Engine
|
|
6
|
+
- engine/cli.js
|
|
7
|
+
|
|
8
|
+
### Dashboard
|
|
9
|
+
- dashboard/js/refresh.js
|
|
10
|
+
- dashboard/layout.html
|
|
11
|
+
|
|
12
|
+
### Other
|
|
13
|
+
- minions.js
|
|
14
|
+
|
|
15
|
+
## 0.1.174 (2026-04-02)
|
|
16
|
+
|
|
17
|
+
### Dashboard
|
|
18
|
+
- dashboard/js/refresh.js
|
|
19
|
+
|
|
3
20
|
## 0.1.173 (2026-04-02)
|
|
4
21
|
|
|
5
22
|
### Engine
|
package/dashboard/js/refresh.js
CHANGED
|
@@ -6,21 +6,37 @@ let _prevEngineAlert = false;
|
|
|
6
6
|
function _detectPageChanges(data) {
|
|
7
7
|
const counts = {
|
|
8
8
|
completions: (data.dispatch?.completed || []).length,
|
|
9
|
+
activeDispatches: (data.dispatch?.active || []).length,
|
|
9
10
|
workDone: (data.workItems || []).filter(w => w.status === 'done' || w.status === 'failed').length,
|
|
10
11
|
workTotal: (data.workItems || []).length,
|
|
12
|
+
workDispatched: (data.workItems || []).filter(w => w.status === 'dispatched').length,
|
|
11
13
|
prdComplete: data.prdProgress?.complete || 0,
|
|
14
|
+
prdInProgress: data.prdProgress?.inProgress || 0,
|
|
15
|
+
plansTotal: (data.plans || []).length,
|
|
16
|
+
prsTotal: (data.pullRequests || []).length,
|
|
12
17
|
prsMerged: (data.pullRequests || []).filter(p => p.status === 'merged').length,
|
|
18
|
+
prsReviewed: (data.pullRequests || []).filter(p => p.reviewStatus === 'approved' || p.reviewStatus === 'changes-requested').length,
|
|
13
19
|
inbox: (data.inbox?.items || []).length,
|
|
20
|
+
kbTotal: Object.values(data.knowledgeBase || {}).reduce((s, v) => s + (Array.isArray(v) ? v.length : 0), 0),
|
|
21
|
+
skillsTotal: (data.skills || []).length,
|
|
22
|
+
mcpTotal: (data.mcpServers || []).length,
|
|
23
|
+
scheduleTotal: (data.schedules || []).length,
|
|
24
|
+
pipelineRuns: (data.pipelines || []).reduce((s, p) => s + (p.runs || []).length, 0),
|
|
25
|
+
pipelineActive: (data.pipelines || []).filter(p => (p.runs || []).some(r => r.status === 'running')).length,
|
|
14
26
|
meetingRounds: (data.meetings || []).reduce((s, m) => s + (m.round || 0), 0),
|
|
27
|
+
meetingTotal: (data.meetings || []).length,
|
|
15
28
|
};
|
|
16
29
|
const changes = {};
|
|
17
30
|
if (_prevCounts.completions !== undefined) {
|
|
18
|
-
if (counts.completions > _prevCounts.completions) changes.home = true;
|
|
19
|
-
if (counts.workDone > _prevCounts.workDone || counts.workTotal > _prevCounts.workTotal) changes.work = true;
|
|
20
|
-
if (counts.prdComplete > _prevCounts.prdComplete) changes.plans = true;
|
|
21
|
-
if (counts.prsMerged > _prevCounts.prsMerged) changes.prs = true;
|
|
22
|
-
if (counts.inbox > _prevCounts.inbox) changes.inbox = true;
|
|
23
|
-
if (counts.
|
|
31
|
+
if (counts.completions > _prevCounts.completions || counts.activeDispatches > _prevCounts.activeDispatches) changes.home = true;
|
|
32
|
+
if (counts.workDone > _prevCounts.workDone || counts.workTotal > _prevCounts.workTotal || counts.workDispatched !== _prevCounts.workDispatched) changes.work = true;
|
|
33
|
+
if (counts.prdComplete > _prevCounts.prdComplete || counts.prdInProgress > _prevCounts.prdInProgress || counts.plansTotal > _prevCounts.plansTotal) changes.plans = true;
|
|
34
|
+
if (counts.prsTotal > _prevCounts.prsTotal || counts.prsMerged > _prevCounts.prsMerged || counts.prsReviewed > _prevCounts.prsReviewed) changes.prs = true;
|
|
35
|
+
if (counts.inbox > _prevCounts.inbox || counts.kbTotal > _prevCounts.kbTotal) changes.inbox = true;
|
|
36
|
+
if (counts.skillsTotal > _prevCounts.skillsTotal || counts.mcpTotal > _prevCounts.mcpTotal) changes.tools = true;
|
|
37
|
+
if (counts.scheduleTotal > _prevCounts.scheduleTotal) changes.schedule = true;
|
|
38
|
+
if (counts.pipelineRuns > _prevCounts.pipelineRuns || counts.pipelineActive > _prevCounts.pipelineActive) changes.pipelines = true;
|
|
39
|
+
if (counts.meetingRounds > _prevCounts.meetingRounds || counts.meetingTotal > _prevCounts.meetingTotal) changes.meetings = true;
|
|
24
40
|
}
|
|
25
41
|
_prevCounts = counts;
|
|
26
42
|
|
|
@@ -81,7 +97,9 @@ function _processStatusUpdate(data) {
|
|
|
81
97
|
}
|
|
82
98
|
document.getElementById('ts').textContent = new Date(data.timestamp).toLocaleTimeString();
|
|
83
99
|
const engineState = (data.engine && data.engine.state) ? data.engine.state : 'stopped';
|
|
84
|
-
|
|
100
|
+
// Show setup banner if no projects linked (the key onboarding step)
|
|
101
|
+
const noProjects = !data.projects || data.projects.length === 0;
|
|
102
|
+
document.getElementById('setup-banner').style.display = (noProjects && engineState !== 'stopped') ? 'block' : 'none';
|
|
85
103
|
renderAgents(data.agents);
|
|
86
104
|
renderPrdProgress(data.prdProgress);
|
|
87
105
|
_cachePrdItems(data.prdProgress);
|
|
@@ -146,7 +164,16 @@ async function refresh() {
|
|
|
146
164
|
refresh();
|
|
147
165
|
|
|
148
166
|
// Poll for status updates (SSE caused HTTP/1.1 connection exhaustion — CC fetch would fail)
|
|
149
|
-
setInterval(refresh, 4000);
|
|
167
|
+
var _refreshTimer = setInterval(refresh, 4000);
|
|
168
|
+
document.addEventListener('visibilitychange', function() {
|
|
169
|
+
if (document.hidden) {
|
|
170
|
+
clearInterval(_refreshTimer);
|
|
171
|
+
_refreshTimer = null;
|
|
172
|
+
} else if (!_refreshTimer) {
|
|
173
|
+
refresh();
|
|
174
|
+
_refreshTimer = setInterval(refresh, 4000);
|
|
175
|
+
}
|
|
176
|
+
});
|
|
150
177
|
|
|
151
178
|
// Wire sidebar navigation
|
|
152
179
|
document.querySelectorAll('.sidebar-link').forEach(link => {
|
package/dashboard/layout.html
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<div class="engine-alert" id="engine-alert"></div>
|
|
22
22
|
|
|
23
23
|
<!-- Command Center Drawer -->
|
|
24
|
-
<div id="cc-drawer" style="display:none;position:fixed;top:0;right:0;bottom:0;width:420px;background:var(--surface);border-left:1px solid var(--border);z-index:
|
|
24
|
+
<div id="cc-drawer" style="display:none;position:fixed;top:0;right:0;bottom:0;width:420px;background:var(--surface);border-left:1px solid var(--border);z-index:350;flex-direction:column;overscroll-behavior:contain">
|
|
25
25
|
<div id="cc-resize-handle" class="cc-resize-handle"></div>
|
|
26
26
|
<div style="padding:12px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between">
|
|
27
27
|
<div style="display:flex;align-items:center;gap:8px">
|
|
@@ -48,10 +48,13 @@
|
|
|
48
48
|
<div id="projects-list" style="display:flex;gap:8px;flex-wrap:wrap;">—</div>
|
|
49
49
|
</div>
|
|
50
50
|
|
|
51
|
-
<div id="setup-banner" style="display:none;margin:16px 24px;padding:16px 20px;background:var(--surface2);border:1px dashed var(--blue);border-radius:8px;
|
|
52
|
-
<div style="font-size:18px;margin-bottom:6px">
|
|
53
|
-
<div style="color:var(--muted);font-size:13px;margin-bottom:
|
|
54
|
-
<
|
|
51
|
+
<div id="setup-banner" style="display:none;margin:16px 24px;padding:16px 20px;background:var(--surface2);border:1px dashed var(--blue);border-radius:8px;color:var(--text)">
|
|
52
|
+
<div style="font-size:18px;margin-bottom:6px;text-align:center">Getting Started</div>
|
|
53
|
+
<div style="color:var(--muted);font-size:13px;margin-bottom:12px;text-align:center">No projects linked yet. Link a project so agents know what code to work on.</div>
|
|
54
|
+
<div style="display:flex;flex-direction:column;gap:8px;align-items:center">
|
|
55
|
+
<code style="background:var(--bg);padding:6px 16px;border-radius:4px;font-size:13px;color:var(--blue);border:1px solid var(--border)">minions add <path-to-your-repo></code>
|
|
56
|
+
<div style="font-size:11px;color:var(--muted)">Then try: <code style="background:var(--bg);padding:2px 6px;border-radius:3px;font-size:11px">minions work "Explore the codebase"</code> or use the Command Center above</div>
|
|
57
|
+
</div>
|
|
55
58
|
</div>
|
|
56
59
|
|
|
57
60
|
<!-- Layout replaced by page-layout sidebar navigation -->
|
package/engine/cli.js
CHANGED
|
@@ -92,6 +92,10 @@ const commands = {
|
|
|
92
92
|
|
|
93
93
|
const { getProjects } = require('./shared');
|
|
94
94
|
const projects = getProjects(config);
|
|
95
|
+
if (projects.length === 0) {
|
|
96
|
+
console.log(' \x1b[33mNo projects configured.\x1b[0m Link one with: minions add <path-to-repo>');
|
|
97
|
+
console.log(' Agents can still work on tasks via the Command Center without a project.');
|
|
98
|
+
}
|
|
95
99
|
for (const p of projects) {
|
|
96
100
|
const root = p.localPath ? path.resolve(p.localPath) : null;
|
|
97
101
|
if (!root || !fs.existsSync(root)) {
|
|
@@ -322,6 +326,7 @@ const commands = {
|
|
|
322
326
|
|
|
323
327
|
// File-change-driven work discovery — trigger tick when work-items or PRDs change
|
|
324
328
|
const _watchedFiles = new Set();
|
|
329
|
+
let _globalDebounce = null;
|
|
325
330
|
function watchForWorkChanges() {
|
|
326
331
|
const filesToWatch = [
|
|
327
332
|
path.join(MINIONS_DIR, 'work-items.json'),
|
|
@@ -344,13 +349,12 @@ const commands = {
|
|
|
344
349
|
if (_watchedFiles.has(filePath)) continue;
|
|
345
350
|
_watchedFiles.add(filePath);
|
|
346
351
|
try {
|
|
347
|
-
let _debounce = null;
|
|
348
352
|
fs.watchFile(filePath, { interval: 2000 }, () => {
|
|
349
|
-
//
|
|
350
|
-
if (
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
e.log('info', `File change detected
|
|
353
|
+
// Global debounce — coalesce rapid multi-file changes into one tick
|
|
354
|
+
if (_globalDebounce) clearTimeout(_globalDebounce);
|
|
355
|
+
_globalDebounce = setTimeout(() => {
|
|
356
|
+
_globalDebounce = null;
|
|
357
|
+
e.log('info', `File change detected — triggering tick`);
|
|
354
358
|
e.tick();
|
|
355
359
|
}, 1000);
|
|
356
360
|
});
|
package/minions.js
CHANGED
|
@@ -393,8 +393,15 @@ async function initMinions({ skipScan = false, scanRoot, scanDepth } = {}) {
|
|
|
393
393
|
const config = loadConfig();
|
|
394
394
|
if (!config.projects) config.projects = [];
|
|
395
395
|
const removedPlaceholders = cleanupPlaceholderProjects(config);
|
|
396
|
-
|
|
397
|
-
if (!config.
|
|
396
|
+
// Merge defaults — fills in new fields from upgrades while preserving user customizations
|
|
397
|
+
if (!config.engine) config.engine = {};
|
|
398
|
+
for (const [k, v] of Object.entries(ENGINE_DEFAULTS)) {
|
|
399
|
+
if (config.engine[k] === undefined) config.engine[k] = v;
|
|
400
|
+
}
|
|
401
|
+
if (!config.claude) config.claude = {};
|
|
402
|
+
for (const [k, v] of Object.entries(DEFAULT_CLAUDE)) {
|
|
403
|
+
if (config.claude[k] === undefined) config.claude[k] = v;
|
|
404
|
+
}
|
|
398
405
|
if (!config.agents || Object.keys(config.agents).length === 0) {
|
|
399
406
|
config.agents = { ...DEFAULT_AGENTS };
|
|
400
407
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.175",
|
|
4
4
|
"description": "Multi-agent AI dev team that runs from ~/.minions/ — five autonomous agents share a single engine, dashboard, and knowledge base",
|
|
5
5
|
"bin": {
|
|
6
6
|
"minions": "bin/minions.js"
|