@yemi33/minions 0.1.498 → 0.1.500

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,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.500 (2026-04-07)
4
+
5
+ ### Features
6
+ - strengthen CC dispatch contract with domain terminology mapping
7
+
8
+ ### Fixes
9
+ - comprehensive steering failure handling with user-visible feedback
10
+
3
11
  ## 0.1.498 (2026-04-07)
4
12
 
5
13
  ### Features
package/dashboard.js CHANGED
@@ -576,6 +576,30 @@ Available action types:
576
576
  - **update-routing**: Update the routing table. Fields: content (full routing.md content)
577
577
  - **file-bug**: File a bug on the Minions repo (yemi33/minions). Fields: title (short bug title), description (markdown body), labels (optional array, defaults to ["bug"]). Trigger phrases: "file a bug", "file an issue", "report a bug", "create an issue", "this is a bug", "log a bug". This is for bugs in Minions itself, not the user's project. When filing, include repro steps and relevant context from the conversation in the description. If the user hasn't provided repro steps, ask before filing.
578
578
 
579
+ ## Domain Terminology — Minions-Specific Meanings
580
+
581
+ Many common English words have specific meanings in the Minions context. **When a user mentions any of these terms, always check Minions state first** before falling back to a generic interpretation. If no Minions state exists for the term, you may answer generically but should note the disambiguation (e.g. "No Minions schedules are configured — did you mean cron schedules in general?").
582
+
583
+ | Term | Minions meaning | Where to check |
584
+ |------|-----------------|----------------|
585
+ | schedules | \`config.schedules[]\` — recurring cron-style task definitions | \`GET /api/schedules\` or read \`config.json\` |
586
+ | pipelines | \`pipelines/*.json\` — multi-stage execution plans with stages, triggers, and runs | \`GET /api/pipelines\` or read \`pipelines/\` dir |
587
+ | agents | Named Minions agents (Dallas, Ripley, etc.) with roles, charters, and status | \`config.agents\`, \`agents/\` dir |
588
+ | inbox | \`notes/inbox/\` — incoming agent findings awaiting consolidation | \`GET /api/inbox\` |
589
+ | work items | \`projects/<name>/work-items.json\` — dispatch units assigned to agents | \`GET /api/work-items\` |
590
+ | plans | \`plans/*.md\` — structured multi-step plan files | \`GET /api/plans\` or read \`plans/\` dir |
591
+ | PRD | \`prd/*.json\` — structured PRD files with items, acceptance criteria, dependencies | \`GET /api/prd-items\` or read \`prd/\` dir |
592
+ | PRs | \`projects/<name>/pull-requests.json\` — tracked pull requests per project | \`GET /api/pull-requests/all\` |
593
+ | dispatch | \`engine/dispatch.json\` — active agent task queue (pending/active/completed) | \`GET /api/status\` |
594
+ | tick | Engine orchestration cycle (~60s) — the heartbeat that drives all polling and dispatch | \`GET /api/status\` for tick count |
595
+ | routing | \`routing.md\` — maps work types to agents (e.g. implement → dallas) | \`GET /api/settings/routing\` or read \`routing.md\` |
596
+ | knowledge / KB | \`knowledge/\` — structured knowledge base entries by category | \`GET /api/knowledge\` |
597
+ | notes | \`notes.md\` — consolidated team notes (merged from inbox) | \`GET /api/notes-full\` |
598
+ | pinned | \`pinned.md\` — critical context injected into ALL agent prompts | \`GET /api/pinned\` |
599
+ | meetings | \`meetings/\` — structured multi-round agent debates (investigate → debate → conclude) | \`GET /api/meetings\` |
600
+
601
+ **Contract:** For any term in this table, resolve it against Minions state first. Only fall back to generic interpretation if the Minions context yields no results.
602
+
579
603
  ## Rules
580
604
 
581
605
  1. **Use tools proactively.** Read files before answering — don't guess from the state snapshot alone.
@@ -611,6 +635,22 @@ function buildCCStatePreamble() {
611
635
  ? schedules.map(s => `- ${s.id}: "${s.title}" (cron: ${s.cron}, type: ${s.type || 'implement'}, ${s.enabled === false ? 'disabled' : 'enabled'})`).join('\n')
612
636
  : '(none configured)';
613
637
 
638
+ let pipelineSummary = '(none configured)';
639
+ try {
640
+ const { getPipelines, getPipelineRuns } = require('./engine/pipeline');
641
+ const pipelines = getPipelines();
642
+ if (pipelines.length > 0) {
643
+ const runs = getPipelineRuns();
644
+ pipelineSummary = pipelines.map(p => {
645
+ const pRuns = runs[p.id] || [];
646
+ const lastRun = pRuns.length > 0 ? pRuns[pRuns.length - 1] : null;
647
+ const lastStatus = lastRun ? ` (last run: ${lastRun.status})` : '';
648
+ const triggerInfo = p.trigger && p.trigger.cron ? `, cron: ${p.trigger.cron}` : ', manual';
649
+ return `- ${p.id}: "${p.title}" (${p.stages ? p.stages.length : 0} stages${triggerInfo}, ${p.enabled === false ? 'disabled' : 'enabled'})${lastStatus}`;
650
+ }).join('\n');
651
+ }
652
+ } catch {}
653
+
614
654
  return `### Agents
615
655
  ${agents}
616
656
 
@@ -627,6 +667,9 @@ ${projects}
627
667
  ### Scheduled Tasks
