@yemi33/minions 0.1.1894 → 0.1.1896

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 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/*.json`), pull requests, and work queues across all linked projects
220
- - **Plan pipeline** — `/plan` spawns a plan agent, chains to plan-to-prd, produces `plans/{project}-{date}.json` with `status: "awaiting-approval"`. Supports shared-branch and parallel strategies.
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/*.json`, approved) | `implement` |
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}.json (generated)
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)
package/engine/cli.js CHANGED
@@ -1144,7 +1144,8 @@ const commands = {
1144
1144
  const e = engine();
1145
1145
  if (!title) {
1146
1146
  console.log('Usage: node .minions/engine.js work "<title>" [options-json]');
1147
- console.log('Options: {"type":"implement","priority":"high","agent":"dallas","description":"...","branch":"feature/..."}');
1147
+ console.log('Options: {"id":"W-customid","type":"implement","priority":"high","agent":"dallas","description":"...","branch":"feature/...","project":"minions"}');
1148
+ console.log(' id Optional caller-supplied work item ID. Defaults to a cuid-style W-<id>.');
1148
1149
  return;
1149
1150
  }
1150
1151
 
@@ -1157,7 +1158,7 @@ const commands = {
1157
1158
  }
1158
1159
 
1159
1160
  const config = getConfig();
1160
- const { getProjects, projectWorkItemsPath, resolveProjectSource } = require('./shared');
1161
+ const { getProjects, projectWorkItemsPath, resolveProjectSource, uid, safeJsonArr } = require('./shared');
1161
1162
  const projects = getProjects(config);
1162
1163
  const target = opts.project ? resolveProjectSource(opts.project, projects, { allowCentral: false }) : null;
1163
1164
  if (target?.error) {
@@ -1166,10 +1167,36 @@ const commands = {
1166
1167
  }
1167
1168
  const targetProject = target?.project || (projects.length > 0 ? projects[0] : null);
1168
1169
  const wiPath = projectWorkItemsPath(targetProject);
1170
+ const archivePath = wiPath.replace(/\.json$/, '-archive.json');
1171
+
1172
+ // Caller-supplied id: validate and pre-check live + archive for collisions
1173
+ // BEFORE acquiring the work-items lock, so a rejection never mutates state.
1174
+ let requestedId = null;
1175
+ if (opts.id != null) {
1176
+ if (typeof opts.id !== 'string' || !opts.id.trim()) {
1177
+ console.log('Error: opts.id must be a non-empty string');
1178
+ process.exit(1);
1179
+ }
1180
+ requestedId = opts.id.trim();
1181
+ const liveItems = safeJsonArr(wiPath);
1182
+ const archivedItems = safeJsonArr(archivePath);
1183
+ if (liveItems.some(w => w?.id === requestedId) || archivedItems.some(w => w?.id === requestedId)) {
1184
+ console.log(`Error: work item id "${requestedId}" already exists in ${path.basename(wiPath)} or its archive`);
1185
+ process.exit(1);
1186
+ }
1187
+ }
1188
+
1169
1189
  let item;
1190
+ let collision = false;
1170
1191
  mutateWorkItems(wiPath, items => {
1192
+ const id = requestedId || ('W-' + uid());
1193
+ // Re-check inside the lock to close the TOCTOU race against other writers.
1194
+ if (items.some(w => w?.id === id)) {
1195
+ collision = true;
1196
+ return items;
1197
+ }
1171
1198
  item = {
1172
- id: `W${String(items.length + 1).padStart(3, '0')}`,
1199
+ id,
1173
1200
  title: title,
1174
1201
  type: opts.type || 'implement',
1175
1202
  status: WI_STATUS.QUEUED,
@@ -1184,7 +1211,12 @@ const commands = {
1184
1211
  items.push(item);
1185
1212
  });
1186
1213
 
1187
- console.log(`Queued work item: ${item.id} — ${item.title} (project: ${targetProject.name || 'default'})`);
1214
+ if (collision || !item) {
1215
+ console.log(`Error: work item id collision detected for "${requestedId || 'auto-generated'}"`);
1216
+ process.exit(1);
1217
+ }
1218
+
1219
+ console.log(`Queued work item: ${item.id} — ${item.title} (project: ${targetProject?.name || 'default'})`);
1188
1220
  console.log(` Type: ${item.type} | Priority: ${item.priority} | Agent: ${item.agent || 'auto'}`);
1189
1221
  },
1190
1222
 
package/engine/shared.js CHANGED
@@ -1716,7 +1716,7 @@ const ESCALATION_POLICY = {
1716
1716
  };
1717
1717
 
1718
1718
  // Structured completion protocol — fields agents must produce in ```completion blocks
1719
- const COMPLETION_FIELDS = ['status', 'summary', 'files_changed', 'tests', 'pr', 'pending', 'failure_class', 'retryable', 'needs_rerun', 'verdict', 'artifacts'];
1719
+ const COMPLETION_FIELDS = ['status', 'summary', 'files_changed', 'tests', 'pr', 'not_changed', 'failure_class', 'retryable', 'needs_rerun', 'verdict', 'artifacts'];
1720
1720
 
1721
1721
  const DEFAULT_AGENT_METRICS = {
1722
1722
  tasksCompleted: 0, tasksErrored: 0,
package/engine.js CHANGED
@@ -1649,7 +1649,6 @@ async function spawnAgent(dispatchItem, config) {
1649
1649
  errorReason = structuredCompletion
1650
1650
  ? String(
1651
1651
  structuredCompletion.summary
1652
- || structuredCompletion.pending
1653
1652
  || structuredCompletion.failure_class
1654
1653
  || `Agent reported ${structuredCompletion.status || 'failure'}`
1655
1654
  ).slice(0, 300)
@@ -4185,7 +4184,7 @@ async function discoverWork(config) {
4185
4184
  }
4186
4185
 
4187
4186
  // Source 2: Minions-level PRD → implements (multi-project, called once outside project loop)
4188
- // PRD items now flow through plans/*.json materializePlansAsWorkItems → discoverFromWorkItems
4187
+ // PRD items (prd/*.json), materialized from plans/*.md, flow through materializePlansAsWorkItems → discoverFromWorkItems
4189
4188
 
4190
4189
  // Central work items (project-agnostic — agent decides where to work)
4191
4190
  const centralWork = discoverCentralWorkItems(config);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1894",
3
+ "version": "0.1.1896",
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"
@@ -67,7 +67,7 @@ Bias toward senior-engineer restraint:
67
67
  The engine provides a completion report path in the prompt and in `MINIONS_COMPLETION_REPORT`. Before exiting, write JSON there with the actual outcome:
68
68
 
69
69
  ```json
70
- {"status":"success","summary":"what changed and how it was validated","verdict":null,"pr":"PR id/url or N/A","failure_class":"N/A","retryable":false,"needs_rerun":false,"artifacts":[{"type":"note|plan|prd|pr|file","path":"relative/path/or/url","title":"short label"}]}
70
+ {"status":"success","summary":"what changed and how it was validated","verdict":null,"pr":"PR id/url or N/A","failure_class":"N/A","retryable":false,"needs_rerun":false,"not_changed":"adjacent X left alone; refactor Y declined as out of scope","artifacts":[{"type":"note|plan|prd|pr|file","path":"relative/path/or/url","title":"short label"}]}
71
71
  ```
72
72
 
73
73
  For the canonical schema — every field, the `failure_class` enum, `noop:true` semantics, `retryable` / `needs_rerun` shape, and the artifacts array — see `docs/completion-reports.md`. The JSON report is the primary signal; fenced `completion` blocks in stdout are accepted only as a fallback.