@yemi33/minions 0.1.451 → 0.1.453

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,11 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.451 (2026-04-07)
3
+ ## 0.1.453 (2026-04-07)
4
4
 
5
5
  ### Features
6
6
  - notification dot on Notes & KB sidebar when sweep completes/fails
7
7
 
8
8
  ### Fixes
9
+ - wrap inbox writes in try-catch on both meeting conclusion paths
10
+ - remove duplicate retry logic causing dispatch double-queueing
9
11
  - plan archive/unarchive now optimistic — immediate UI feedback
10
12
  - meeting conclude timeout synthesizes conclusion instead of null
11
13
  - track ADO head commit for push detection — unblocks re-review cycle
@@ -1189,52 +1189,18 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
1189
1189
  meta._agentId = agentId;
1190
1190
  updateWorkItemStatus(meta, WI_STATUS.DONE, '');
1191
1191
  }
1192
- if (!effectiveSuccess && meta?.item?.id) {
1193
- // Auto-retry: read fresh _retryCount from file (not stale dispatch-time snapshot)
1194
- let retries = (meta.item._retryCount || 0);
1192
+ // Failure retry is handled by completeDispatch in dispatch.js — not duplicated here.
1193
+ // Only clear _decomposing flag on failure so decompose items don't get permanently stuck.
1194
+ if (!effectiveSuccess && meta?.item?.id && type === WORK_TYPE.DECOMPOSE) {
1195
1195
  const wiPath = resolveWorkItemPath(meta);
1196
- try {
1197
- if (wiPath) {
1198
- const items = safeJson(wiPath) || [];
1199
- const wi = items.find(i => i.id === meta.item.id);
1200
- if (wi) retries = (wi._retryCount || 0); // Use fresh value from file
1201
- }
1202
- } catch { /* optional */ }
1203
-
1204
- if (retries < ENGINE_DEFAULTS.maxRetries) {
1205
- log('info', `Agent failed for ${meta.item.id} — auto-retry ${retries + 1}/${ENGINE_DEFAULTS.maxRetries}`);
1206
- updateWorkItemStatus(meta, WI_STATUS.PENDING, '');
1196
+ if (wiPath) {
1207
1197
  try {
1208
- if (wiPath) {
1209
- mutateJsonFileLocked(wiPath, data => {
1210
- if (!Array.isArray(data)) return data;
1211
- const wi = data.find(i => i.id === meta.item.id);
1212
- if (!wi) return data;
1213
- // Don't revert if already completed by another code path
1214
- if (wi.status === WI_STATUS.DONE || wi.completedAt) {
1215
- log('info', `Skip retry for ${meta.item.id} — already completed`);
1216
- return data;
1217
- }
1218
- wi._retryCount = retries + 1; wi.status = WI_STATUS.PENDING; delete wi.dispatched_at; delete wi.dispatched_to; delete wi.failReason;
1219
- if (type === WORK_TYPE.DECOMPOSE) delete wi._decomposing;
1220
- return data;
1221
- });
1222
- }
1223
- } catch (err) { log('warn', `Retry update: ${err.message}`); }
1224
- } else {
1225
- updateWorkItemStatus(meta, WI_STATUS.FAILED, `Agent failed (${ENGINE_DEFAULTS.maxRetries} retries exhausted)`);
1226
- }
1227
- // Clear _decomposing flag on failure so item doesn't get permanently stuck
1228
- if (type === WORK_TYPE.DECOMPOSE) {
1229
- try {
1230
- if (wiPath) {
1231
- mutateJsonFileLocked(wiPath, data => {
1232
- if (!Array.isArray(data)) return data;
1233
- const wi = data.find(i => i.id === meta.item.id);
1234
- if (wi) delete wi._decomposing;
1235
- return data;
1236
- });
1237
- }
1198
+ mutateJsonFileLocked(wiPath, data => {
1199
+ if (!Array.isArray(data)) return data;
1200
+ const wi = data.find(i => i.id === meta.item.id);
1201
+ if (wi) delete wi._decomposing;
1202
+ return data;
1203
+ });
1238
1204
  } catch (err) { log('warn', `Decompose cleanup: ${err.message}`); }
1239
1205
  }
1240
1206
  }
package/engine/meeting.js CHANGED
@@ -221,12 +221,14 @@ function collectMeetingFindings(meetingId, agentId, roundName, output) {
221
221
  meeting.completedAt = new Date().toISOString();
222
222
 
223
223
  // Write transcript to inbox so agents learn from it (slug-based dedup)
224
- const config = queries.getConfig();
225
- const agents = config.agents || {};
226
- const transcript = meeting.transcript.map(t =>
227
- `### ${agents[t.agent]?.name || t.agent} (${t.type}, Round ${t.round})\n\n${t.content}`
228
- ).join('\n\n---\n\n');
229
- shared.writeToInbox('meeting', meetingId, `# Meeting Transcript: ${meeting.title}\n\n${transcript}`);
224
+ try {
225
+ const config = queries.getConfig();
226
+ const agents = config.agents || {};
227
+ const transcript = meeting.transcript.map(t =>
228
+ `### ${agents[t.agent]?.name || t.agent} (${t.type}, Round ${t.round})\n\n${t.content}`
229
+ ).join('\n\n---\n\n');
230
+ shared.writeToInbox('meeting', meetingId, `# Meeting Transcript: ${meeting.title}\n\n${transcript}`);
231
+ } catch (e) { log('warn', `Meeting ${meetingId} inbox write: ${e.message}`); }
230
232
 
231
233
  log('info', `Meeting ${meetingId} completed — transcript written to inbox`);
232
234
  saveMeeting(meeting);
@@ -390,11 +392,13 @@ function checkMeetingTimeouts(config) {
390
392
  meeting.completedAt = new Date().toISOString();
391
393
 
392
394
  // Write transcript to inbox (same as normal conclusion path)
393
- const agents = config.agents || {};
394
- const transcript = meeting.transcript.map(t =>
395
- `### ${agents[t.agent]?.name || t.agent} (${t.type}, Round ${t.round})\n\n${t.content}`
396
- ).join('\n\n---\n\n');
397
- shared.writeToInbox('meeting', meeting.id, `# Meeting Transcript: ${meeting.title}\n\n${transcript}`);
395
+ try {
396
+ const agents = config.agents || {};
397
+ const transcript = meeting.transcript.map(t =>
398
+ `### ${agents[t.agent]?.name || t.agent} (${t.type}, Round ${t.round})\n\n${t.content}`
399
+ ).join('\n\n---\n\n');
400
+ shared.writeToInbox('meeting', meeting.id, `# Meeting Transcript: ${meeting.title}\n\n${transcript}`);
401
+ } catch (e) { log('warn', `Meeting ${meeting.id} inbox write: ${e.message}`); }
398
402
 
399
403
  saveMeeting(meeting);
400
404
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.451",
3
+ "version": "0.1.453",
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"