628
668
  ${schedSummary}
629
669
 
670
+ ### Pipelines
671
+ ${pipelineSummary}
672
+
630
673
  ### Dashboard API (all endpoints)
631
674
  ${_getApiRoutesSummary()}
632
675
 
package/engine.js CHANGED
@@ -576,12 +576,27 @@ function spawnAgent(dispatchItem, config) {
576
576
  delete procInfo._steeringMessage;
577
577
  delete procInfo._steeringSessionId;
578
578
 
579
+ // Guard: can't resume without a session
580
+ if (!steerSessionId) {
581
+ log('warn', `Steering: no sessionId for ${agentId} — appending message to live output only`);
582
+ try { fs.appendFileSync(liveOutputPath, `\n[steering-failed] No session to resume. Message was: ${steerMsg}\n`); } catch {}
583
+ activeProcesses.delete(id);
584
+ completeDispatch(id, DISPATCH_RESULT.SUCCESS, 'Steering skipped (no session)', '', { processWorkItemFailure: false });
585
+ return;
586
+ }
587
+
579
588
  log('info', `Steering: re-spawning ${agentId} with --resume ${steerSessionId}`);
580
589
 
581
590
  // Write new prompt with steering message
582
591
  const steerPrompt = `Message from your human teammate:\n\n${steerMsg}\n\nRespond to this, then continue working on your current task.`;
583
592
  const steerPromptPath = path.join(ENGINE_DIR, 'tmp', `prompt-steer-${safeId}.md`);
584
- safeWrite(steerPromptPath, steerPrompt);
593
+ try { safeWrite(steerPromptPath, steerPrompt); } catch (e) {
594
+ log('warn', `Steering: failed to write prompt for ${agentId}: ${e.message}`);
595
+ try { fs.appendFileSync(liveOutputPath, `\n[steering-failed] Could not write prompt. Message was: ${steerMsg}\n`); } catch {}
596
+ activeProcesses.delete(id);
597
+ completeDispatch(id, DISPATCH_RESULT.SUCCESS, 'Steering prompt write failed', '', { processWorkItemFailure: false });
598
+ return;
599
+ }
585
600
 
586
601
  // Build resume args
587
602
  const resumeArgs = [
@@ -595,11 +610,21 @@ function spawnAgent(dispatchItem, config) {
595
610
 
596
611
  const spawnScript = path.join(ENGINE_DIR, 'spawn-agent.js');
597
612
  const childEnv = shared.cleanChildEnv();
598
- const resumeProc = runFile(process.execPath, [spawnScript, steerPromptPath, steerPromptPath, ...resumeArgs], {
599
- cwd,
600
- stdio: ['pipe', 'pipe', 'pipe'],
601
- env: childEnv,
602
- });
613
+ let resumeProc;
614
+ try {
615
+ resumeProc = runFile(process.execPath, [spawnScript, steerPromptPath, steerPromptPath, ...resumeArgs], {
616
+ cwd,
617
+ stdio: ['pipe', 'pipe', 'pipe'],
618
+ env: childEnv,
619
+ });
620
+ } catch (e) {
621
+ log('warn', `Steering: spawn failed for ${agentId}: ${e.message}`);
622
+ try { fs.appendFileSync(liveOutputPath, `\n[steering-failed] Spawn error: ${e.message}. Message was: ${steerMsg}\n`); } catch {}
623
+ try { fs.unlinkSync(steerPromptPath); } catch {}
624
+ activeProcesses.delete(id);
625
+ completeDispatch(id, DISPATCH_RESULT.SUCCESS, 'Steering spawn failed', '', { processWorkItemFailure: false });
626
+ return;
627
+ }
603
628
 
604
629
  // Re-attach to existing tracking
605
630
  activeProcesses.set(id, { proc: resumeProc, agentId, startedAt: procInfo.startedAt, sessionId: steerSessionId, _steeringAt: Date.now() });
@@ -635,6 +660,7 @@ function spawnAgent(dispatchItem, config) {
635
660
  try { fs.unlinkSync(steerPromptPath); } catch { /* cleanup */ }
636
661
  if (resumeCode !== 0) {
637
662
  log('warn', `Steering resume for ${agentId} exited with code ${resumeCode} | stderr: ${stderr.slice(-300).replace(/\n/g, ' ')}`);
663
+ try { fs.appendFileSync(liveOutputPath, `\n[steering-failed] Resume exited with code ${resumeCode}. Your message was received but the agent could not continue the session.\n`); } catch {}
638
664
  activeProcesses.delete(id);
639
665
  completeDispatch(id, DISPATCH_RESULT.SUCCESS, 'Steering resume failed but original work completed', '', { processWorkItemFailure: false });
640
666
  return;
@@ -644,6 +670,7 @@ function spawnAgent(dispatchItem, config) {
644
670
  });
645
671
  resumeProc.on('error', (err) => {
646
672
  log('warn', `Steering re-spawn error for ${agentId}: ${err.message}`);
673
+ try { fs.appendFileSync(liveOutputPath, `\n[steering-failed] Spawn error: ${err.message}. Your message was received but the agent could not resume.\n`); } catch {}
647
674
  activeProcesses.delete(id);
648
675
  completeDispatch(id, DISPATCH_RESULT.SUCCESS, 'Steering re-spawn error but original work completed', '', { processWorkItemFailure: false });
649
676
  });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.498",
3
+ "version": "0.1.500",
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"