@yemi33/minions 0.1.358 → 0.1.360

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,15 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.358 (2026-04-06)
3
+ ## 0.1.360 (2026-04-06)
4
4
 
5
5
  ### Features
6
6
  - pipeline plan stage uses LLM to generate structured plan from meeting
7
7
  - show 'Converting to PRD' status instead of 'In Progress' during plan conversion
8
8
 
9
+ ### Fixes
10
+ - check pull-requests.json for existing PRs before no-PR retry
11
+ - smart no-PR handling — distinguish MCP stall from intentional no-PR
12
+
9
13
  ## 0.1.356 (2026-04-06)
10
14
 
11
15
  ### Fixes
@@ -1279,11 +1279,19 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
1279
1279
  // Detect implement tasks that completed without creating a PR
1280
1280
  if (isSuccess && (type === WORK_TYPE.IMPLEMENT || type === WORK_TYPE.IMPLEMENT_LARGE || type === WORK_TYPE.FIX) && prsCreatedCount === 0 && meta?.item?.id && !meta?.item?.skipPr && meta?.project?.localPath) {
1281
1281
  // Check if a PR already exists linked to this work item (from a previous attempt)
1282
- const projects = shared.getProjects(config);
1283
- const existingPrFound = Object.values(getPrLinks()).includes(meta.item.id);
1282
+ let existingPrFound = Object.values(getPrLinks()).includes(meta.item.id);
1283
+ // Also check pull-requests.json for PRs with matching prdItems or branch
1284
+ if (!existingPrFound) {
1285
+ const allProjects = shared.getProjects(config);
1286
+ for (const p of allProjects) {
1287
+ const prs = safeJson(shared.projectPrPath(p)) || [];
1288
+ if (prs.some(pr => (pr.prdItems || []).includes(meta.item.id) || (pr.branch && pr.branch.includes(meta.item.id)))) {
1289
+ existingPrFound = true;
1290
+ break;
1291
+ }
1292
+ }
1293
+ }
1284
1294
  if (!existingPrFound) {
1285
- log('warn', `Agent completed implement task ${meta.item.id} but no PR was created — reverting to failed for retry`);
1286
- // Revert to failed so auto-retry can re-attempt with PR creation
1287
1295
  let wiPath;
1288
1296
  if (meta.source === 'central-work-item' || meta.source === 'central-work-item-fanout') {
1289
1297
  wiPath = path.join(MINIONS_DIR, 'work-items.json');
@@ -1294,18 +1302,30 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
1294
1302
  const items = safeJson(wiPath) || [];
1295
1303
  const wi = items.find(i => i.id === meta.item.id);
1296
1304
  if (wi) {
1297
- wi.noPr = true;
1298
- wi.failReason = 'Completed without creating a pull request';
1299
1305
  const retries = wi._retryCount || 0;
1300
- if (retries < ENGINE_DEFAULTS.maxRetries) {
1306
+ // Check if agent produced meaningful output (not just MCP timeout)
1307
+ const hasOutput = stdout && stdout.length > 500;
1308
+ if (!hasOutput && retries < ENGINE_DEFAULTS.maxRetries) {
1309
+ // No meaningful output — likely MCP stall or startup failure, retry
1301
1310
  wi.status = WI_STATUS.PENDING;
1302
1311
  wi._retryCount = retries + 1;
1303
1312
  delete wi.dispatched_at;
1304
1313
  delete wi.dispatched_to;
1305
- log('info', `Auto-retry ${retries + 1}/${ENGINE_DEFAULTS.maxRetries} for ${meta.item.id} (no PR created)`);
1314
+ log('info', `Auto-retry ${retries + 1}/${ENGINE_DEFAULTS.maxRetries} for ${meta.item.id} (no output, no PR)`);
1315
+ } else if (hasOutput) {
1316
+ // Agent ran successfully but chose not to create a PR — mark done
1317
+ wi.status = WI_STATUS.DONE;
1318
+ wi.completedAt = ts();
1319
+ wi._noPr = true;
1320
+ wi._noPrReason = 'Agent completed without creating a PR (changes may already exist or not be needed)';
1321
+ delete wi.failReason;
1322
+ log('info', `${meta.item.id} completed without PR — marking done (agent produced output)`);
1306
1323
  } else {
1307
- wi.status = WI_STATUS.FAILED;
1308
- log('warn', `${meta.item.id} failed after ${ENGINE_DEFAULTS.maxRetries} retries — no PR created`);
1324
+ // No output after max retries — mark as needs review
1325
+ wi.status = WI_STATUS.NEEDS_REVIEW;
1326
+ wi._noPr = true;
1327
+ wi.failReason = 'Completed without output or PR after ' + ENGINE_DEFAULTS.maxRetries + ' attempts';
1328
+ log('warn', `${meta.item.id} needs review — no output after ${ENGINE_DEFAULTS.maxRetries} retries`);
1309
1329
  }
1310
1330
  shared.safeWrite(wiPath, items);
1311
1331
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.358",
3
+ "version": "0.1.360",
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"