@yemi33/minions 0.1.372 → 0.1.374

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,6 +1,11 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.372 (2026-04-06)
3
+ ## 0.1.374 (2026-04-06)
4
+
5
+ ### Fixes
6
+ - medium bugs — KB declaration, meeting phantom archive, lifecycle race (#216)
7
+
8
+ ## 0.1.373 (2026-04-06)
4
9
 
5
10
  ### Features
6
11
  - Fix review re-dispatch infinite loop (#226)
@@ -8,6 +13,7 @@
8
13
  - Fix 2 failing source-pattern test assertions (#224)
9
14
 
10
15
  ### Fixes
16
+ - critical engine bugs — pipeline async, lifecycle null guard, scheduler (#215)
11
17
  - restore dispatched_to on work items when marking done after retry
12
18
  - copy button preserves markdown formatting
13
19
 
@@ -12,6 +12,7 @@ const KB_CAT_ICONS = {
12
12
  reviews: '\u{1F50D}', learnings: '\u{1F4A1}', decisions: '\u{2696}',
13
13
  incidents: '\u{1F6A8}', 'api-notes': '\u{1F517}',
14
14
  };
15
+ let _kbData = {};
15
16
  let _kbActiveTab = 'all';
16
17
  const KB_PER_PAGE = 30;
17
18
  let _kbPage = 0;
@@ -86,7 +87,7 @@ function renderKnowledgeBase() {
86
87
  '<div class="kb-item-title">' + icon + ' ' + escHtml(item.title) + '</div>' +
87
88
  '<div class="kb-item-meta">' +
88
89
  '<span>' + label + '</span>' +
89
- (item.agent ? '<span>' + item.agent + '</span>' : '') +
90
+ (item.agent ? '<span>' + escHtml(item.agent) + '</span>' : '') +
90
91
  '<span>' + (item.date || '') + '</span>' +
91
92
  '<span>' + Math.round(item.size / 1024) + 'KB</span>' +
92
93
  '</div>' +
@@ -344,8 +344,8 @@ async function _archiveMeeting(id) {
344
344
  method: 'POST', headers: { 'Content-Type': 'application/json' },
345
345
  body: JSON.stringify({ id })
346
346
  });
347
- if (!res.ok) { const d = await res.json().catch(() => ({})); alert('Failed: ' + (d.error || 'unknown')); refresh(); }
348
- } catch (e) { alert('Error: ' + e.message); refresh(); }
347
+ if (!res.ok) { _deletedIds.delete('mtg:' + id); const d = await res.json().catch(() => ({})); alert('Failed: ' + (d.error || 'unknown')); refresh(); }
348
+ } catch (e) { _deletedIds.delete('mtg:' + id); alert('Error: ' + e.message); refresh(); }
349
349
  }
350
350
 
351
351
  async function _unarchiveMeeting(id) {
@@ -457,24 +457,22 @@ function chainPlanToPrd(dispatchItem, meta, config) {
457
457
 
458
458
  log('info', `Plan chaining: queuing plan-to-prd for next tick (chained from ${dispatchItem.id})`);
459
459
  const wiPath = path.join(MINIONS_DIR, 'work-items.json');
460
- let items = [];
461
- try { items = JSON.parse(fs.readFileSync(wiPath, 'utf8')); } catch (err) {
462
- log('warn', `Failed to parse ${wiPath}: ${err.message}`);
463
- try { fs.copyFileSync(wiPath, wiPath + '.bak'); } catch {}
464
- }
465
- items.push({
466
- id: 'W-' + shared.uid(),
467
- title: `Convert plan to PRD: ${meta?.item?.title || planFile.name}`,
468
- type: 'plan-to-prd',
469
- priority: meta?.item?.priority || 'high',
470
- description: `Plan file: plans/${planFile.name}\nChained from plan task ${dispatchItem.id}`,
471
- status: WI_STATUS.PENDING,
472
- created: ts(),
473
- createdBy: 'engine:chain',
474
- project: targetProject.name,
475
- planFile: planFile.name,
476
- });
477
- shared.safeWrite(wiPath, items);
460
+ shared.mutateJsonFileLocked(wiPath, (items) => {
461
+ if (!Array.isArray(items)) items = [];
462
+ items.push({
463
+ id: 'W-' + shared.uid(),
464
+ title: `Convert plan to PRD: ${meta?.item?.title || planFile.name}`,
465
+ type: 'plan-to-prd',
466
+ priority: meta?.item?.priority || 'high',
467
+ description: `Plan file: plans/${planFile.name}\nChained from plan task ${dispatchItem.id}`,
468
+ status: WI_STATUS.PENDING,
469
+ created: ts(),
470
+ createdBy: 'engine:chain',
471
+ project: targetProject.name,
472
+ planFile: planFile.name,
473
+ });
474
+ return items;
475
+ }, { defaultValue: [] });
478
476
  }
479
477
 
480
478
  // ─── Work Item Path Resolution ───────────────────────────────────────────────
@@ -784,7 +782,7 @@ async function handlePostMerge(pr, project, config, newStatus) {
784
782
 
785
783
  const prNum = (pr.id || '').replace('PR-', '');
786
784
 
787
- if (pr.branch) {
785
+ if (pr.branch && project) {
788
786
  const root = path.resolve(project.localPath);
789
787
  const wtRoot = path.resolve(root, config.engine?.worktreeRoot || '../worktrees');
790
788
  // Find worktrees matching this branch — dir format is {slug}-{branch}-{suffix}
@@ -358,7 +358,7 @@ function executeScheduleStage(stage, stageState, config) {
358
358
  return { status: 'completed', completedAt: ts() };
359
359
  }
360
360
 
361
- function executeParallelStage(stage, stageState, run, pipeline, config) {
361
+ async function executeParallelStage(stage, stageState, run, pipeline, config) {
362
362
  const subStages = stage.stages || [];
363
363
  const subResults = {};
364
364
  for (const sub of subStages) {
@@ -496,7 +496,7 @@ function isStageComplete(stage, stageState, run, config) {
496
496
 
497
497
  // ── Discovery (called per tick) ──────────────────────────────────────────────
498
498
 
499
- function discoverPipelineWork(config) {
499
+ async function discoverPipelineWork(config) {
500
500
  const pipelines = getPipelines();
501
501
  if (pipelines.length === 0) return;
502
502
 
@@ -114,7 +114,7 @@ function discoverScheduledWork(config) {
114
114
  mutateJsonFileLocked(SCHEDULE_RUNS_PATH, (runs) => {
115
115
  for (const sched of schedules) {
116
116
  if (!sched.id || !sched.cron || !sched.title) continue;
117
- if (sched.enabled !== true) continue; // explicit true required undefined/null/false all skip
117
+ if (!sched.enabled) continue; // truthy checkmatches dashboard UI badge behavior
118
118
 
119
119
  const lastRun = runs[sched.id] || null;
120
120
  if (!shouldRunNow(sched, lastRun)) continue;
package/engine.js CHANGED
@@ -2104,7 +2104,7 @@ function discoverWork(config) {
2104
2104
  // Pipeline orchestration — check stage completions and start ready stages
2105
2105
  try {
2106
2106
  const { discoverPipelineWork } = require('./engine/pipeline');
2107
- discoverPipelineWork(config);
2107
+ await discoverPipelineWork(config);
2108
2108
  } catch (e) { log('warn', 'discover pipeline work: ' + e.message); }
2109
2109
 
2110
2110
  // Periodic plan completion sweep — catch PRDs that completed while engine was down
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.372",
3
+ "version": "0.1.374",
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"