@yemi33/minions 0.1.898 → 0.1.900

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,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.900 (2026-04-12)
4
+
5
+ ### Other
6
+ - chore(dashboard): remove dashboard.html monolith, fragments are canonical (closes #932) (#942)
7
+
8
+ ## 0.1.899 (2026-04-12)
9
+
10
+ ### Fixes
11
+ - add backward-scan in syncPrdItemStatus to re-open done work items on PRD reset (closes #929) (#940)
12
+
3
13
  ## 0.1.898 (2026-04-12)
4
14
 
5
15
  ### Fixes
@@ -14,7 +14,7 @@ function buildDashboardHtml() {
14
14
  const layoutPath = path.join(dashDir, 'layout.html');
15
15
 
16
16
  if (!fs.existsSync(layoutPath)) {
17
- return safeRead(path.join(MINIONS_DIR, 'dashboard.html')) || '';
17
+ throw new Error(`Dashboard layout not found: ${layoutPath}. The dashboard/ directory must exist.`);
18
18
  }
19
19
 
20
20
  const layout = safeRead(layoutPath);
package/dashboard.js CHANGED
@@ -62,14 +62,13 @@ function resolvePlanPath(file) {
62
62
  return active;
63
63
  }
64
64
 
65
- // Assemble dashboard HTML from fragments (or fall back to monolith)
65
+ // Assemble dashboard HTML from fragments (canonical source: dashboard/)
66
66
  function buildDashboardHtml() {
67
67
  const dashDir = path.join(MINIONS_DIR, 'dashboard');
68
68
  const layoutPath = path.join(dashDir, 'layout.html');
69
69
 
70
- // Fall back to monolith if fragments don't exist
71
70
  if (!fs.existsSync(layoutPath)) {
72
- return safeRead(path.join(MINIONS_DIR, 'dashboard.html')) || '';
71
+ throw new Error(`Dashboard layout not found: ${layoutPath}. The dashboard/ directory must exist.`);
73
72
  }
74
73
 
75
74
  const layout = safeRead(layoutPath);
@@ -148,7 +148,7 @@ Frontend
148
148
  | `engine/shared.js` | `parseStreamJsonOutput()` extracts `sessionId` from result |
149
149
  | `engine/cc-session.json` | Persisted session state (sessionId, turnCount, timestamps) |
150
150
  | `dashboard.js` | CC endpoint, `buildCCStatePreamble()`, `ccDocCall()`, `parseCCActions()` |
151
- | `dashboard.html` | Frontend: localStorage persistence, session indicator, New Session button |
151
+ | `dashboard/js/` | Frontend: localStorage persistence, session indicator, New Session button |
152
152
 
153
153
  ## Command Bar
154
154
 
@@ -31,7 +31,7 @@ These files are removed during sync to personal:
31
31
 
32
32
  Controlled by the `files` field in `package.json`:
33
33
  - `bin/minions.js` — CLI entry point
34
- - `engine.js`, `dashboard.js`, `dashboard.html`, `minions.js` — core scripts
34
+ - `engine.js`, `dashboard.js`, `dashboard/` (fragments), `minions.js` — core scripts
35
35
  - `engine/spawn-agent.js`, `engine/ado-mcp-wrapper.js` — engine helpers
36
36
  - `agents/*/charter.md` — agent role definitions
37
37
  - `playbooks/*.md` — task templates
@@ -8,7 +8,7 @@ const path = require('path');
8
8
  const os = require('os');
9
9
  const shared = require('./shared');
10
10
  const { safeRead, safeJson, safeWrite, mutateJsonFileLocked, mutateWorkItems, execSilent, execAsync, projectPrPath, getPrLinks, addPrLink,
11
- log, ts, dateStamp, WI_STATUS, DONE_STATUSES, PLAN_TERMINAL_STATUSES, WORK_TYPE, PLAN_STATUS, PR_STATUS, DISPATCH_RESULT,
11
+ log, ts, dateStamp, WI_STATUS, DONE_STATUSES, PLAN_TERMINAL_STATUSES, WORK_TYPE, PLAN_STATUS, PRD_ITEM_STATUS, PR_STATUS, DISPATCH_RESULT,
12
12
  ENGINE_DEFAULTS, DEFAULT_AGENT_METRICS, FAILURE_CLASS } = shared;
13
13
  const { trackEngineUsage } = require('./llm');
14
14
  const queries = require('./queries');
@@ -637,6 +637,52 @@ function syncPrdItemStatus(itemId, status, sourcePlan) {
637
637
  } catch (err) { log('warn', `PRD status sync: ${err.message}`); }
638
638
  }
639
639
 
640
+ // ─── PRD Backward-Scan Reconciliation (#929) ────────────────────────────────
641
+ // Proactive counterpart to syncPrdItemStatus. Scans all active PRDs and promotes
642
+ // "missing" items to "updated" when a done work item already exists for that ID.
643
+ // This catches cases where a PRD regeneration incorrectly sets items to "missing"
644
+ // and no subsequent work item state change triggers the reactive sync.
645
+
646
+ function reconcilePrdStatuses(config) {
647
+ if (!fs.existsSync(PRD_DIR)) return;
648
+ let prdFiles;
649
+ try { prdFiles = fs.readdirSync(PRD_DIR).filter(f => f.endsWith('.json')); } catch { return; }
650
+ if (prdFiles.length === 0) return;
651
+
652
+ const allWorkItems = queries.getWorkItems(config);
653
+ if (allWorkItems.length === 0) return;
654
+
655
+ // Index done work items by ID for O(1) lookup
656
+ const doneWiById = new Map();
657
+ for (const wi of allWorkItems) {
658
+ if (wi.id && DONE_STATUSES.has(wi.status)) doneWiById.set(wi.id, wi);
659
+ }
660
+ if (doneWiById.size === 0) return;
661
+
662
+ for (const file of prdFiles) {
663
+ try {
664
+ const fpath = path.join(PRD_DIR, file);
665
+ const plan = safeJson(fpath);
666
+ if (!plan?.missing_features) continue;
667
+ // Skip completed/archived PRDs — no reconciliation needed
668
+ if (plan.status === PLAN_STATUS.COMPLETED) continue;
669
+
670
+ let modified = false;
671
+ for (const feature of plan.missing_features) {
672
+ if (feature.status === PRD_ITEM_STATUS.MISSING && doneWiById.has(feature.id)) {
673
+ feature.status = PRD_ITEM_STATUS.UPDATED;
674
+ modified = true;
675
+ log('info', `PRD backward-scan: promoted ${feature.id} from missing→updated in ${file} (done work item exists)`);
676
+ }
677
+ }
678
+
679
+ if (modified) {
680
+ safeWrite(fpath, plan);
681
+ }
682
+ } catch (err) { log('warn', `PRD backward-scan for ${file}: ${err.message}`); }
683
+ }
684
+ }
685
+
640
686
  // ─── PR Sync from Output ─────────────────────────────────────────────────────
641
687
 
642
688
  function syncPrsFromOutput(output, agentId, meta, config) {
@@ -1876,6 +1922,7 @@ module.exports = {
1876
1922
  cleanupPlanWorktrees,
1877
1923
  updateWorkItemStatus,
1878
1924
  syncPrdItemStatus,
1925
+ reconcilePrdStatuses,
1879
1926
  syncPrsFromOutput,
1880
1927
  updatePrAfterReview,
1881
1928
  updatePrAfterFix,
package/engine.js CHANGED
@@ -135,7 +135,7 @@ const { renderPlaybook, validatePlaybookVars, PLAYBOOK_REQUIRED_VARS,
135
135
 
136
136
  // ─── Lifecycle (extracted to engine/lifecycle.js) ────────────────────────────
137
137
 
138
- const { runPostCompletionHooks, updateWorkItemStatus, syncPrdItemStatus, handlePostMerge, checkPlanCompletion,
138
+ const { runPostCompletionHooks, updateWorkItemStatus, syncPrdItemStatus, reconcilePrdStatuses, handlePostMerge, checkPlanCompletion,
139
139
  syncPrsFromOutput, updatePrAfterReview, updatePrAfterFix, checkForLearnings, extractSkillsFromOutput,
140
140
  updateAgentHistory, updateMetrics, createReviewFeedbackForAuthor, parseAgentOutput, syncPrdFromPrs,
141
141
  isItemCompleted, classifyFailure, processPendingRebases } = require('./engine/lifecycle');
@@ -2692,6 +2692,7 @@ async function discoverWork(config) {
2692
2692
 
2693
2693
  // Side-effect passes: materialize plans and design docs into work-items.json
2694
2694
  // These write to project work queues — picked up by discoverFromWorkItems below.
2695
+ reconcilePrdStatuses(config); // Backward-scan: correct "missing" PRD items that have done work items (#929)
2695
2696
  materializePlansAsWorkItems(config);
2696
2697
 
2697
2698
  for (const project of projects) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.898",
3
+ "version": "0.1.900",
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"
@@ -2,7 +2,7 @@ You are the Command Center AI for "Minions" — a multi-agent software engineeri
2
2
  You have full CLI power (read, write, edit, shell, builds) plus minions-specific actions to delegate work to agents.
3
3
 
4
4
  ## Guardrails
5
- READ ONLY — never write/edit: `engine.js`, `engine/*.js`, `dashboard.js`, `dashboard.html`, `minions.js`, `bin/*.js`, `engine/control.json`, `engine/dispatch.json`, `config.json`.
5
+ READ ONLY — never write/edit: `engine.js`, `engine/*.js`, `dashboard.js`, `dashboard/**`, `minions.js`, `bin/*.js`, `engine/control.json`, `engine/dispatch.json`, `config.json`.
6
6
  CAN modify: notes, plans, knowledge, work items, pull-requests.json, routing.md, charters, skills, playbooks, project repos.
7
7
 
8
8
  ## Filesystem