@yemi33/minions 0.1.2177 → 0.1.2178

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/engine/shared.js CHANGED
@@ -2369,9 +2369,31 @@ const ENGINE_DEFAULTS = {
2369
2369
  autoFixConflicts: true, // auto-dispatch fix agents when a PR has merge conflicts
2370
2370
  autoFixBuilds: true, // auto-dispatch fix agents when a PR build fails
2371
2371
  autoReviewPrs: true, // auto-dispatch review agents for newly opened agent PRs
2372
+ // P-a1f3c2d4 — hard-stop polling kill-switch / master override. When true,
2373
+ // section 2.6 (pollPrStatus) and 2.7 (pollPrHumanComments) skip both
2374
+ // providers regardless of adoPollEnabled / ghPollEnabled, and
2375
+ // discoverFromPrs treats pollEnabled as false for every project so the
2376
+ // downstream auto-dispatch gates (autoFixBuilds / autoFixConflicts /
2377
+ // autoReviewPrs / autoFixReviewFeedback / autoFixHumanComments) all
2378
+ // become inert. Default false so a fresh install behaves identically to
2379
+ // before this knob existed. Flip via Dashboard → Settings → Polling, or
2380
+ // set `engine.pollingPaused: true` in config.json. Reconciliation still
2381
+ // runs (it's a recovery sweep, not a convenience poll) — see section 2.7.
2382
+ pollingPaused: false, // hard-stop kill-switch / master override (see comment above)
2372
2383
  autoReReviewPrs: true, // auto-dispatch review agents after a PR fix is pushed
2373
2384
  autoFixReviewFeedback: true, // auto-dispatch fix agents for minions review changes-requested verdicts
2374
2385
  autoFixHumanComments: true, // auto-dispatch fix agents for actionable human PR comments
2386
+ // P-b2e5d8c7 — hard-stop auto-fix kill-switch / master override. When true,
2387
+ // discoverFromPrs treats every auto-fix gate (autoFixBuilds /
2388
+ // autoFixConflicts / autoFixReviewFeedback / autoFixHumanComments) as false
2389
+ // for every project, so no fix agent is auto-dispatched against any PR.
2390
+ // Review polling, review dispatch (autoReviewPrs / autoReReviewPrs), and
2391
+ // reconciliation are intentionally NOT gated — operators can pause the
2392
+ // fix-storm during an incident while still seeing fresh PR status and
2393
+ // review verdicts. Default false so a fresh install behaves identically
2394
+ // to before this knob existed. Flip via Dashboard → Settings → Auto-fix
2395
+ // & Review Loop, or set `engine.autoFixPaused: true` in config.json.
2396
+ autoFixPaused: false, // hard-stop kill-switch / master override (see comment above)
2375
2397
  autoConsolidateMemory: false, // opt-in: periodically spawn engine/kb-sweep-runner.js from the tick loop (4h cadence). Inbox→notes consolidation already runs every tick via consolidateInbox; this flag only controls the KB sweep.
2376
2398
  prNoOpFixPauseAttempts: 2, // pause one PR automation cause after repeated no-op fixes for unchanged evidence
2377
2399
  quarantineAutoRecoveryMax: 2, // #2996 follow-up: cap on auto-flipping WORKTREE_DIRTY/WORKTREE_DIVERGENT failures back to pending (the quarantine is self-healing so the next dispatch starts clean; the cap prevents infinite loops if quarantine itself keeps failing).
@@ -2468,6 +2490,39 @@ const ENGINE_DEFAULTS = {
2468
2490
  maxBuildFixRetries: 3,
2469
2491
  adoPollEnabled: true, // poll ADO PR status, comments, and reconciliation on each tick cycle
2470
2492
  ghPollEnabled: true, // poll GitHub PR status, comments, and reconciliation on each tick cycle
2493
+ // P-c4d8e1a3 — granular per-poller flags for the 6 PR-poll axes + rebase
2494
+ // processor. Each one defaults true and silently inherits a `false` from
2495
+ // its legacy bundle macro (adoPollEnabled / ghPollEnabled) for backward
2496
+ // compat, so existing config.json knobs keep working. New behavior:
2497
+ // setting `adoPollEnabled: false` (or `ghPollEnabled: false`) alone now
2498
+ // also silences the matching reconcile sweep — operators who want the
2499
+ // recovery sweep back must explicitly set `adoPrReconcileEnabled: true`
2500
+ // (or `ghPrReconcileEnabled: true`). processPendingRebasesEnabled has no
2501
+ // legacy counterpart; the rebase processor was previously ungated. See
2502
+ // shared.resolvePollFlag for the resolution order and the per-axis
2503
+ // surfaces in engine.js section 2.6 / 2.7.
2504
+ adoPrStatusPollEnabled: true,
2505
+ adoPrCommentsPollEnabled: true,
2506
+ adoPrReconcileEnabled: true,
2507
+ ghPrStatusPollEnabled: true,
2508
+ ghPrCommentsPollEnabled: true,
2509
+ ghPrReconcileEnabled: true,
2510
+ processPendingRebasesEnabled: true,
2511
+ // P-d6f0a2b5 — granular work-discovery flags. Each one gates a single
2512
+ // discovery phase inside `engine.discoverWork()`. Default true so the
2513
+ // out-of-box tick behaviour is unchanged; flip OFF via
2514
+ // `config.engine.<flag>` to silence a single discovery source without
2515
+ // touching the per-project `project.workSources.*.enabled` toggles
2516
+ // (those keep composing independently inside the matching discoverFrom*
2517
+ // helper — a `false` at either level skips the call). Wired inline as
2518
+ // `config.engine?.<flag> !== false` at each call site —
2519
+ // shared.resolvePollFlag is intentionally NOT used here because no
2520
+ // legacy macro bundle ever covered these phases.
2521
+ prDiscoveryEnabled: true, // discoverFromPrs (per-project PR-driven fix/review/test discovery)
2522
+ workItemsDiscoveryEnabled: true, // discoverFromWorkItems (per-project work-items.json scan)
2523
+ centralWorkDiscoveryEnabled: true, // discoverCentralWorkItems (top-level work-items.json scan)
2524
+ scheduledWorkDiscoveryEnabled: true, // discoverScheduledWork (cron-style scheduled tasks + meetings)
2525
+ planMaterializationEnabled: true, // reconcilePrdStatuses + materializePlansAsWorkItems pair
2471
2526
  prPollStatusEvery: 72, // poll PR build/review/merge status every N ticks for both ADO and GitHub (~12 min at default 10s tick)
2472
2527
  prPollCommentsEvery: 72, // poll PR human comments every N ticks for both ADO and GitHub (~12 min at default 10s tick)
2473
2528
  // W-mpxpckey000laa4f: lifted inline tick-counter literals to named constants
@@ -2522,6 +2577,26 @@ const ENGINE_DEFAULTS = {
2522
2577
  agentBusyReassignMs: 600000, // 10min — reassign work item to another agent if preferred agent is busy beyond this threshold
2523
2578
  ccEffort: null, // effort level for CC/doc-chat (null, 'low', 'medium', 'high')
2524
2579
  enablePreDispatchEval: true, // P-d2a9f6e5: cheap LLM gate before queueing — on by default. See engine/pre-dispatch-eval.js (Ripley §3 recommendation, 2026-05-11 architecture review). Validates from acceptance_criteria when present, falls back to description when criteria are absent but description is rich (≥80 chars). Fail-open on any validator error.
2580
+ // W-mq9acoo800177bcb — bounded-concurrency for the pre-dispatch validator. The
2581
+ // discoverWork loop in engine.js used to run validateAcceptanceCriteria
2582
+ // sequentially, costing ~25-30s per item × N items per tick (an 11-item
2583
+ // approved PRD took ~5 min to queue). This caps the parallel LLM calls per
2584
+ // tick — 6 is a balance between LLM-provider concurrency tolerance and not
2585
+ // starving the rest of the tick budget. Clamped to [1, 20] in
2586
+ // dashboard.js#handleSettingsUpdate; engine.js#resolvePreDispatchEvalConcurrency
2587
+ // applies the same clamp at read time so a hand-edited config can't bypass it.
2588
+ preDispatchEvalConcurrency: 6,
2589
+ // W-mq9acoo800177bcb — short-circuit the validator for items materialized
2590
+ // from an approved/active PRD. plan-to-prd already LLM-vets every item that
2591
+ // lands in a PRD, so re-validating each item per discovery tick is the
2592
+ // dominant cost of the workflow that triggered this optimization (user-
2593
+ // observed: 2 PRDs / 11 items → ~5 min queueing). Items keep the
2594
+ // `_preDispatchEvalSkipped: 'prd-sourced'` marker on their dispatch entry for
2595
+ // observability. The bypass fires only when item.meta.item.sourcePlan is set
2596
+ // AND the parent PRD's status is approved/active; rejected/paused/revision-
2597
+ // requested/completed PRDs still flow through the normal validator path so a
2598
+ // stale PRD reopen can't smuggle in unvetted items.
2599
+ preDispatchEvalSkipPrdSourced: true,
2525
2600
  completionNonceRequired: false, // P-d2a8f6c1 (agent trust boundary F8): when true, a missing `nonce` field in the completion JSON hard-fails the dispatch with failure_class:'completion-nonce-mismatch'. Default false for one release so older agents/runtime caches that haven't picked up the prompt change degrade with a warning instead of breaking. Mismatched nonces hard-fail regardless of this flag. See docs/completion-reports.md → "Trust boundary".
2526
2601
  autoApplyReviewVote: false, // W-mpea9fyb0010febf / P-f7splitgate: gates POSITIVE auto-actions only — when true, the engine mirrors live platform vote state into local pull-requests.json reviewStatus (so platform-side approves auto-promote local status). When false (default), the verdict is recorded in pull-requests.json reviewStatus from the agent's completion only — informational. NEGATIVE-correction (dismissing the engine's own prior REQUEST_CHANGES / resetting its own prior negative ADO vote on a verdict flip to APPROVE) is correctness and runs UNCONDITIONALLY regardless of this flag.
2527
2602
 
@@ -2541,6 +2616,20 @@ const ENGINE_DEFAULTS = {
2541
2616
  copilotSuppressAgentsMd: true, // Copilot --no-custom-instructions: stop AGENTS.md auto-load from fighting Minions playbook prompts
2542
2617
  copilotStreamMode: 'on', // Copilot --stream <on|off>: 'on' streams assistant.message_delta events live; 'off' batches them
2543
2618
  copilotReasoningSummaries: false, // Copilot --enable-reasoning-summaries (Anthropic-family models only)
2619
+ // P-mcp-storm — Copilot loads `~/.copilot/mcp-config.json` (the operator's
2620
+ // user-scope MCP servers) UNCONDITIONALLY on every process start: it is NOT
2621
+ // gated by `--add-dir`, cwd, or `hermeticHarness` (proven empirically — a
2622
+ // copilot spawned from a neutral dir with no `--add-dir ~/.copilot` still
2623
+ // connects every server). So every spawned Copilot agent boots the operator's
2624
+ // full interactive MCP stack; on Windows each `type:local`/`stdio` server
2625
+ // (e.g. playwright, maestro) launches its own visible console window and
2626
+ // playwright opens browser tabs. The only lever Copilot exposes is
2627
+ // `--disable-mcp-server <name>` (repeatable). This list names the servers the
2628
+ // engine disables for autonomous agent dispatches. Default [] = inherit ALL
2629
+ // (no behavior change). Per-agent override `agent.copilotAgentDisabledMcpServers`.
2630
+ // Resolved through `shared.resolveCopilotAgentDisabledMcpServers(agent, engine)`.
2631
+ // NOTE: `hermeticHarness` does NOT suppress these (it only strips `--add-dir`).
2632
+ copilotAgentDisabledMcpServers: [],
2544
2633
  ccUseWorkerPool: false, // Sub-task C of W-mp2w003600196c51 (CC perf): when true AND CC runtime is copilot, _invokeCcStream routes through engine/cc-worker-pool.js (persistent `copilot --acp` per CC tab) instead of spawning a fresh CLI per turn. Off by default — opt-in feature flag. **Structurally copilot-only**: the pool spawns `copilot --acp` (Agent Client Protocol); Claude Code does not implement ACP, so resolveCcUseWorkerPool returns false on non-copilot CC runtimes even with explicit-true (W-mphlriic00095f69 — prevents silent runtime switch). Engine/agent dispatch path stays per-process regardless.
2545
2634
  maxBudgetUsd: undefined, // fleet USD ceiling for --max-budget-usd (per-agent override: agents.<id>.maxBudgetUsd). Honors 0 via ?? so a literal cap of $0 works
2546
2635
  disableModelDiscovery: false, // skip runtime.listModels() REST calls fleet-wide (settings UI falls back to free-text)
@@ -2770,6 +2859,31 @@ const ENGINE_DEFAULTS = {
2770
2859
  operatorLogin: null,
2771
2860
  };
2772
2861
 
2862
+ // ── P-c4d8e1a3: granular per-poller flag resolution ──────────────────────────
2863
+ //
2864
+ // Helper for the 6 PR-poll axes + processPendingRebases. Each axis has a
2865
+ // granular `*Enabled` flag in ENGINE_DEFAULTS (default true) plus an
2866
+ // optional legacy bundle macro (`adoPollEnabled` / `ghPollEnabled`) that
2867
+ // silences the matching ADO/GitHub trio when set to false. Resolution
2868
+ // order, in priority:
2869
+ //
2870
+ // 1. granular key explicitly present on engineCfg → use it
2871
+ // 2. legacyMacroKey is set on engineCfg AND === false → false
2872
+ // (legacy users keep working — and now reconcile is silenced too)
2873
+ // 3. fall through to ENGINE_DEFAULTS[granularKey] (default true)
2874
+ //
2875
+ // legacyMacroKey may be `null` for axes that have no legacy counterpart
2876
+ // (today: processPendingRebasesEnabled).
2877
+ function resolvePollFlag(engineCfg, granularKey, legacyMacroKey) {
2878
+ if (engineCfg && Object.prototype.hasOwnProperty.call(engineCfg, granularKey)) {
2879
+ return engineCfg[granularKey] !== false;
2880
+ }
2881
+ if (legacyMacroKey && engineCfg && engineCfg[legacyMacroKey] === false) {
2882
+ return false;
2883
+ }
2884
+ return ENGINE_DEFAULTS[granularKey] !== false;
2885
+ }
2886
+
2773
2887
  // ─── Runtime Fleet Resolution (P-3b8e5f1d) ──────────────────────────────────
2774
2888
  //
2775
2889
  // Six helpers that are the single source of truth for "which CLI runtime + model
@@ -2921,6 +3035,36 @@ function resolveAgentBareMode(agent, engine) {
2921
3035
  return false;
2922
3036
  }
2923
3037
 
3038
+ // P-mcp-storm — Resolve the list of MCP server names to disable for spawned
3039
+ // Copilot agents (emitted as `--disable-mcp-server <name>`). Chain: per-agent
3040
+ // `agent.copilotAgentDisabledMcpServers` → `engine.copilotAgentDisabledMcpServers`
3041
+ // → `[]` (inherit all). Tolerant of either an array OR a comma/whitespace-
3042
+ // separated string (Settings UI / `MINIONS_*` env deliver strings). Always
3043
+ // returns a deduped array of trimmed, non-empty strings. See ENGINE_DEFAULTS
3044
+ // for why this exists (Copilot loads ~/.copilot MCP config unconditionally;
3045
+ // `hermeticHarness` does NOT suppress it).
3046
+ function _normalizeMcpServerList(v) {
3047
+ if (v == null) return null;
3048
+ const raw = Array.isArray(v) ? v : String(v).split(/[\s,]+/);
3049
+ const out = [];
3050
+ const seen = new Set();
3051
+ for (const item of raw) {
3052
+ const name = String(item == null ? '' : item).trim();
3053
+ if (!name || seen.has(name)) continue;
3054
+ seen.add(name);
3055
+ out.push(name);
3056
+ }
3057
+ return out;
3058
+ }
3059
+
3060
+ function resolveCopilotAgentDisabledMcpServers(agent, engine) {
3061
+ const a = agent ? _normalizeMcpServerList(agent.copilotAgentDisabledMcpServers) : null;
3062
+ if (a) return a;
3063
+ const e = engine ? _normalizeMcpServerList(engine.copilotAgentDisabledMcpServers) : null;
3064
+ if (e) return e;
3065
+ return [];
3066
+ }
3067
+
2924
3068
  // ─── Legacy ccModel → defaultModel Migration ─────────────────────────────────
2925
3069
  //
2926
3070
  // Pre-P-3b8e5f1d, `engine.ccModel` was the single fleet-wide model knob (it
@@ -3704,6 +3848,49 @@ function extractPlanDeclaredProject(planContent) {
3704
3848
  }
3705
3849
  return '';
3706
3850
  }
3851
+
3852
+ // P-7a3f1c08: Parse a cross-repo plan's list of target projects.
3853
+ // Primary signal: `<!-- minions:targetProjects=a, b, c -->` HTML comment.
3854
+ // Fallback (human): `**Projects:** a, b | c` markdown line in the first 80 lines.
3855
+ // Both forms accept `,`, `|`, or `;` as separators with surrounding whitespace.
3856
+ // Returns string[] of trimmed project names (empty array when nothing parseable).
3857
+ function extractPlanTargetProjects(planContent) {
3858
+ if (typeof planContent !== 'string' || !planContent.trim()) return [];
3859
+
3860
+ const split = (raw) => {
3861
+ if (typeof raw !== 'string') return [];
3862
+ return raw
3863
+ .split(/[,|;]/)
3864
+ .map(s => s.trim().replace(/^["'`]+|["'`]+$/g, '').trim())
3865
+ .filter(Boolean);
3866
+ };
3867
+
3868
+ // Primary signal: structured HTML comment marker (case-insensitive on the key).
3869
+ const markerMatch = planContent.match(/<!--\s*minions:targetProjects\s*=\s*([^>]*?)\s*-->/i);
3870
+ if (markerMatch) {
3871
+ const parsed = split(markerMatch[1]);
3872
+ if (parsed.length > 0) return parsed;
3873
+ }
3874
+
3875
+ // Fallback signal: human-readable plural `Projects:` line — distinct from the
3876
+ // singular `Project:` line consumed by extractPlanDeclaredProject. Scan the
3877
+ // first 80 lines, matching the same leading-bullet / bold-markdown tolerance.
3878
+ const lines = planContent.split(/\r?\n/).slice(0, 80);
3879
+ for (const rawLine of lines) {
3880
+ const line = rawLine
3881
+ .replace(/^\s*[-*]\s+/, '')
3882
+ .replace(/\*\*/g, '')
3883
+ .trim();
3884
+ const match = line.match(/^Projects\s*:\s*(.+)$/i);
3885
+ if (!match) continue;
3886
+ let value = match[1].trim();
3887
+ value = value.replace(/\s+#.*$/, '').trim();
3888
+ const parsed = split(value);
3889
+ if (parsed.length > 0) return parsed;
3890
+ }
3891
+
3892
+ return [];
3893
+ }
3707
3894
  const DISPATCH_RESULT = { SUCCESS: 'success', ERROR: 'error', TIMEOUT: 'timeout' };
3708
3895
  const PIPELINE_STATUS = {
3709
3896
  PENDING: 'pending', RUNNING: 'running', COMPLETED: 'completed',
@@ -7504,14 +7691,16 @@ module.exports = {
7504
7691
  KB_READABLE_CATEGORIES,
7505
7692
  classifyInboxItem,
7506
7693
  ENGINE_DEFAULTS,
7694
+ resolvePollFlag, // P-c4d8e1a3 — granular per-poller flag resolution
7507
7695
  resolveAgentCli, resolveCcCli, resolveCcUseWorkerPool, resolveAgentModel, resolveCcModel,
7508
7696
  resolveAgentMaxBudget, resolveAgentBareMode,
7697
+ resolveCopilotAgentDisabledMcpServers,
7509
7698
  applyLegacyCcModelMigration, _resetLegacyCcModelMigrationFlag,
7510
7699
  applyCcWorkerPoolForceOnMigration,
7511
7700
  runtimeConfigWarnings,
7512
7701
  projectWorkSourceWarnings,
7513
7702
  backfillProjectWorkSourceDefaults,
7514
- WI_STATUS, DONE_STATUSES, PLAN_TERMINAL_STATUSES, WORK_TYPE, WORKTREE_REQUIRING_TYPES, VALID_WORK_TYPES, resolveWorkItemTypeFromPrdItem, PLAN_STATUS, PRD_ITEM_STATUS, PRD_MATERIALIZABLE, PR_STATUS, PR_POLLABLE_STATUSES, PR_PENDING_REASON, BUILD_STATUS, REVIEW_STATUS, FETCH_TIMEOUT_MS, RETRY_DELAY_MS, ADO_TOKEN_REFRESH_MAX_RETRIES, DISPATCH_RESULT, mutateMetrics, mutateWatches, mutateScheduleRuns, mutatePipelineRuns, mutateManagedProcesses, mutateWorktreePool, mutateQaRuns, mutateQaSessions, trackReviewMetric, queuePlanToPrd, extractPlanDeclaredProject,
7703
+ WI_STATUS, DONE_STATUSES, PLAN_TERMINAL_STATUSES, WORK_TYPE, WORKTREE_REQUIRING_TYPES, VALID_WORK_TYPES, resolveWorkItemTypeFromPrdItem, PLAN_STATUS, PRD_ITEM_STATUS, PRD_MATERIALIZABLE, PR_STATUS, PR_POLLABLE_STATUSES, PR_PENDING_REASON, BUILD_STATUS, REVIEW_STATUS, FETCH_TIMEOUT_MS, RETRY_DELAY_MS, ADO_TOKEN_REFRESH_MAX_RETRIES, DISPATCH_RESULT, mutateMetrics, mutateWatches, mutateScheduleRuns, mutatePipelineRuns, mutateManagedProcesses, mutateWorktreePool, mutateQaRuns, mutateQaSessions, trackReviewMetric, queuePlanToPrd, extractPlanDeclaredProject, extractPlanTargetProjects,
7515
7704
  WATCH_STATUS, WATCH_TARGET_TYPE, WATCH_CONDITION, WATCH_ABSOLUTE_CONDITIONS, WATCH_ACTION_TYPE,
7516
7705
  WATCH_STALLED_DEFAULT_TICKS, WATCH_STUCK_STAGE_DEFAULT_TICKS,
7517
7706
  PIPELINE_STATUS, STAGE_TYPE, MEETING_STATUS, AGENT_STATUS,