@yemi33/minions 0.1.1895 → 0.1.1897
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/README.md +4 -4
- package/dashboard/js/render-plans.js +5 -2
- package/dashboard.js +5 -4
- package/engine/shared.js +21 -5
- package/engine.js +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -216,8 +216,8 @@ minions work "Explore the codebase and document the architecture"
|
|
|
216
216
|
|
|
217
217
|
## What It Does
|
|
218
218
|
|
|
219
|
-
- **Auto-discovers work** from plans (`plans/*.
|
|
220
|
-
- **Plan pipeline** — `/plan` spawns a plan agent, chains to plan-to-prd, produces `plans/{project}-{date}.
|
|
219
|
+
- **Auto-discovers work** from plans (`plans/*.md`), pull requests, and work queues across all linked projects (Plans are markdown in `plans/`; PRDs are JSON in `prd/`.)
|
|
220
|
+
- **Plan pipeline** — `/plan` spawns a plan agent, chains to plan-to-prd, produces `plans/{project}-{date}.md` with `status: "awaiting-approval"`. Supports shared-branch and parallel strategies.
|
|
221
221
|
- **Human approval gate** — plans require approval before materializing as work items. Dashboard provides Approve / Discuss & Revise / Reject. Discussion launches an interactive Command Center session via the configured runtime CLI (`config.engine.ccCli`).
|
|
222
222
|
- **Dispatches AI agents** (Claude CLI) with full project context, git worktrees, and MCP server access
|
|
223
223
|
- **Routes intelligently** — fixes first, then reviews, then implementation, matched to agent strengths
|
|
@@ -380,7 +380,7 @@ The engine discovers work from 4 sources, in priority order:
|
|
|
380
380
|
| Priority | Source | Dispatch Type |
|
|
381
381
|
|----------|--------|---------------|
|
|
382
382
|
| 1 | Pull requests (changes-requested, human feedback, build failures, pending review) | `fix`, `review`, `test` |
|
|
383
|
-
| 2 | Plan items (`plans/*.
|
|
383
|
+
| 2 | Plan items (`plans/*.md`, approved) | `implement` |
|
|
384
384
|
| 3 | Per-project work items | item's `type` |
|
|
385
385
|
| 4 | Central work items (project-agnostic tasks) | item's `type` |
|
|
386
386
|
|
|
@@ -699,7 +699,7 @@ To move to a new machine: `npm install -g @yemi33/minions && minions init --forc
|
|
|
699
699
|
config.json <- projects[], agents, engine, claude settings (generated by minions init)
|
|
700
700
|
config.template.json <- Template for new installs
|
|
701
701
|
package.json <- npm package definition
|
|
702
|
-
plans/ <- Approved plans: plans/{project}-{date}.
|
|
702
|
+
plans/ <- Approved plans: plans/{project}-{date}.md (generated)
|
|
703
703
|
prd/ <- PRD archives and verification guides (generated)
|
|
704
704
|
pipelines/ <- Pipeline definitions (generated)
|
|
705
705
|
meetings/ <- Meeting state files (generated)
|
|
@@ -412,13 +412,16 @@ async function planExecute(file, project, btn) {
|
|
|
412
412
|
const data = await res.json();
|
|
413
413
|
if (res.ok) {
|
|
414
414
|
// Inject into local work items so the next render immediately hides Execute
|
|
415
|
-
if (!data.alreadyQueued) {
|
|
415
|
+
if (!data.alreadyQueued && data.id) {
|
|
416
416
|
(window._lastWorkItems = window._lastWorkItems || []).push({
|
|
417
417
|
id: data.id, type: 'plan-to-prd', status: 'pending', planFile: file
|
|
418
418
|
});
|
|
419
419
|
}
|
|
420
420
|
closeModal();
|
|
421
|
-
|
|
421
|
+
// Fall back to a clean message if the server didn't return an id (#2375).
|
|
422
|
+
const idLabel = data.id ? ' (' + data.id + ')' : '';
|
|
423
|
+
const queuedLabel = data.id ? 'Queued ' + data.id + ' — agent will convert plan to PRD' : 'Plan queued — agent will convert plan to PRD';
|
|
424
|
+
showToast('cmd-toast', data.alreadyQueued ? 'Already queued' + idLabel : queuedLabel, true);
|
|
422
425
|
wakeEngine();
|
|
423
426
|
refreshPlans();
|
|
424
427
|
} else {
|
package/dashboard.js
CHANGED
|
@@ -4574,7 +4574,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
4574
4574
|
const projectTarget = resolveProjectSourceTarget(projectName, PROJECTS, { allowCentral: false });
|
|
4575
4575
|
const targetProject = projectTarget.project || (PROJECTS.length === 1 ? PROJECTS[0] : null);
|
|
4576
4576
|
if (targetProject) {
|
|
4577
|
-
|
|
4577
|
+
const diffAwareResult = shared.queuePlanToPrd({
|
|
4578
4578
|
planFile: plan.source_plan, prdFile: body.file,
|
|
4579
4579
|
title: `Update PRD from revised plan: ${plan.source_plan}`,
|
|
4580
4580
|
description: `mode: diff-aware-update\nPlan file: plans/${plan.source_plan}\nPRD file: prd/${body.file}\n\n` +
|
|
@@ -4584,6 +4584,7 @@ const server = http.createServer(async (req, res) => {
|
|
|
4584
4584
|
project: targetProject.name, createdBy: 'dashboard:plan-resume',
|
|
4585
4585
|
extra: { _existingPrdFile: body.file },
|
|
4586
4586
|
});
|
|
4587
|
+
diffAwareQueued = diffAwareResult.queued;
|
|
4587
4588
|
}
|
|
4588
4589
|
}
|
|
4589
4590
|
|
|
@@ -4731,15 +4732,15 @@ const server = http.createServer(async (req, res) => {
|
|
|
4731
4732
|
'\n\nA prior PRD already exists for this plan. Read it, apply this feedback, and overwrite the PRD with the corrected version.';
|
|
4732
4733
|
}
|
|
4733
4734
|
|
|
4734
|
-
const
|
|
4735
|
+
const queueResult = shared.queuePlanToPrd({
|
|
4735
4736
|
planFile: body.file,
|
|
4736
4737
|
title: 'Convert plan to PRD: ' + body.file.replace('.md', ''),
|
|
4737
4738
|
description,
|
|
4738
4739
|
project: declaredProject || body.project || '', createdBy: 'dashboard:execute',
|
|
4739
4740
|
});
|
|
4740
|
-
if (!queued) return jsonReply(res, 200, { ok: true, alreadyQueued: true });
|
|
4741
|
+
if (!queueResult.queued) return jsonReply(res, 200, { ok: true, alreadyQueued: true, id: queueResult.id });
|
|
4741
4742
|
invalidateStatusCache();
|
|
4742
|
-
return jsonReply(res, 200, { ok: true });
|
|
4743
|
+
return jsonReply(res, 200, { ok: true, id: queueResult.id });
|
|
4743
4744
|
} catch (e) { return jsonReply(res, 400, { error: e.message }); }
|
|
4744
4745
|
}
|
|
4745
4746
|
|
package/engine/shared.js
CHANGED
|
@@ -1628,17 +1628,30 @@ function trackReviewMetric(pr, newReviewStatus, config) {
|
|
|
1628
1628
|
} catch (err) { log('warn', `Metrics update: ${err.message}`); }
|
|
1629
1629
|
}
|
|
1630
1630
|
|
|
1631
|
-
/**
|
|
1631
|
+
/**
|
|
1632
|
+
* Queue a plan-to-prd work item with dedup check inside lock.
|
|
1633
|
+
*
|
|
1634
|
+
* Returns { queued, alreadyQueued, id, item } so callers (e.g. POST /api/plans/execute)
|
|
1635
|
+
* can surface the new or existing work item id back to the dashboard. Returning
|
|
1636
|
+
* just a boolean caused the toast to render "queued undefined" (issue #2375).
|
|
1637
|
+
*/
|
|
1632
1638
|
function queuePlanToPrd({ planFile, prdFile, title, description, project, createdBy, extra }) {
|
|
1633
1639
|
// Use MINIONS_DIR (honors MINIONS_TEST_DIR override) instead of resolving from
|
|
1634
1640
|
// __dirname — otherwise tests that exercise this helper leak work items into
|
|
1635
1641
|
// the real package-root work-items.json even after createTestMinionsDir().
|
|
1636
1642
|
const centralWiPath = path.join(MINIONS_DIR, 'work-items.json');
|
|
1637
1643
|
let queued = false;
|
|
1644
|
+
let id = null;
|
|
1645
|
+
let item = null;
|
|
1638
1646
|
mutateJsonFileLocked(centralWiPath, items => {
|
|
1639
1647
|
if (!Array.isArray(items)) items = [];
|
|
1640
|
-
|
|
1641
|
-
|
|
1648
|
+
const existing = items.find(w => w.type === 'plan-to-prd' && w.planFile === planFile && (w.status === 'pending' || w.status === 'dispatched'));
|
|
1649
|
+
if (existing) {
|
|
1650
|
+
id = existing.id;
|
|
1651
|
+
item = existing;
|
|
1652
|
+
return items;
|
|
1653
|
+
}
|
|
1654
|
+
const newItem = {
|
|
1642
1655
|
id: 'W-' + uid(),
|
|
1643
1656
|
title,
|
|
1644
1657
|
type: 'plan-to-prd',
|
|
@@ -1650,11 +1663,14 @@ function queuePlanToPrd({ planFile, prdFile, title, description, project, create
|
|
|
1650
1663
|
project,
|
|
1651
1664
|
planFile,
|
|
1652
1665
|
...(extra || {}),
|
|
1653
|
-
}
|
|
1666
|
+
};
|
|
1667
|
+
items.push(newItem);
|
|
1654
1668
|
queued = true;
|
|
1669
|
+
id = newItem.id;
|
|
1670
|
+
item = newItem;
|
|
1655
1671
|
return items;
|
|
1656
1672
|
}, { defaultValue: [] });
|
|
1657
|
-
return queued;
|
|
1673
|
+
return { queued, alreadyQueued: !queued, id, item };
|
|
1658
1674
|
}
|
|
1659
1675
|
|
|
1660
1676
|
function extractPlanDeclaredProject(planContent) {
|
package/engine.js
CHANGED
|
@@ -4184,7 +4184,7 @@ async function discoverWork(config) {
|
|
|
4184
4184
|
}
|
|
4185
4185
|
|
|
4186
4186
|
// Source 2: Minions-level PRD → implements (multi-project, called once outside project loop)
|
|
4187
|
-
// PRD items
|
|
4187
|
+
// PRD items (prd/*.json), materialized from plans/*.md, flow through materializePlansAsWorkItems → discoverFromWorkItems
|
|
4188
4188
|
|
|
4189
4189
|
// Central work items (project-agnostic — agent decides where to work)
|
|
4190
4190
|
const centralWork = discoverCentralWorkItems(config);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1897",
|
|
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"
|