@yemi33/minions 0.1.2294 → 0.1.2296

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.
@@ -60,6 +60,29 @@ function checkPlanCompletion(meta, config) {
60
60
  const workItemById = {};
61
61
  for (const w of planItems) { if (w.id) workItemById[w.id] = w; }
62
62
 
63
+ // Self-heal stale completion. checkPlanCompletion only ever ADVANCED a plan to
64
+ // `completed` — it never reverted. So a PRD that was completed and then gained
65
+ // a late item (e.g. a build-fix appended post-completion) or had an item
66
+ // regress / lose its WI got stuck `completed` forever: the materializer SKIPS
67
+ // `completed` PRDs (engine.js#materializePlansAsWorkItems), so the new item
68
+ // never materializes, and the gates below return early without clearing the
69
+ // flag — a permanent "completed PRD with a missing item" (the P-mqyp0006 /
70
+ // "Fix PR #341 failing build" incident). Re-open such a plan so the
71
+ // materializer recreates the missing WI and the normal completion flow resumes.
72
+ // Idempotent: once reverted (status active, flag cleared) the guard no-ops, so
73
+ // it cannot flap on subsequent scans while the item is genuinely incomplete.
74
+ const reopenStaleCompletedPlan = (reason) => {
75
+ if (plan.status !== PLAN_STATUS.COMPLETED && !plan._completionNotified) return false;
76
+ log('warn', `Plan ${planFile}: re-opening stale completed PRD — ${reason}`);
77
+ mutateJsonFileLocked(planPath, (data) => {
78
+ if (data.status === PLAN_STATUS.COMPLETED) data.status = PLAN_STATUS.ACTIVE;
79
+ delete data.completedAt;
80
+ data._completionNotified = false;
81
+ return data;
82
+ });
83
+ return true;
84
+ };
85
+
63
86
  // Check 1: every feature must have a work item (materialized)
64
87
  // Fallback: also accept features marked done directly in the PRD JSON (resolved externally)
65
88
  const unmaterialized = [...planFeatureIds].filter(id => {
@@ -69,6 +92,7 @@ function checkPlanCompletion(meta, config) {
69
92
  });
70
93
  if (unmaterialized.length > 0) {
71
94
  log('info', `Plan ${planFile}: ${unmaterialized.length}/${planFeatureIds.size} feature(s) not yet materialized as work items: ${unmaterialized.join(', ')}`);
95
+ reopenStaleCompletedPlan(`${unmaterialized.length} unmaterialized item(s): ${unmaterialized.join(', ')}`);
72
96
  return;
73
97
  }
74
98
 
@@ -88,6 +112,7 @@ function checkPlanCompletion(meta, config) {
88
112
  });
89
113
  if (notTerminal.length > 0) {
90
114
  log('info', `Plan ${planFile}: waiting for ${notTerminal.length}/${planFeatureIds.size} item(s) to reach terminal state: ${notTerminal.join(', ')}`);
115
+ reopenStaleCompletedPlan(`${notTerminal.length} non-terminal item(s): ${notTerminal.join(', ')}`);
91
116
  return;
92
117
  }
93
118
 
package/engine.js CHANGED
@@ -9738,16 +9738,6 @@ async function tickInner() {
9738
9738
  } else if (!autoFixPaused) {
9739
9739
  _resetAutoFixPausedLogState();
9740
9740
  }
9741
- const adoPollEnabled = !pollingPaused && (config.engine?.adoPollEnabled ?? ENGINE_DEFAULTS.adoPollEnabled);
9742
- const ghPollEnabled = !pollingPaused && (config.engine?.ghPollEnabled ?? ENGINE_DEFAULTS.ghPollEnabled);
9743
- // P-c4d8e1a3 — granular per-poller flags. Each of the 6 PR-poll axes
9744
- // (ADO/GH × status/comments/reconcile) plus processPendingRebases gets
9745
- // its own resolution via shared.resolvePollFlag(...). Explicit granular
9746
- // values win; the legacy `adoPollEnabled` / `ghPollEnabled` macros
9747
- // silence their whole bundle as a fallback (including reconcile — a
9748
- // documented breaking change). Defaults: all true. pollingPaused (master
9749
- // killswitch) still composes with status + comments gates; reconcile and
9750
- // the rebase processor are recovery-sweep paths and are NOT gated by it.
9751
9741
  const adoStatusPollEnabled = !pollingPaused && resolvePollFlag(config.engine, 'adoPrStatusPollEnabled', 'adoPollEnabled');
9752
9742
  const ghStatusPollEnabled = !pollingPaused && resolvePollFlag(config.engine, 'ghPrStatusPollEnabled', 'ghPollEnabled');
9753
9743
  const adoCommentsPollEnabled = !pollingPaused && resolvePollFlag(config.engine, 'adoPrCommentsPollEnabled', 'adoPollEnabled');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.2294",
3
+ "version": "0.1.2296",
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"