@yemi33/minions 0.1.1048 → 0.1.1050

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,16 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1048 (2026-04-17)
3
+ ## 0.1.1050 (2026-04-17)
4
+
5
+ ### Features
6
+ - seed realActivityMap at spawn time, stamp pid in live-output (#1200)
4
7
 
5
8
  ### Fixes
6
9
  - stamp live-output.log stub before spawn (#1198)
7
10
  - harden settings save and migrate pr poll config
8
11
 
9
12
  ### Other
13
+ - chore: raise default meeting round timeout
10
14
  - Harden prompt context handling
11
15
  - Harden loop watch conversion
12
16
  - Add watches sidebar activity badge
@@ -45,7 +45,7 @@ async function openSettings() {
45
45
  settingsField('Idle Alert', 'set-idleAlertMinutes', e.idleAlertMinutes || 15, 'min', 'Alert after agent idle this long') +
46
46
  settingsField('Shutdown Timeout', 'set-shutdownTimeout', e.shutdownTimeout || 300000, 'ms', 'Max wait for agents during graceful shutdown') +
47
47
  settingsField('Restart Grace Period', 'set-restartGracePeriod', e.restartGracePeriod || 1200000, 'ms', 'Grace period before orphan detection on restart') +
48
- settingsField('Meeting Round Timeout', 'set-meetingRoundTimeout', e.meetingRoundTimeout || 600000, 'ms', 'Auto-advance meeting round after this') +
48
+ settingsField('Meeting Round Timeout', 'set-meetingRoundTimeout', e.meetingRoundTimeout || 900000, 'ms', 'Auto-advance meeting round after this') +
49
49
  '</div>' +
50
50
  '<div style="display:flex;flex-direction:column;gap:6px;margin-bottom:16px">' +
51
51
  settingsToggle('Auto-approve Plans', 'set-autoApprovePlans', !!e.autoApprovePlans, 'PRDs are approved automatically without human review') +
package/engine/shared.js CHANGED
@@ -695,7 +695,7 @@ const ENGINE_DEFAULTS = {
695
695
  autoArchive: false, // opt-in: auto-archive plans after verify completes (false = mark ready, user archives manually)
696
696
  autoFixConflicts: true, // auto-dispatch fix agents when a PR has merge conflicts
697
697
  autoFixBuilds: true, // auto-dispatch fix agents when a PR build fails
698
- meetingRoundTimeout: 600000, // 10min per meeting round before auto-advance
698
+ meetingRoundTimeout: 900000, // 15min per meeting round before auto-advance
699
699
  evalLoop: true, // enable review→fix loop after implementation completes
700
700
  evalMaxIterations: 3, // max review→fix cycles before escalating to human
701
701
  evalMaxCost: null, // USD ceiling per work item across all eval iterations; null = no limit (gather baseline data first)
package/engine/timeout.js CHANGED
@@ -308,15 +308,33 @@ function checkTimeouts(config) {
308
308
  const procInfo = activeProcesses.get(item.id);
309
309
  if (procInfo?._steeringAt && Date.now() - procInfo._steeringAt < 60000) continue;
310
310
 
311
- // Capture live-output.log file state for orphan/hung diagnostics (#W-mo248lkjwgsu).
312
- // Three distinguishable failure modes:
313
- // logExists=false → spawn call itself threw, no log ever written
314
- // logExists=true, size~stub process died at startup (stub-only content)
315
- // logExists=true, size>stub genuine hang (process alive, wrote output, then stopped)
316
- let _logState = 'logExists=false logSize=0';
311
+ // Capture live-output.log file state for orphan/hung diagnostics
312
+ // (#W-mo248lkjwgsu original, #W-mo25loq8kjer pid annotation).
313
+ // Four distinguishable failure modes:
314
+ // logExists=false → spawn call itself threw, no log ever written
315
+ // logExists=true pidPresent=false → engine stub written but spawn died before emitting pid line
316
+ // logExists=true pidPresent=true silent → process spawned (pid recorded) but never produced stdout
317
+ // logExists=true pidPresent=true size>pid → genuine hang (process wrote output then stopped)
318
+ //
319
+ // The pid line `[<iso>] pid: <N>` is stamped by engine.js immediately after runFile() returns.
320
+ // Its presence → the child process was actually spawned; absence → spawn itself failed or the
321
+ // appendFileSync on the pid line threw (rare).
322
+ let _logState = 'logExists=false logSize=0 pidPresent=false';
317
323
  try {
318
324
  const lst = fs.statSync(liveLogPath);
319
- _logState = `logExists=true logSize=${lst.size}`;
325
+ // Read only the head (4KB) — pid line is written right after the stub, always near the top.
326
+ // Avoids loading the full log just for a diagnostic annotation.
327
+ let pidPresent = false;
328
+ try {
329
+ const fd = fs.openSync(liveLogPath, 'r');
330
+ const headSize = Math.min(lst.size, 4096);
331
+ const headBuf = Buffer.alloc(headSize);
332
+ fs.readSync(fd, headBuf, 0, headSize, 0);
333
+ fs.closeSync(fd);
334
+ // Match `] pid: <digits>` — agnostic to ISO timestamp format at the start.
335
+ pidPresent = /\]\s+pid:\s+\d+/.test(headBuf.toString('utf8'));
336
+ } catch { /* read failure — pidPresent stays false */ }
337
+ _logState = `logExists=true logSize=${lst.size} pidPresent=${pidPresent}`;
320
338
  } catch { /* ENOENT — keep default */ }
321
339
 
322
340
  if (!hasProcess && silentMs > effectiveTimeout && (Date.now() > engineRestartGraceUntil || engineRestartGraceExempt?.has(item.id))) {
package/engine.js CHANGED
@@ -916,6 +916,23 @@ async function spawnAgent(dispatchItem, config) {
916
916
  throw spawnErr;
917
917
  }
918
918
 
919
+ // Seed realActivityMap and stamp PID immediately — BEFORE any handlers or timers (#W-mo25loq8kjer).
920
+ // Why NOW, not later in the function:
921
+ // 1. Heartbeat clock anchoring. timeout.js uses realActivityMap as the last-activity timestamp for
922
+ // tracked processes; when the map has no entry, it falls back to item.started_at (dispatch time,
923
+ // which is 20-60s before actual spawn for write tasks doing worktree setup). Read-only tasks
924
+ // that produce no stdout for minutes (explore, security audit, large scans) were hitting
925
+ // heartbeatTimeout prematurely — clock had already been running since dispatch.
926
+ // 2. Error-handler race. The `proc.on('error', ...)` handler below calls realActivityMap.delete(id)
927
+ // on synchronous spawn failures. Seeding before registering handlers ensures delete sees a value
928
+ // to clear rather than leaving an absent-then-absent no-op that downstream code must guard.
929
+ // 3. Orphan diagnostics. The PID line gives timeout.js a deterministic way to tell "spawn died
930
+ // before first write" (stub-only log) from "process started and is hung" (stub + pid line).
931
+ realActivityMap.set(id, Date.now());
932
+ try {
933
+ fs.appendFileSync(liveOutputPath, `[${new Date().toISOString()}] pid: ${proc.pid ?? 'unknown'}\n`);
934
+ } catch { /* log stamp is best-effort — don't block spawn on fs failure */ }
935
+
919
936
  const MAX_OUTPUT = 1024 * 1024; // 1MB
920
937
  let stdout = '';
921
938
  let stderr = '';
@@ -1292,9 +1309,11 @@ async function spawnAgent(dispatchItem, config) {
1292
1309
  }
1293
1310
  }, 3000);
1294
1311
 
1295
- // Track process — even if PID isn't available yet (async on Windows)
1312
+ // Track process — even if PID isn't available yet (async on Windows).
1313
+ // realActivityMap was already seeded immediately after runFile() returned (#W-mo25loq8kjer);
1314
+ // don't re-seed here — the stdout/stderr handlers above can already have updated it with
1315
+ // a fresher timestamp, and overwriting would clobber the real "last activity" signal.
1296
1316
  activeProcesses.set(id, { proc, agentId, startedAt, sessionId: cachedSessionId });
1297
- realActivityMap.set(id, Date.now()); // Initialize real activity at spawn time
1298
1317
 
1299
1318
  updateAgentStatus(id, AGENT_STATUS.RUNNING, `Process spawned for ${agentId}`);
1300
1319
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1048",
3
+ "version": "0.1.1050",
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"