@yemi33/minions 0.1.384 → 0.1.385
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 +2 -1
- package/dashboard/js/render-dispatch.js +11 -6
- package/dashboard.js +57 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -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,47 @@ 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
|
+
|
|
164
205
|
function getMcpServers() {
|
|
165
206
|
try {
|
|
166
207
|
const home = os.homedir();
|
|
@@ -261,6 +302,8 @@ function getStatus() {
|
|
|
261
302
|
diskCommit,
|
|
262
303
|
stale: !!(engine.codeVersion && diskVersion && engine.codeVersion !== diskVersion) ||
|
|
263
304
|
!!(engine.codeCommit && diskCommit && engine.codeCommit !== diskCommit),
|
|
305
|
+
latest: _npmVersionCache?.latest || null,
|
|
306
|
+
updateAvailable: !!(diskVersion && _npmVersionCache?.latest && _npmVersionCache.latest !== diskVersion && _compareVersions(_npmVersionCache.latest, diskVersion) > 0),
|
|
264
307
|
};
|
|
265
308
|
})(),
|
|
266
309
|
timestamp: new Date().toISOString(),
|
|
@@ -3367,6 +3410,20 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3367
3410
|
|
|
3368
3411
|
const ROUTES = [
|
|
3369
3412
|
// Routes endpoint (self-describing API)
|
|
3413
|
+
{ method: 'GET', path: '/api/version', desc: 'Current + latest version info with update check', handler: async (req, res) => {
|
|
3414
|
+
const npm = await checkNpmVersion();
|
|
3415
|
+
let diskVersion = null;
|
|
3416
|
+
try { diskVersion = require('./package.json').version; } catch {}
|
|
3417
|
+
const engine = getEngineState();
|
|
3418
|
+
return jsonReply(res, 200, {
|
|
3419
|
+
current: diskVersion,
|
|
3420
|
+
running: engine.codeVersion || null,
|
|
3421
|
+
latest: npm.latest,
|
|
3422
|
+
updateAvailable: !!(diskVersion && npm.latest && _compareVersions(npm.latest, diskVersion) > 0),
|
|
3423
|
+
stale: !!(engine.codeVersion && diskVersion && engine.codeVersion !== diskVersion),
|
|
3424
|
+
checkedAt: npm.checkedAt,
|
|
3425
|
+
});
|
|
3426
|
+
}},
|
|
3370
3427
|
{ method: 'GET', path: '/api/routes', desc: 'List all available API endpoints', handler: (req, res) => {
|
|
3371
3428
|
const list = ROUTES.map(r => ({
|
|
3372
3429
|
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.385",
|
|
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"
|