@yemi33/minions 0.1.462 → 0.1.464

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,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.464 (2026-04-07)
4
+
5
+ ### Fixes
6
+ - extend heartbeat timeout for any Bash tool call (10min default)
7
+ - clear stale session.json on resume failure, hang kill, and orphan
8
+
3
9
  ## 0.1.462 (2026-04-07)
4
10
 
5
11
  ### Fixes
package/engine/timeout.js CHANGED
@@ -187,9 +187,11 @@ function checkTimeouts(config) {
187
187
  blockingTimeout = Math.max(heartbeatTimeout, taskTimeout + 60000); // task timeout + 1min grace
188
188
  isBlocking = true;
189
189
  }
190
- // Bash with explicit long timeout (>5min)
191
- if (name === 'Bash' && input.timeout && input.timeout > heartbeatTimeout) {
192
- blockingTimeout = Math.max(heartbeatTimeout, input.timeout + 60000);
190
+ // Bash tool call — may be running a long build/install with no stdout
191
+ if (name === 'Bash') {
192
+ // Use explicit timeout if set, otherwise default to 10min for any Bash call
193
+ const bashTimeout = input.timeout || 600000;
194
+ blockingTimeout = Math.max(heartbeatTimeout, bashTimeout + 60000);
193
195
  isBlocking = true;
194
196
  }
195
197
  break; // only check the most recent tool_use
@@ -211,6 +213,8 @@ function checkTimeouts(config) {
211
213
  if (!hasProcess && silentMs > effectiveTimeout && Date.now() > engineRestartGraceUntil) {
212
214
  // No tracked process AND no recent output past effective timeout AND grace period expired → orphaned
213
215
  log('warn', `Orphan detected: ${item.agent} (${item.id}) — no process tracked, silent for ${silentSec}s${isBlocking ? ' (blocking timeout exceeded)' : ''}`);
216
+ // Clear session so retry starts fresh
217
+ try { shared.safeUnlink(path.join(AGENTS_DIR, item.agent, 'session.json')); } catch {}
214
218
  deadItems.push({ item, reason: `Orphaned — no process, silent for ${silentSec}s` });
215
219
  } else if (hasProcess && silentMs > effectiveTimeout) {
216
220
  // Has process but no output past effective timeout → hung
@@ -220,6 +224,8 @@ function checkTimeouts(config) {
220
224
  shared.killGracefully(procInfo.proc, 5000);
221
225
  activeProcesses.delete(item.id);
222
226
  }
227
+ // Clear session so retry starts fresh instead of resuming the killed session
228
+ try { shared.safeUnlink(path.join(AGENTS_DIR, item.agent, 'session.json')); } catch {}
223
229
  deadItems.push({ item, reason: `Hung — no output for ${silentSec}s` });
224
230
  }
225
231
  // If has process and recent output → healthy, let it run
package/engine.js CHANGED
@@ -562,6 +562,12 @@ function spawnAgent(dispatchItem, config) {
562
562
  if (heartbeatTimer) { clearInterval(heartbeatTimer); heartbeatTimer = null; }
563
563
  log('info', `Agent ${agentId} (${id}) exited with code ${code}`);
564
564
 
565
+ // Clear stale session if resume failed — prevents burning all retries on the same bad session
566
+ if (code !== 0 && cachedSessionId && stderr.includes('No conversation found')) {
567
+ log('warn', `Stale session ${cachedSessionId} for ${agentId} — clearing session.json`);
568
+ try { shared.safeUnlink(path.join(AGENTS_DIR, agentId, 'session.json')); } catch {}
569
+ }
570
+
565
571
  // Check if this was a steering kill — re-spawn with resume
566
572
  const procInfo = activeProcesses.get(id);
567
573
  if (procInfo?._steeringMessage) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.462",
3
+ "version": "0.1.464",
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"