@yemi33/minions 0.1.471 → 0.1.473
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 +3 -1
- package/dashboard/js/render-agents.js +5 -2
- package/engine/queries.js +3 -1
- package/engine/timeout.js +4 -5
- package/engine.js +2 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.473 (2026-04-07)
|
|
4
4
|
|
|
5
5
|
### Fixes
|
|
6
|
+
- agent card click feels instant — show panel before API loads
|
|
7
|
+
- steering audit — prevent double-kill, clean up temp files, fix leaks
|
|
6
8
|
- steering resume improvements — better error logging, heartbeat restart
|
|
7
9
|
- prevent slow work item modal on large descriptions
|
|
8
10
|
- only cache sessionId for steering when actually resuming same branch
|
|
@@ -33,6 +33,11 @@ async function openAgentDetail(id) {
|
|
|
33
33
|
'<span style="color:var(--muted)">' + escHtml(agent.lastAction) + '</span>' +
|
|
34
34
|
(agent.resultSummary ? '<div style="margin-top:4px;font-size:11px;color:var(--text);line-height:1.4">' + renderMd(agent.resultSummary.slice(0, 300)) + '</div>' : '');
|
|
35
35
|
|
|
36
|
+
// Show panel immediately with loading state — don't wait for API
|
|
37
|
+
document.getElementById('detail-content').innerHTML = '<div style="padding:24px;text-align:center;color:var(--muted)">Loading...</div>';
|
|
38
|
+
document.getElementById('detail-overlay').classList.add('open');
|
|
39
|
+
document.getElementById('detail-panel').classList.add('open');
|
|
40
|
+
|
|
36
41
|
try {
|
|
37
42
|
const detail = await safeFetch('/api/agent/' + id).then(r => r.json());
|
|
38
43
|
renderDetailTabs(detail);
|
|
@@ -46,8 +51,6 @@ async function openAgentDetail(id) {
|
|
|
46
51
|
'</div>';
|
|
47
52
|
}
|
|
48
53
|
|
|
49
|
-
document.getElementById('detail-overlay').classList.add('open');
|
|
50
|
-
document.getElementById('detail-panel').classList.add('open');
|
|
51
54
|
}
|
|
52
55
|
|
|
53
56
|
window.MinionsAgents = { renderAgents, openAgentDetail };
|
package/engine/queries.js
CHANGED
|
@@ -254,7 +254,9 @@ function getAgentDetail(id) {
|
|
|
254
254
|
const agentDir = path.join(AGENTS_DIR, id);
|
|
255
255
|
const charter = safeRead(path.join(agentDir, 'charter.md')) || 'No charter found.';
|
|
256
256
|
const history = safeRead(path.join(agentDir, 'history.md')) || 'No history yet.';
|
|
257
|
-
|
|
257
|
+
// Only send last 50KB of output.log — full logs can be megabytes and slow down the API
|
|
258
|
+
let outputLog = safeRead(path.join(agentDir, 'output.log')) || '';
|
|
259
|
+
if (outputLog.length > 50000) outputLog = '…(truncated — showing last 50KB)\n\n' + outputLog.slice(-50000);
|
|
258
260
|
|
|
259
261
|
const statusData = getAgentStatus(id); // derives from dispatch.json
|
|
260
262
|
|
package/engine/timeout.js
CHANGED
|
@@ -57,18 +57,19 @@ function checkIdleThreshold(config) {
|
|
|
57
57
|
function checkSteering(config) {
|
|
58
58
|
const activeProcesses = engine().activeProcesses;
|
|
59
59
|
for (const [id, info] of activeProcesses) {
|
|
60
|
+
// Skip if already being steered (prevents double-kill race)
|
|
61
|
+
if (info._steeringMessage || info._steeringAt) continue;
|
|
62
|
+
|
|
60
63
|
const steerPath = path.join(AGENTS_DIR, info.agentId, 'steer.md');
|
|
61
64
|
let steerMtime;
|
|
62
65
|
try { steerMtime = fs.statSync(steerPath).mtimeMs; } catch { continue; } // ENOENT = no steering message
|
|
63
66
|
|
|
64
67
|
const sessionId = info.sessionId;
|
|
65
68
|
if (!sessionId) {
|
|
66
|
-
// No sessionId yet — check stale (>5 min means it'll never arrive)
|
|
67
69
|
if (Date.now() - steerMtime > 300000) {
|
|
68
70
|
log('warn', `Steering: no sessionId for ${info.agentId} after 5m — deleting stale message`);
|
|
69
71
|
try { fs.unlinkSync(steerPath); } catch {}
|
|
70
72
|
}
|
|
71
|
-
// Leave steer.md in place — retry next tick when sessionId may be available
|
|
72
73
|
continue;
|
|
73
74
|
}
|
|
74
75
|
|
|
@@ -78,13 +79,11 @@ function checkSteering(config) {
|
|
|
78
79
|
|
|
79
80
|
log('info', `Steering: killing ${info.agentId} (${id}) for session resume with human message`);
|
|
80
81
|
|
|
81
|
-
// Kill current process
|
|
82
82
|
shared.killImmediate(info.proc);
|
|
83
83
|
|
|
84
|
-
// Store steering context for re-spawn on close
|
|
85
84
|
info._steeringMessage = message;
|
|
86
85
|
info._steeringSessionId = sessionId;
|
|
87
|
-
info._steeringAt = Date.now();
|
|
86
|
+
info._steeringAt = Date.now();
|
|
88
87
|
}
|
|
89
88
|
}
|
|
90
89
|
|
package/engine.js
CHANGED
|
@@ -631,10 +631,11 @@ function spawnAgent(dispatchItem, config) {
|
|
|
631
631
|
|
|
632
632
|
// Re-wire close handler for the resumed process
|
|
633
633
|
resumeProc.on('close', (resumeCode) => {
|
|
634
|
+
if (heartbeatTimer) { clearInterval(heartbeatTimer); heartbeatTimer = null; }
|
|
635
|
+
try { fs.unlinkSync(steerPromptPath); } catch { /* cleanup */ }
|
|
634
636
|
if (resumeCode !== 0) {
|
|
635
637
|
log('warn', `Steering resume for ${agentId} exited with code ${resumeCode} | stderr: ${stderr.slice(-300).replace(/\n/g, ' ')}`);
|
|
636
638
|
activeProcesses.delete(id);
|
|
637
|
-
// Don't burn a retry slot — complete as success so work item stays done/dispatched
|
|
638
639
|
completeDispatch(id, DISPATCH_RESULT.SUCCESS, 'Steering resume failed but original work completed', '', { processWorkItemFailure: false });
|
|
639
640
|
return;
|
|
640
641
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.473",
|
|
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"
|