@yemi33/minions 0.1.546 → 0.1.547

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,5 +1,10 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.547 (2026-04-07)
4
+
5
+ ### Fixes
6
+ - remap sequential PRD item IDs to prevent cross-PRD collisions (#474)
7
+
3
8
  ## 0.1.546 (2026-04-07)
4
9
 
5
10
  ### Features
package/engine.js CHANGED
@@ -1077,10 +1077,39 @@ function materializePlansAsWorkItems(config) {
1077
1077
  let planFiles;
1078
1078
  try { planFiles = fs.readdirSync(PRD_DIR).filter(f => f.endsWith('.json')); } catch { return; }
1079
1079
 
1080
+ // Regex for detecting sequential PRD item IDs (P-001, P-002) — hoisted outside loop
1081
+ const SEQUENTIAL_ID_RE = /^P-?\d+$/;
1082
+
1080
1083
  for (const file of planFiles) {
1081
1084
  const plan = safeJson(path.join(PRD_DIR, file));
1082
1085
  if (!plan?.missing_features) continue;
1083
1086
 
1087
+ // ID collision prevention: remap sequential IDs (P-001, P-002) to globally unique P-<uid> IDs.
1088
+ // Agents are instructed to use P-<uuid> format but sometimes generate sequential IDs,
1089
+ // which collide across PRDs causing phantom done/dispatched status (see #466).
1090
+ try {
1091
+ if (plan.missing_features.some(f => SEQUENTIAL_ID_RE.test(f.id))) {
1092
+ const allWorkItems = queries.getWorkItems(config);
1093
+ const anyMaterialized = plan.missing_features.some(f =>
1094
+ SEQUENTIAL_ID_RE.test(f.id) && allWorkItems.some(w => w.id === f.id && w.sourcePlan === file));
1095
+ if (!anyMaterialized) {
1096
+ const idMap = new Map();
1097
+ for (const f of plan.missing_features) {
1098
+ if (SEQUENTIAL_ID_RE.test(f.id)) {
1099
+ const newId = 'P-' + shared.uid();
1100
+ idMap.set(f.id, newId);
1101
+ f.id = newId;
1102
+ }
1103
+ }
1104
+ for (const f of plan.missing_features) {
1105
+ if (f.depends_on) f.depends_on = f.depends_on.map(d => idMap.get(d) || d);
1106
+ }
1107
+ safeWrite(path.join(PRD_DIR, file), plan);
1108
+ log('info', `Remapped ${idMap.size} sequential ID(s) in ${file} to prevent cross-PRD collisions`);
1109
+ }
1110
+ }
1111
+ } catch (e) { log('warn', `Sequential ID remapping failed for ${file}: ${e.message}`); }
1112
+
1084
1113
  // Plan staleness: if source_plan .md was modified since last sync, auto-clean and re-sync
1085
1114
  if (plan.source_plan) {
1086
1115
  const sourcePlanPath = path.join(PLANS_DIR, plan.source_plan);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.546",
3
+ "version": "0.1.547",
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"