@yemi33/minions 0.1.1601 → 0.1.1602

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 CHANGED
@@ -1,12 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1601 (2026-04-28)
3
+ ## 0.1.1602 (2026-04-28)
4
4
 
5
5
  ### Features
6
6
  - match runtime tags to actual logos (pixel-crab Claude, mascot Copilot)
7
7
  - replace runtime text tag with inline SVG logos
8
8
 
9
9
  ### Fixes
10
+ - guard runtime model races
10
11
  - runtime-aware model picker + cross-runtime validation
11
12
  - keep cc stream final text complete
12
13
  - switch Copilot icon to outline style for cleaner inline read
@@ -1,6 +1,25 @@
1
1
  // settings.js — Settings panel functions extracted from dashboard.html
2
2
 
3
3
  let _settingsData = null;
4
+ // Async runtime/model discovery can resolve out of order when the operator
5
+ // flips between runtimes quickly. Without a per-target token, a slower Copilot
6
+ // response can repaint the Claude model field after the runtime already
7
+ // changed, which then leaks a stale cross-runtime model into saveSettings().
8
+ const _modelLoadEpochs = {
9
+ runtime: Object.create(null),
10
+ agent: Object.create(null),
11
+ };
12
+
13
+ function _nextModelLoadToken(scope, key) {
14
+ const bucket = _modelLoadEpochs[scope];
15
+ const next = (bucket[key] || 0) + 1;
16
+ bucket[key] = next;
17
+ return next;
18
+ }
19
+
20
+ function _isCurrentModelLoad(scope, key, token) {
21
+ return _modelLoadEpochs[scope][key] === token;
22
+ }
4
23
 
5
24
  async function openSettings() {
6
25
  document.getElementById('modal-title').textContent = 'Settings';
@@ -400,6 +419,7 @@ async function initRuntimeFleetUI(engineCfg, agentsCfg) {
400
419
  async function loadModelsForRuntime(runtimeName, inputId, currentValue) {
401
420
  const wrap = document.getElementById(inputId)?.parentElement;
402
421
  if (!wrap) return;
422
+ const token = _nextModelLoadToken('runtime', inputId);
403
423
  if (!runtimeName) {
404
424
  wrap.innerHTML = '<input id="' + inputId + '" value="' + escHtml(currentValue || '') + '" placeholder="(no runtime selected)" disabled style="width:100%;padding:4px 6px;background:var(--surface);border:1px solid var(--border);border-radius:4px;color:var(--muted);font-size:12px">';
405
425
  return;
@@ -410,6 +430,7 @@ async function loadModelsForRuntime(runtimeName, inputId, currentValue) {
410
430
  if (res.ok) payload = await res.json();
411
431
  } catch { /* fall through to free-text */ }
412
432
 
433
+ if (!_isCurrentModelLoad('runtime', inputId, token)) return;
413
434
  const models = Array.isArray(payload.models) ? payload.models : null;
414
435
  if (!models || models.length === 0) {
415
436
  // Free-text fallback — let the user type anything (custom Anthropic /
@@ -445,6 +466,7 @@ async function loadModelsForAgent(agentId, runtimeName, currentValue) {
445
466
  if (!cell) return;
446
467
  const baseAttrs = 'data-agent="' + escHtml(agentId) + '" data-field="model"';
447
468
  const baseStyle = 'width:120px;padding:4px 6px;background:var(--surface);border:1px solid var(--border);border-radius:4px;color:var(--text);font-size:11px';
469
+ const token = _nextModelLoadToken('agent', agentId);
448
470
  if (!runtimeName) {
449
471
  cell.innerHTML = '<input ' + baseAttrs + ' value="' + escHtml(currentValue || '') + '" placeholder="(no runtime)" disabled style="' + baseStyle + ';color:var(--muted)">';
450
472
  return;
@@ -455,6 +477,7 @@ async function loadModelsForAgent(agentId, runtimeName, currentValue) {
455
477
  if (res.ok) payload = await res.json();
456
478
  } catch { /* fall through to free-text */ }
457
479
 
480
+ if (!_isCurrentModelLoad('agent', agentId, token)) return;
458
481
  const models = Array.isArray(payload.models) ? payload.models : null;
459
482
  if (!models || models.length === 0) {
460
483
  cell.innerHTML = '<input ' + baseAttrs + ' value="' + escHtml(currentValue || '') + '" placeholder="' + escHtml(runtimeName) + ' default" style="' + baseStyle + '">';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1601",
3
+ "version": "0.1.1602",
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"