@yemi33/minions 0.1.830 → 0.1.832
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 +3 -1
- package/dashboard.js +16 -41
- package/engine/shared.js +2 -2
- package/engine.js +5 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,17 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.832 (2026-04-11)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
- stale PRD shows Regenerate PRD + Resume as-is buttons
|
|
7
7
|
|
|
8
8
|
### Fixes
|
|
9
|
+
- only 'updated' re-opens done work items, remove 'planned' status
|
|
9
10
|
- revert doc-chat MAX_HEIGHT to 500px
|
|
10
11
|
- hide plan card action buttons when stale banner is showing
|
|
11
12
|
- hide conflicting action buttons when stale PRD banner is showing
|
|
12
13
|
- diff-aware plan-to-prd triggered by Resume, not auto-dispatch
|
|
13
14
|
|
|
14
15
|
### Other
|
|
16
|
+
- refactor: migrate handlePrdRegenerate and handlePlansExecute to queuePlanToPrd
|
|
15
17
|
- refactor: add PRD_ITEM_STATUS/PRD_MATERIALIZABLE constants, extract queuePlanToPrd
|
|
16
18
|
- refactor: remove dead criteria variable, DRY plan resume functions
|
|
17
19
|
|
package/dashboard.js
CHANGED
|
@@ -2402,31 +2402,19 @@ If nothing to do: { "duplicates": [], "reclassify": [], "remove": [] }`;
|
|
|
2402
2402
|
try { fs.unlinkSync(prdPath); } catch { /* cleanup */ }
|
|
2403
2403
|
|
|
2404
2404
|
// Queue plan-to-prd regeneration with instructions to preserve completed items
|
|
2405
|
-
const wiPath = path.join(MINIONS_DIR, 'work-items.json');
|
|
2406
|
-
|
|
2407
2405
|
const completedContext = completedItems.length > 0
|
|
2408
2406
|
? `\n\n**Previously completed items (preserve their status in the new PRD):**\n${completedItems.map(i => `- ${i.id}: ${i.name} [${i.status}]`).join('\n')}`
|
|
2409
2407
|
: '';
|
|
2410
2408
|
|
|
2411
|
-
const
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2416
|
-
|
|
2417
|
-
);
|
|
2418
|
-
if (alreadyQueued) { alreadyQueuedId = alreadyQueued.id; return; }
|
|
2419
|
-
items.push({
|
|
2420
|
-
id, title: `Regenerate PRD: ${plan.plan_summary || plan.source_plan}`,
|
|
2421
|
-
type: 'plan-to-prd', priority: 'high',
|
|
2422
|
-
description: `Plan file: plans/${plan.source_plan}\nTarget PRD filename: ${body.file}\nRegeneration requested by user after plan revision.${completedContext}`,
|
|
2423
|
-
status: WI_STATUS.PENDING, created: new Date().toISOString(), createdBy: 'dashboard:regenerate',
|
|
2424
|
-
project: plan.project || '', planFile: plan.source_plan,
|
|
2425
|
-
_targetPrdFile: body.file,
|
|
2426
|
-
});
|
|
2409
|
+
const queued = shared.queuePlanToPrd({
|
|
2410
|
+
planFile: plan.source_plan, prdFile: body.file,
|
|
2411
|
+
title: `Regenerate PRD: ${plan.plan_summary || plan.source_plan}`,
|
|
2412
|
+
description: `Plan file: plans/${plan.source_plan}\nTarget PRD filename: ${body.file}\nRegeneration requested by user after plan revision.${completedContext}`,
|
|
2413
|
+
project: plan.project || '', createdBy: 'dashboard:regenerate',
|
|
2414
|
+
extra: { _targetPrdFile: body.file },
|
|
2427
2415
|
});
|
|
2428
|
-
if (
|
|
2429
|
-
return jsonReply(res, 200, {
|
|
2416
|
+
if (!queued) return jsonReply(res, 200, { alreadyQueued: true });
|
|
2417
|
+
return jsonReply(res, 200, { ok: true, file: plan.source_plan });
|
|
2430
2418
|
} catch (e) { return jsonReply(res, 500, { error: e.message }); }
|
|
2431
2419
|
}
|
|
2432
2420
|
|
|
@@ -2440,28 +2428,15 @@ If nothing to do: { "duplicates": [], "reclassify": [], "remove": [] }`;
|
|
|
2440
2428
|
const planPath = path.join(MINIONS_DIR, 'plans', body.file);
|
|
2441
2429
|
if (!fs.existsSync(planPath)) return jsonReply(res, 404, { error: 'plan file not found' });
|
|
2442
2430
|
|
|
2443
|
-
|
|
2444
|
-
|
|
2445
|
-
|
|
2446
|
-
|
|
2447
|
-
|
|
2448
|
-
|
|
2449
|
-
|
|
2450
|
-
const existing = items.find(w => w.type === 'plan-to-prd' && w.planFile === body.file && (w.status === WI_STATUS.PENDING || w.status === WI_STATUS.DISPATCHED));
|
|
2451
|
-
if (existing) { existingId = existing.id; return items; }
|
|
2452
|
-
items.push({
|
|
2453
|
-
id, title: 'Convert plan to PRD: ' + body.file.replace('.md', ''),
|
|
2454
|
-
type: 'plan-to-prd', priority: 'high',
|
|
2455
|
-
description: 'Plan file: plans/' + body.file,
|
|
2456
|
-
status: WI_STATUS.PENDING, created: new Date().toISOString(),
|
|
2457
|
-
createdBy: 'dashboard:execute', project: body.project || '',
|
|
2458
|
-
planFile: body.file,
|
|
2459
|
-
});
|
|
2460
|
-
return items;
|
|
2461
|
-
}, { defaultValue: [] });
|
|
2462
|
-
if (existingId) return jsonReply(res, 200, { ok: true, id: existingId, alreadyQueued: true });
|
|
2431
|
+
const queued = shared.queuePlanToPrd({
|
|
2432
|
+
planFile: body.file,
|
|
2433
|
+
title: 'Convert plan to PRD: ' + body.file.replace('.md', ''),
|
|
2434
|
+
description: 'Plan file: plans/' + body.file,
|
|
2435
|
+
project: body.project || '', createdBy: 'dashboard:execute',
|
|
2436
|
+
});
|
|
2437
|
+
if (!queued) return jsonReply(res, 200, { ok: true, alreadyQueued: true });
|
|
2463
2438
|
invalidateStatusCache();
|
|
2464
|
-
return jsonReply(res, 200, { ok: true
|
|
2439
|
+
return jsonReply(res, 200, { ok: true });
|
|
2465
2440
|
} catch (e) { return jsonReply(res, 400, { error: e.message }); }
|
|
2466
2441
|
}
|
|
2467
2442
|
|
package/engine/shared.js
CHANGED
|
@@ -587,8 +587,8 @@ const PLAN_STATUS = {
|
|
|
587
587
|
PAUSED: 'paused', REJECTED: 'rejected', COMPLETED: 'completed',
|
|
588
588
|
REVISION_REQUESTED: 'revision-requested',
|
|
589
589
|
};
|
|
590
|
-
const PRD_ITEM_STATUS = { MISSING: 'missing',
|
|
591
|
-
const PRD_MATERIALIZABLE = new Set([PRD_ITEM_STATUS.MISSING, PRD_ITEM_STATUS.
|
|
590
|
+
const PRD_ITEM_STATUS = { MISSING: 'missing', UPDATED: 'updated', DONE: 'done' };
|
|
591
|
+
const PRD_MATERIALIZABLE = new Set([PRD_ITEM_STATUS.MISSING, PRD_ITEM_STATUS.UPDATED]);
|
|
592
592
|
const PR_STATUS = { ACTIVE: 'active', MERGED: 'merged', ABANDONED: 'abandoned', CLOSED: 'closed', LINKED: 'linked' };
|
|
593
593
|
// PRs eligible for polling (status/build/comment checks) — excludes terminal statuses
|
|
594
594
|
const PR_POLLABLE_STATUSES = new Set([PR_STATUS.ACTIVE, PR_STATUS.LINKED]);
|
package/engine.js
CHANGED
|
@@ -25,7 +25,7 @@ const fs = require('fs');
|
|
|
25
25
|
const path = require('path');
|
|
26
26
|
const shared = require('./engine/shared');
|
|
27
27
|
const { exec, execAsync, execSilent, runFile, ts, ENGINE_DEFAULTS: DEFAULTS,
|
|
28
|
-
WI_STATUS, DONE_STATUSES, WORK_TYPE, PLAN_STATUS, PRD_MATERIALIZABLE, PR_STATUS, DISPATCH_RESULT, AGENT_STATUS } = shared;
|
|
28
|
+
WI_STATUS, DONE_STATUSES, WORK_TYPE, PLAN_STATUS, PRD_ITEM_STATUS, PRD_MATERIALIZABLE, PR_STATUS, DISPATCH_RESULT, AGENT_STATUS } = shared;
|
|
29
29
|
const queries = require('./engine/queries');
|
|
30
30
|
|
|
31
31
|
// ─── Paths ──────────────────────────────────────────────────────────────────
|
|
@@ -1360,8 +1360,8 @@ function materializePlansAsWorkItems(config) {
|
|
|
1360
1360
|
if (targetProject) {
|
|
1361
1361
|
const queued = shared.queuePlanToPrd({
|
|
1362
1362
|
planFile: plan.source_plan, prdFile: file,
|
|
1363
|
-
title: `
|
|
1364
|
-
description: `Plan file: plans/${plan.source_plan}\nSource plan was
|
|
1363
|
+
title: `Generate PRD from plan: ${plan.source_plan}`,
|
|
1364
|
+
description: `Plan file: plans/${plan.source_plan}\nSource plan was updated while PRD was awaiting approval — generating fresh PRD.${completedContext}`,
|
|
1365
1365
|
project: targetProject.name, createdBy: 'engine:plan-revision',
|
|
1366
1366
|
});
|
|
1367
1367
|
if (queued) log('info', `Queued plan-to-prd regeneration for revised plan ${plan.source_plan} (${completedItems.length} completed items to carry over)`);
|
|
@@ -1458,9 +1458,9 @@ function materializePlansAsWorkItems(config) {
|
|
|
1458
1458
|
|
|
1459
1459
|
mutateWorkItems(wiPath, existingItems => {
|
|
1460
1460
|
for (const item of projItems) {
|
|
1461
|
-
// Re-open:
|
|
1461
|
+
// Re-open: only 'updated' re-opens a done work item (missing = new item, not re-open)
|
|
1462
1462
|
const existingWi = existingItems.find(w => w.id === item.id);
|
|
1463
|
-
const shouldReopen =
|
|
1463
|
+
const shouldReopen = item.status === PRD_ITEM_STATUS.UPDATED;
|
|
1464
1464
|
if (existingWi && DONE_STATUSES.has(existingWi.status) && shouldReopen) {
|
|
1465
1465
|
existingWi.status = WI_STATUS.PENDING;
|
|
1466
1466
|
existingWi._reopened = true;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.832",
|
|
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"
|