@yemi33/minions 0.1.316 → 0.1.317

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.316 (2026-04-03)
3
+ ## 0.1.317 (2026-04-03)
4
4
 
5
5
  ### Fixes
6
6
  - deduplicate PRs in pull-requests.json on write
7
7
  - show reviewer names in dashboard Signed Off By column
8
8
 
9
9
  ### Other
10
+ - refactor: use constants in lifecycle.js and timeout.js
10
11
  - refactor: extract status/type/result constants to shared.js
11
12
  - cleanup: remove evaluate.md (re-created by agents), fix stale references
12
13
  - perf: CC message handling — debounce localStorage, cap array, batch scroll
@@ -1263,15 +1263,16 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
1263
1263
  wi.noPr = true;
1264
1264
  wi.failReason = 'Completed without creating a pull request';
1265
1265
  const retries = wi._retryCount || 0;
1266
- if (retries < 3) {
1267
- wi.status = 'pending';
1266
+ const maxR = ENGINE_DEFAULTS.maxRetries;
1267
+ if (retries < maxR) {
1268
+ wi.status = WI_STATUS.PENDING;
1268
1269
  wi._retryCount = retries + 1;
1269
1270
  delete wi.dispatched_at;
1270
1271
  delete wi.dispatched_to;
1271
- e.log('info', `Auto-retry ${retries + 1}/3 for ${meta.item.id} (no PR created)`);
1272
+ e.log('info', `Auto-retry ${retries + 1}/${maxR} for ${meta.item.id} (no PR created)`);
1272
1273
  } else {
1273
- wi.status = 'failed';
1274
- e.log('warn', `${meta.item.id} failed after 3 retries — no PR created`);
1274
+ wi.status = WI_STATUS.FAILED;
1275
+ e.log('warn', `${meta.item.id} failed after ${maxR} retries — no PR created`);
1275
1276
  }
1276
1277
  shared.safeWrite(wiPath, items);
1277
1278
  }
package/engine/timeout.js CHANGED
@@ -8,7 +8,8 @@ const path = require('path');
8
8
  const shared = require('./shared');
9
9
  const queries = require('./queries');
10
10
 
11
- const { safeRead, safeWrite, safeJson, getProjects, projectWorkItemsPath, log, ts, ENGINE_DEFAULTS: DEFAULTS } = shared;
11
+ const { safeRead, safeWrite, safeJson, getProjects, projectWorkItemsPath, log, ts,
12
+ ENGINE_DEFAULTS: DEFAULTS, WI_STATUS, DISPATCH_RESULT } = shared;
12
13
  const { getDispatch, getAgentStatus } = queries;
13
14
  const AGENTS_DIR = queries.AGENTS_DIR;
14
15
  const MINIONS_DIR = shared.MINIONS_DIR;
@@ -140,7 +141,7 @@ function checkTimeouts(config) {
140
141
  safeWrite(outputLogPath, `# Output for dispatch ${item.id}\n# Exit code: ${isSuccess ? 0 : 1}\n# Completed: ${ts()}\n# Detected via output scan\n\n## Result\n${text || '(no text)'}\n`);
141
142
  } catch (e) { log('warn', 'parse output result: ' + e.message); }
142
143
 
143
- completeDispatch(item.id, isSuccess ? 'success' : 'error', 'Completed (detected from output)');
144
+ completeDispatch(item.id, isSuccess ? DISPATCH_RESULT.SUCCESS : DISPATCH_RESULT.ERROR, 'Completed (detected from output)');
144
145
 
145
146
  // Run post-completion hooks via shared helper
146
147
  runPostCompletionHooks(item, item.agent, isSuccess ? 0 : 1, liveLog, config);
@@ -215,7 +216,7 @@ function checkTimeouts(config) {
215
216
 
216
217
  // Clean up dead items
217
218
  for (const { item, reason } of deadItems) {
218
- completeDispatch(item.id, 'error', reason);
219
+ completeDispatch(item.id, DISPATCH_RESULT.ERROR, reason);
219
220
  }
220
221
 
221
222
  // Agent status is now derived from dispatch.json at read time (getAgentStatus).
@@ -232,7 +233,7 @@ function checkTimeouts(config) {
232
233
  if (!items || !Array.isArray(items)) continue;
233
234
  let changed = false;
234
235
  for (const item of items) {
235
- if (item.status !== 'dispatched') continue;
236
+ if (item.status !== WI_STATUS.DISPATCHED) continue;
236
237
  // Check if any active dispatch references this item
237
238
  // Dispatch keys include project name: work-{project}-{id} or central-work-{id}
238
239
  const projectNames = getProjects(config).map(p => p.name);
@@ -244,19 +245,20 @@ function checkTimeouts(config) {
244
245
  (dispatchData.active || []).some(d => d.meta?.item?.id === item.id);
245
246
  if (!isActive) {
246
247
  // Don't revive items that were explicitly failed for non-retryable reasons
247
- if (item.status === 'failed' && item.failReason && !item.failReason.includes('Agent died')) continue;
248
+ if (item.status === WI_STATUS.FAILED && item.failReason && !item.failReason.includes('Agent died')) continue;
248
249
  const retries = (item._retryCount || 0);
249
- if (retries < 3) {
250
- log('info', `Reconcile: work item ${item.id} agent died — auto-retry ${retries + 1}/3`);
251
- item.status = 'pending';
250
+ const maxRetries = DEFAULTS.maxRetries;
251
+ if (retries < maxRetries) {
252
+ log('info', `Reconcile: work item ${item.id} agent died — auto-retry ${retries + 1}/${maxRetries}`);
253
+ item.status = WI_STATUS.PENDING;
252
254
  item._retryCount = retries + 1;
253
255
  delete item.dispatched_at;
254
256
  delete item.dispatched_to;
255
257
  delete item._pendingReason;
256
258
  } else {
257
259
  log('warn', `Reconcile: work item ${item.id} failed after ${retries} retries — marking as failed`);
258
- item.status = 'failed';
259
- item.failReason = 'Agent died or was killed (3 retries exhausted)';
260
+ item.status = WI_STATUS.FAILED;
261
+ item.failReason = `Agent died or was killed (${maxRetries} retries exhausted)`;
260
262
  item.failedAt = ts();
261
263
  delete item._pendingReason;
262
264
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.316",
3
+ "version": "0.1.317",
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"