@yemi33/minions 0.1.384 → 0.1.386
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 +7 -1
- package/dashboard/js/render-dispatch.js +11 -6
- package/dashboard.js +76 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.386 (2026-04-06)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- cache git rev-parse in version check — was spawning every 4s
|
|
7
|
+
|
|
8
|
+
## 0.1.385 (2026-04-06)
|
|
4
9
|
|
|
5
10
|
### Features
|
|
11
|
+
- npm update check — show when newer version is available
|
|
6
12
|
- show engine version and stale-code warning in dashboard
|
|
7
13
|
|
|
8
14
|
## 0.1.383 (2026-04-06)
|
|
@@ -215,19 +215,24 @@ function renderVersionBanner(version) {
|
|
|
215
215
|
if (!el) return;
|
|
216
216
|
if (!version) { el.style.display = 'none'; return; }
|
|
217
217
|
|
|
218
|
-
|
|
219
|
-
const label = version.running ? 'v' + version.running : '';
|
|
218
|
+
const v = version.running || version.disk || '?';
|
|
220
219
|
const commitLabel = version.runningCommit ? ' (' + version.runningCommit + ')' : '';
|
|
221
|
-
el.textContent = label + commitLabel;
|
|
222
|
-
el.title = 'Engine: v' + (version.running || '?') + ' ' + (version.runningCommit || '') +
|
|
223
|
-
'\nDisk: v' + (version.disk || '?') + ' ' + (version.diskCommit || '');
|
|
224
220
|
|
|
225
221
|
if (version.stale) {
|
|
222
|
+
// Engine running old code — needs restart
|
|
226
223
|
el.style.cssText = 'font-size:9px;padding:2px 8px;background:rgba(210,153,34,0.15);border:1px solid rgba(210,153,34,0.3);border-radius:4px;color:var(--yellow);cursor:help';
|
|
227
|
-
el.textContent = '\u26A0 Engine running v' + (version.running || '?') + '
|
|
224
|
+
el.textContent = '\u26A0 Engine running v' + (version.running || '?') + ' — disk has v' + (version.disk || '?') + '. Restart to apply.';
|
|
228
225
|
el.title = 'The engine process is running older code than what is on disk. Run: minions restart';
|
|
226
|
+
} else if (version.updateAvailable) {
|
|
227
|
+
// New version on npm
|
|
228
|
+
el.style.cssText = 'font-size:9px;padding:2px 8px;background:rgba(63,185,80,0.1);border:1px solid rgba(63,185,80,0.3);border-radius:4px;color:var(--green);cursor:help';
|
|
229
|
+
el.textContent = 'v' + v + commitLabel + ' — v' + version.latest + ' available. Run: npm update -g @yemi33/minions';
|
|
230
|
+
el.title = 'A newer version is available on npm';
|
|
229
231
|
} else {
|
|
232
|
+
// Up to date
|
|
230
233
|
el.style.cssText = 'font-size:9px;color:var(--muted)';
|
|
234
|
+
el.textContent = 'v' + v + commitLabel;
|
|
235
|
+
el.title = 'Minions v' + v + (version.latest ? ' (latest)' : '');
|
|
231
236
|
}
|
|
232
237
|
}
|
|
233
238
|
|
package/dashboard.js
CHANGED
|
@@ -161,6 +161,63 @@ function getVerifyGuides() {
|
|
|
161
161
|
function getArchivedPrds() { return []; }
|
|
162
162
|
function getEngineState() { return queries.getControl(); }
|
|
163
163
|
|
|
164
|
+
// ── npm update check (cached for 4 hours) ──────────────────────────────────
|
|
165
|
+
let _npmVersionCache = null;
|
|
166
|
+
let _npmVersionCacheTs = 0;
|
|
167
|
+
const NPM_CHECK_INTERVAL = 4 * 60 * 60 * 1000; // 4 hours
|
|
168
|
+
const PKG_NAME = '@yemi33/minions';
|
|
169
|
+
|
|
170
|
+
async function checkNpmVersion() {
|
|
171
|
+
const now = Date.now();
|
|
172
|
+
if (_npmVersionCache && (now - _npmVersionCacheTs) < NPM_CHECK_INTERVAL) return _npmVersionCache;
|
|
173
|
+
try {
|
|
174
|
+
const https = require('https');
|
|
175
|
+
const data = await new Promise((resolve, reject) => {
|
|
176
|
+
const req = https.get(`https://registry.npmjs.org/${PKG_NAME}/latest`, { timeout: 5000 }, (res) => {
|
|
177
|
+
let body = '';
|
|
178
|
+
res.on('data', c => body += c);
|
|
179
|
+
res.on('end', () => { try { resolve(JSON.parse(body)); } catch { reject(new Error('bad json')); } });
|
|
180
|
+
});
|
|
181
|
+
req.on('error', reject);
|
|
182
|
+
req.on('timeout', () => { req.destroy(); reject(new Error('timeout')); });
|
|
183
|
+
});
|
|
184
|
+
_npmVersionCache = { latest: data.version || null, checkedAt: new Date().toISOString() };
|
|
185
|
+
_npmVersionCacheTs = now;
|
|
186
|
+
} catch {
|
|
187
|
+
_npmVersionCache = _npmVersionCache || { latest: null, checkedAt: null, error: 'check failed' };
|
|
188
|
+
}
|
|
189
|
+
return _npmVersionCache;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
function _compareVersions(a, b) {
|
|
193
|
+
const pa = (a || '').split('.').map(Number);
|
|
194
|
+
const pb = (b || '').split('.').map(Number);
|
|
195
|
+
for (let i = 0; i < Math.max(pa.length, pb.length); i++) {
|
|
196
|
+
if ((pa[i] || 0) > (pb[i] || 0)) return 1;
|
|
197
|
+
if ((pa[i] || 0) < (pb[i] || 0)) return -1;
|
|
198
|
+
}
|
|
199
|
+
return 0;
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
// Kick off first npm check on startup (non-blocking)
|
|
203
|
+
checkNpmVersion().catch(() => {});
|
|
204
|
+
|
|
205
|
+
// Cache disk version + git commit (only changes on deploy/pull, not per-request)
|
|
206
|
+
let _diskVersionCache = null;
|
|
207
|
+
let _diskVersionCacheTs = 0;
|
|
208
|
+
const DISK_VERSION_TTL = 60000; // re-check every 60s
|
|
209
|
+
function getDiskVersion() {
|
|
210
|
+
const now = Date.now();
|
|
211
|
+
if (_diskVersionCache && (now - _diskVersionCacheTs) < DISK_VERSION_TTL) return _diskVersionCache;
|
|
212
|
+
let diskVersion = null;
|
|
213
|
+
try { diskVersion = require('./package.json').version; } catch {}
|
|
214
|
+
let diskCommit = null;
|
|
215
|
+
try { diskCommit = require('child_process').execSync('git rev-parse --short HEAD', { cwd: MINIONS_DIR, encoding: 'utf8', timeout: 5000, windowsHide: true }).trim(); } catch {}
|
|
216
|
+
_diskVersionCache = { diskVersion, diskCommit };
|
|
217
|
+
_diskVersionCacheTs = now;
|
|
218
|
+
return _diskVersionCache;
|
|
219
|
+
}
|
|
220
|
+
|
|
164
221
|
function getMcpServers() {
|
|
165
222
|
try {
|
|
166
223
|
const home = os.homedir();
|
|
@@ -250,10 +307,7 @@ function getStatus() {
|
|
|
250
307
|
installId: safeRead(path.join(MINIONS_DIR, '.install-id')).trim() || null,
|
|
251
308
|
version: (() => {
|
|
252
309
|
const engine = getEngineState();
|
|
253
|
-
|
|
254
|
-
try { diskVersion = require('./package.json').version; } catch {}
|
|
255
|
-
let diskCommit = null;
|
|
256
|
-
try { diskCommit = require('child_process').execSync('git rev-parse --short HEAD', { cwd: MINIONS_DIR, encoding: 'utf8', timeout: 5000, windowsHide: true }).trim(); } catch {}
|
|
310
|
+
const { diskVersion, diskCommit } = getDiskVersion();
|
|
257
311
|
return {
|
|
258
312
|
running: engine.codeVersion || null,
|
|
259
313
|
runningCommit: engine.codeCommit || null,
|
|
@@ -261,6 +315,8 @@ function getStatus() {
|
|
|
261
315
|
diskCommit,
|
|
262
316
|
stale: !!(engine.codeVersion && diskVersion && engine.codeVersion !== diskVersion) ||
|
|
263
317
|
!!(engine.codeCommit && diskCommit && engine.codeCommit !== diskCommit),
|
|
318
|
+
latest: _npmVersionCache?.latest || null,
|
|
319
|
+
updateAvailable: !!(diskVersion && _npmVersionCache?.latest && _npmVersionCache.latest !== diskVersion && _compareVersions(_npmVersionCache.latest, diskVersion) > 0),
|
|
264
320
|
};
|
|
265
321
|
})(),
|
|
266
322
|
timestamp: new Date().toISOString(),
|
|
@@ -3367,6 +3423,22 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3367
3423
|
|
|
3368
3424
|
const ROUTES = [
|
|
3369
3425
|
// Routes endpoint (self-describing API)
|
|
3426
|
+
{ method: 'GET', path: '/api/version', desc: 'Current + latest version info with update check', handler: async (req, res) => {
|
|
3427
|
+
const npm = await checkNpmVersion();
|
|
3428
|
+
const { diskVersion, diskCommit } = getDiskVersion();
|
|
3429
|
+
const engine = getEngineState();
|
|
3430
|
+
return jsonReply(res, 200, {
|
|
3431
|
+
current: diskVersion,
|
|
3432
|
+
currentCommit: diskCommit,
|
|
3433
|
+
running: engine.codeVersion || null,
|
|
3434
|
+
runningCommit: engine.codeCommit || null,
|
|
3435
|
+
latest: npm.latest,
|
|
3436
|
+
updateAvailable: !!(diskVersion && npm.latest && _compareVersions(npm.latest, diskVersion) > 0),
|
|
3437
|
+
stale: !!(engine.codeVersion && diskVersion && engine.codeVersion !== diskVersion) ||
|
|
3438
|
+
!!(engine.codeCommit && diskCommit && engine.codeCommit !== diskCommit),
|
|
3439
|
+
checkedAt: npm.checkedAt,
|
|
3440
|
+
});
|
|
3441
|
+
}},
|
|
3370
3442
|
{ method: 'GET', path: '/api/routes', desc: 'List all available API endpoints', handler: (req, res) => {
|
|
3371
3443
|
const list = ROUTES.map(r => ({
|
|
3372
3444
|
method: r.method,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.386",
|
|
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"
|