@yemi33/minions 0.1.167 → 0.1.169

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,27 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.169 (2026-04-02)
4
+
5
+ ### Engine
6
+ - engine/lifecycle.js
7
+
8
+ ## 0.1.168 (2026-04-02)
9
+
10
+ ### Engine
11
+ - engine.js
12
+ - engine/lifecycle.js
13
+ - engine/playbook.js
14
+ - engine/shared.js
15
+
16
+ ### Dashboard
17
+ - dashboard.js
18
+ - dashboard/js/render-work-items.js
19
+ - dashboard/js/settings.js
20
+
21
+ ### Other
22
+ - routing.md
23
+ - test/unit.test.js
24
+
3
25
  ## 0.1.167 (2026-04-02)
4
26
 
5
27
  ### Engine
@@ -116,7 +116,7 @@ function renderWorkItems(items) {
116
116
  function editWorkItem(id, source) {
117
117
  const item = allWorkItems.find(i => i.id === id);
118
118
  if (!item) return;
119
- const types = ['implement', 'fix', 'review', 'plan', 'verify', 'evaluate', 'decompose', 'meeting', 'investigate', 'refactor', 'test', 'explore', 'ask', 'docs'];
119
+ const types = ['implement', 'fix', 'review', 'plan', 'verify', 'decompose', 'meeting', 'investigate', 'refactor', 'test', 'explore', 'ask', 'docs'];
120
120
  const priorities = ['critical', 'high', 'medium', 'low'];
121
121
  const agentOpts = (cmdAgents || []).map(a => '<option value="' + escHtml(a.id) + '"' + (item.agent === a.id ? ' selected' : '') + '>' + escHtml(a.name) + '</option>').join('');
122
122
  const typeOpts = types.map(t => '<option value="' + t + '"' + ((item.type || 'implement') === t ? ' selected' : '') + '>' + t + '</option>').join('');
@@ -316,7 +316,7 @@ async function submitFeedback(id, source) {
316
316
  }
317
317
 
318
318
  function openCreateWorkItemModal() {
319
- const typeOpts = ['implement', 'fix', 'explore', 'test', 'review', 'ask', 'plan', 'verify', 'evaluate', 'decompose', 'meeting'].map(t =>
319
+ const typeOpts = ['implement', 'fix', 'explore', 'test', 'review', 'ask', 'plan', 'verify', 'decompose', 'meeting'].map(t =>
320
320
  '<option value="' + t + '"' + (t === 'implement' ? ' selected' : '') + '>' + t + '</option>'
321
321
  ).join('');
322
322
  const priOpts = ['high', 'medium', 'low'].map(p =>
@@ -39,7 +39,7 @@ async function openSettings() {
39
39
  '</div>' +
40
40
  '<div style="display:flex;flex-direction:column;gap:6px;margin-bottom:16px">' +
41
41
  settingsToggle('Auto-approve Plans', 'set-autoApprovePlans', !!e.autoApprovePlans, 'PRDs are approved automatically without human review') +
42
- settingsToggle('Auto-review PRs', 'set-autoReview', e.autoReview !== false, 'Automatically dispatch review agents for new PRs') +
42
+ settingsToggle('Eval Loop', 'set-evalLoop', e.evalLoop !== false, 'Auto-review implementations and iterate fix cycles until pass') +
43
43
  settingsToggle('Auto-decompose', 'set-autoDecompose', e.autoDecompose !== false, 'Large implement items are auto-split into sub-tasks') +
44
44
  settingsToggle('Allow Temp Agents', 'set-allowTempAgents', !!e.allowTempAgents, 'Spawn ephemeral agents when all permanent agents are busy') +
45
45
  '</div>' +
@@ -122,7 +122,7 @@ async function saveSettings() {
122
122
  restartGracePeriod: document.getElementById('set-restartGracePeriod').value,
123
123
  meetingRoundTimeout: document.getElementById('set-meetingRoundTimeout').value,
124
124
  autoApprovePlans: document.getElementById('set-autoApprovePlans').checked,
125
- autoReview: document.getElementById('set-autoReview').checked,
125
+ evalLoop: document.getElementById('set-evalLoop').checked,
126
126
  autoDecompose: document.getElementById('set-autoDecompose').checked,
127
127
  allowTempAgents: document.getElementById('set-allowTempAgents').checked,
128
128
  };
package/dashboard.js CHANGED
@@ -2956,7 +2956,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
2956
2956
  }
2957
2957
  }
2958
2958
  if (e.worktreeRoot !== undefined) config.engine.worktreeRoot = String(e.worktreeRoot || D.worktreeRoot);
2959
- for (const key of ['autoApprovePlans', 'autoReview', 'autoDecompose', 'allowTempAgents']) {
2959
+ for (const key of ['autoApprovePlans', 'evalLoop', 'autoDecompose', 'allowTempAgents']) {
2960
2960
  if (e[key] !== undefined) config.engine[key] = !!e[key];
2961
2961
  }
2962
2962
  }
@@ -478,6 +478,7 @@ function updateWorkItemStatus(meta, status, reason) {
478
478
  if (status === 'done') {
479
479
  delete target.failReason;
480
480
  delete target.failedAt;
481
+ delete target._retryCount;
481
482
  target.completedAt = ts();
482
483
  } else if (status === 'failed') {
483
484
  if (reason) target.failReason = reason;
@@ -1068,7 +1069,7 @@ function resolveWiPath(meta) {
1068
1069
  }
1069
1070
 
1070
1071
  /**
1071
- * Parse structured eval verdict from evaluate agent output.
1072
+ * Parse structured eval verdict from review agent output.
1072
1073
  * Looks for a JSON block with { pass, build, tests, criteria_met, criteria_failed, feedback }.
1073
1074
  * Returns parsed object or null if not found.
1074
1075
  */
@@ -1247,8 +1248,8 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
1247
1248
  // For 'fix' items, only trigger when they were created by the eval loop (_evalParentId set)
1248
1249
  const isEvalEligible = type === 'implement' || (type === 'fix' && meta?.item?._evalParentId);
1249
1250
  if (isSuccess && !skipDoneStatus && isEvalEligible && meta?.item?.id) {
1250
- const autoReview = config.engine?.autoReview ?? shared.ENGINE_DEFAULTS.autoReview;
1251
- if (autoReview) {
1251
+ const evalLoop = config.engine?.evalLoop !== false;
1252
+ if (evalLoop) {
1252
1253
  try {
1253
1254
  const wiPath = resolveWiPath(meta);
1254
1255
  if (wiPath) {
@@ -1297,10 +1298,10 @@ function runPostCompletionHooks(dispatchItem, agentId, code, stdout, config) {
1297
1298
  if (isSuccess && type === 'review' && meta?.item?._evalParentId) {
1298
1299
  try {
1299
1300
  const verdict = parseEvalVerdict(resultSummary || stdout);
1300
- const autoReview = config.engine?.autoReview ?? shared.ENGINE_DEFAULTS.autoReview;
1301
+ const evalLoop = config.engine?.evalLoop !== false;
1301
1302
  const maxIter = config.engine?.evalMaxIterations ?? shared.ENGINE_DEFAULTS.evalMaxIterations;
1302
1303
 
1303
- if (verdict && !verdict.pass && autoReview) {
1304
+ if (verdict && !verdict.pass && evalLoop) {
1304
1305
  const wiPath = resolveWiPath(meta);
1305
1306
  if (wiPath) {
1306
1307
  const items = safeJson(wiPath) || [];
@@ -478,7 +478,7 @@ function selectPlaybook(workType, item) {
478
478
  if (workType === 'review' && !item?._pr && !item?.pr_id) {
479
479
  return 'work-item';
480
480
  }
481
- const typeSpecificPlaybooks = ['explore', 'review', 'test', 'plan-to-prd', 'plan', 'ask', 'verify', 'evaluate', 'decompose', 'meeting-investigate', 'meeting-debate', 'meeting-conclude'];
481
+ const typeSpecificPlaybooks = ['explore', 'review', 'test', 'plan-to-prd', 'plan', 'ask', 'verify', 'decompose', 'meeting-investigate', 'meeting-debate', 'meeting-conclude'];
482
482
  return typeSpecificPlaybooks.includes(workType) ? workType : 'work-item';
483
483
  }
484
484
 
package/engine/shared.js CHANGED
@@ -355,10 +355,9 @@ const ENGINE_DEFAULTS = {
355
355
  allowTempAgents: false, // opt-in: spawn ephemeral agents when all permanent agents are busy
356
356
  autoDecompose: true, // auto-decompose implement:large items into sub-tasks
357
357
  autoApprovePlans: false, // auto-approve PRDs without waiting for human approval
358
- autoReview: true, // auto-dispatch review agents for new PRs (disable for manual review workflow)
359
358
  meetingRoundTimeout: 600000, // 10min per meeting round before auto-advance
360
- evalLoop: true, // enable evaluate→fix loop after implementation completes
361
- evalMaxIterations: 3, // max evaluate→fix cycles before escalating to human
359
+ evalLoop: true, // enable review→fix loop after implementation completes
360
+ evalMaxIterations: 3, // max review→fix cycles before escalating to human
362
361
  evalMaxCost: null, // USD ceiling per work item across all eval iterations; null = no limit (gather baseline data first)
363
362
  };
364
363
 
package/engine.js CHANGED
@@ -1257,9 +1257,9 @@ function discoverFromPrs(config, project) {
1257
1257
  // minionsReview tracks metadata (reviewer, note) but not the authoritative status
1258
1258
  const reviewStatus = pr.reviewStatus || 'pending';
1259
1259
 
1260
- // PRs needing review: pending or waiting (review dispatched but no verdict yet)
1261
- const autoReview = config.engine?.autoReview !== false;
1262
- const needsReview = autoReview && reviewStatus === 'pending';
1260
+ // PRs needing review: only dispatch if evalLoop is enabled
1261
+ const evalLoop = config.engine?.evalLoop !== false;
1262
+ const needsReview = evalLoop && reviewStatus === 'pending';
1263
1263
  if (needsReview) {
1264
1264
  const key = `review-${project?.name || 'default'}-${pr.id}`;
1265
1265
  if (isAlreadyDispatched(key) || isOnCooldown(key, cooldownMs)) continue;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.167",
3
+ "version": "0.1.169",
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"
package/routing.md CHANGED
@@ -17,7 +17,6 @@ How the engine decides who handles what. Parsed by engine.js — keep the table
17
17
  | test | dallas | ralph |
18
18
  | ask | ripley | rebecca |
19
19
  | verify | dallas | ralph |
20
- | evaluate | ripley | lambert |
21
20
  | decompose | ripley | rebecca |
22
21
  | meeting | ripley | rebecca |
23
22
 
@@ -1,114 +0,0 @@
1
- # Evaluate: {{item_name}}
2
-
3
- > Agent: {{agent_name}} ({{agent_role}}) | Team root: {{team_root}}
4
-
5
- ## Context
6
-
7
- Project: {{project_name}}
8
- Repo: {{repo_name}} | Org: {{ado_org}} | ADO Project: {{ado_project}}
9
- PR: {{pr_url}}
10
- Work Item: {{item_id}}
11
-
12
- ## Acceptance Criteria
13
-
14
- {{acceptance_criteria}}
15
-
16
- ## Task Description
17
-
18
- {{task_description}}
19
-
20
- ## Your Task
21
-
22
- You are the **Evaluator** in the Planner-Generator-Evaluator pattern. Your job is to independently verify whether the implementation in the PR branch meets the acceptance criteria. You are NOT the implementer — you are the skeptic.
23
-
24
- **Mindset: Do not pass unless build succeeds AND all acceptance criteria are demonstrably met.** Assume the implementation is incomplete or wrong until proven otherwise. Look for edge cases, missing requirements, and silent failures.
25
-
26
- ## Step 1: Check Out the PR Branch
27
-
28
- ```bash
29
- cd {{project_path}}
30
- git fetch origin
31
- git checkout {{branch_name}}
32
- git pull origin {{branch_name}}
33
- ```
34
-
35
- ## Step 2: Build
36
-
37
- Run the project build. Check `CLAUDE.md`, `package.json`, or `README` for build instructions.
38
-
39
- ```bash
40
- # Typical:
41
- npm install && npm run build
42
- # Or whatever the project uses
43
- ```
44
-
45
- Record: **PASS** or **FAIL** with error output.
46
-
47
- If the build fails, **stop here** — the verdict is `pass: false`. Include the build error in feedback.
48
-
49
- ## Step 3: Run Tests
50
-
51
- Run the full test suite:
52
-
53
- ```bash
54
- npm test
55
- ```
56
-
57
- Record: **X passed / Y failed / Z skipped**.
58
-
59
- If any tests fail, note which ones and whether they are related to the changes.
60
-
61
- ## Step 4: Diff Review Against Acceptance Criteria
62
-
63
- Review the actual code changes:
64
-
65
- ```bash
66
- git diff {{main_branch}}...{{branch_name}} --stat
67
- git diff {{main_branch}}...{{branch_name}}
68
- ```
69
-
70
- For **each** acceptance criterion, determine:
71
- - **Met**: The diff demonstrably satisfies this criterion. Cite the specific file/line.
72
- - **Not met**: The diff does not satisfy this criterion, or satisfies it only partially. Explain what's missing.
73
-
74
- Be precise. "Looks good" is not an evaluation — cite file paths and line numbers.
75
-
76
- ## Step 5: Output Structured Verdict
77
-
78
- After completing your evaluation, output the following JSON block as your final output. This MUST be valid JSON wrapped in a `json` fenced code block:
79
-
80
- ```json
81
- {
82
- "pass": false,
83
- "build": true,
84
- "tests": "42/42",
85
- "criteria_met": [
86
- "criterion 1 — met because X (source: path/to/file.js:42)"
87
- ],
88
- "criteria_failed": [
89
- "criterion 2 — not met because Y is missing"
90
- ],
91
- "feedback": "Summary of what needs to change for this to pass. Be specific — file names, line numbers, what to add/fix."
92
- }
93
- ```
94
-
95
- Field definitions:
96
- - `pass`: `true` only if build succeeds AND **all** acceptance criteria are met. Otherwise `false`.
97
- - `build`: `true` if the build completed without errors, `false` otherwise.
98
- - `tests`: String in format `"passed/total"` (e.g., `"38/40"`). Use `"N/A"` if no test suite exists.
99
- - `criteria_met`: Array of strings — one per criterion that IS met. Include source references.
100
- - `criteria_failed`: Array of strings — one per criterion that is NOT met. Explain why.
101
- - `feedback`: Actionable feedback for the implementer. Be specific about what to fix. If `pass` is `true`, use this for minor suggestions or "LGTM".
102
-
103
- ## Rules
104
-
105
- - **No Playwright / browser testing** — this phase evaluates build, tests, and code review only.
106
- - **Do NOT fix code** — only evaluate and report. You are the evaluator, not the implementer.
107
- - **Do NOT rubber-stamp** — if a criterion is ambiguous, evaluate conservatively (fail it and explain).
108
- - **Build failure is an automatic fail** — do not evaluate criteria if the build doesn't pass.
109
- - **Every criterion must be addressed** — `criteria_met` + `criteria_failed` should cover all acceptance criteria.
110
- - **Cite sources** — reference file paths and line numbers for every met/failed criterion.
111
-
112
- {{references}}
113
-
114
- **Note:** Do NOT write to `agents/*/status.json` — the engine manages your status automatically.