@yemi33/minions 0.1.1719 → 0.1.1721

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,13 +1,19 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1719 (2026-05-04)
3
+ ## 0.1.1721 (2026-05-05)
4
+
5
+ ### Fixes
6
+ - gate PR-derived dispatch on provider polling for both ADO and GitHub
7
+
8
+ ## 0.1.1720 (2026-05-04)
4
9
 
5
10
  ### Features
6
- - fix stale Claude caps native inference (#2063)
7
- - prevent deferred steering crash (#2060)
11
+ - separate GitHub and ADO project fields (#2065)
8
12
 
9
- ### Fixes
10
- - filter agent failure classification (#2064)
13
+ ## 0.1.1718 (2026-05-04)
14
+
15
+ ### Features
16
+ - prevent deferred steering crash (#2060)
11
17
 
12
18
  ## 0.1.1716 (2026-05-04)
13
19
 
@@ -94,17 +94,17 @@ async function openSettings() {
94
94
  '<h3 style="font-size:13px;color:var(--blue);margin-bottom:8px">PR Polling &amp; Dispatch Gates</h3>' +
95
95
  '<div style="border:1px solid var(--border);border-radius:6px;padding:10px 12px;margin-bottom:16px">' +
96
96
  '<div style="display:flex;flex-direction:column;gap:6px;margin-bottom:10px">' +
97
- settingsToggle('ADO Polling', 'set-adoPollEnabled', e.adoPollEnabled !== false, 'Keeps ADO PR build results, votes, and comments fresh each tick the two fix gates below are silently inert when this is off') +
98
- '<div style="margin-left:20px;padding-left:10px;border-left:2px solid var(--border);display:flex;flex-direction:column;gap:4px">' +
99
- settingsToggle('Auto-fix Builds', 'set-autoFixBuilds', e.autoFixBuilds !== false, 'Dispatch gate: auto-fix agent when build fails (downstream of ADO Polling)') +
100
- settingsToggle('Auto-fix Conflicts', 'set-autoFixConflicts', e.autoFixConflicts !== false, 'Dispatch gate: auto-fix agent when merge conflict detected (downstream of ADO Polling)') +
101
- settingsToggle('Auto-review PRs', 'set-autoReviewPrs', e.autoReviewPrs !== false, 'Dispatch gate: review agent for newly opened agent PRs (throttle-aware)') +
102
- settingsToggle('Auto-re-review PRs', 'set-autoReReviewPrs', e.autoReReviewPrs !== false, 'Dispatch gate: review agent after a fix push is awaiting re-review (throttle-aware)') +
103
- settingsToggle('Auto-fix Review Feedback', 'set-autoFixReviewFeedback', e.autoFixReviewFeedback !== false, 'Dispatch gate: fix agent for minions changes-requested verdicts (throttle-aware)') +
104
- settingsToggle('Auto-fix Human Comments', 'set-autoFixHumanComments', e.autoFixHumanComments !== false, 'Dispatch gate: fix agent for actionable human PR comments (throttle-aware)') +
105
- '</div>' +
97
+ settingsToggle('ADO Polling', 'set-adoPollEnabled', e.adoPollEnabled !== false, 'Keeps ADO PR build results, votes, and comments fresh each tick; ADO PR dispatch gates are inert when this is off') +
98
+ settingsToggle('GitHub Polling', 'set-ghPollEnabled', e.ghPollEnabled !== false, 'Keeps GitHub PR build results, votes, and comments fresh each tick; GitHub PR dispatch gates are inert when this is off') +
99
+ '</div>' +
100
+ '<div style="margin-top:10px;padding-top:10px;border-top:1px solid var(--border);display:flex;flex-direction:column;gap:4px">' +
101
+ settingsToggle('Auto-fix Builds', 'set-autoFixBuilds', e.autoFixBuilds !== false, 'Shared dispatch gate: auto-fix agent when a PR build fails; also requires that PR provider polling is enabled') +
102
+ settingsToggle('Auto-fix Conflicts', 'set-autoFixConflicts', e.autoFixConflicts !== false, 'Shared dispatch gate: auto-fix agent when a PR merge conflict is detected; also requires that PR provider polling is enabled') +
103
+ settingsToggle('Auto-review PRs', 'set-autoReviewPrs', e.autoReviewPrs !== false, 'Shared dispatch gate: review agent for newly opened agent PRs; also requires that PR provider polling is enabled') +
104
+ settingsToggle('Auto-re-review PRs', 'set-autoReReviewPrs', e.autoReReviewPrs !== false, 'Shared dispatch gate: review agent after a fix push is awaiting re-review; also requires that PR provider polling is enabled') +
105
+ settingsToggle('Auto-fix Review Feedback', 'set-autoFixReviewFeedback', e.autoFixReviewFeedback !== false, 'Shared dispatch gate: fix agent for minions changes-requested verdicts; also requires that PR provider polling is enabled') +
106
+ settingsToggle('Auto-fix Human Comments', 'set-autoFixHumanComments', e.autoFixHumanComments !== false, 'Shared dispatch gate: fix agent for actionable human PR comments; also requires that PR provider polling is enabled') +
106
107
  '</div>' +
107
- settingsToggle('GitHub Polling', 'set-ghPollEnabled', e.ghPollEnabled !== false, 'Keeps GitHub PR build results, votes, and comments fresh each tick (reconciliation always runs regardless)') +
108
108
  '<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-top:10px">' +
109
109
  settingsField('PR Status Poll Frequency', 'set-prPollStatusEvery', e.prPollStatusEvery ?? e.adoPollStatusEvery ?? 12, 'ticks', 'Poll PR build/review/merge status every N ticks for both ADO and GitHub (~12 min at default tick rate)') +
110
110
  settingsField('PR Comments Poll Frequency', 'set-prPollCommentsEvery', e.prPollCommentsEvery ?? e.adoPollCommentsEvery ?? 12, 'ticks', 'Poll PR human comments every N ticks for both ADO and GitHub (~12 min at default tick rate)') +
package/dashboard.js CHANGED
@@ -4927,20 +4927,16 @@ What would you like to discuss or change? When you're happy, say "approve" and I
4927
4927
  return jsonReply(res, e.statusCode || 400, { error: e.message });
4928
4928
  }
4929
4929
 
4930
- const project = {
4931
- name, description, localPath: target.replace(/\\/g, '/'),
4932
- repoHost: detected.repoHost || 'ado', repositoryId: detected.repositoryId || '',
4933
- adoOrg: detected.org || '', adoProject: detected.project || '',
4934
- repoName: detected.repoName || name, mainBranch: detected.mainBranch || 'main',
4935
- prUrlBase: projectDiscovery.buildPrUrlBase({
4936
- repoHost: detected.repoHost,
4937
- org: detected.org,
4938
- project: detected.project,
4939
- repoName: detected.repoName,
4940
- prUrlBase: detected.prUrlBase,
4941
- }),
4942
- workSources: { pullRequests: { enabled: true, cooldownMinutes: 30 }, workItems: { enabled: true, cooldownMinutes: 0 } }
4943
- };
4930
+ const project = projectDiscovery.buildProjectEntry({
4931
+ name, description, localPath: target,
4932
+ repoHost: detected.repoHost || 'github',
4933
+ repositoryId: detected.repositoryId || '',
4934
+ org: detected.org || '',
4935
+ project: detected.project || '',
4936
+ repoName: detected.repoName || name,
4937
+ mainBranch: detected.mainBranch || 'main',
4938
+ prUrlBase: detected.prUrlBase,
4939
+ });
4944
4940
 
4945
4941
  config.projects.push(project);
4946
4942
  safeWrite(configPath, config);
@@ -37,7 +37,7 @@ Before scanning, the engine materializes plans and specs into project work items
37
37
  | `_mergeConflict: true` | Route to author for conflict resolution | `fix` |
38
38
  Skips PRs where `status !== "active"`.
39
39
 
40
- Inside `discoverFromPrs()`, `evalLoop` / `evalMaxIterations` only gate the minion review loop: initial minion reviews, minion re-reviews, and minion review-feedback fixes. Human-feedback fixes are evaluated outside that gate, build failures use the separate `maxBuildFixAttempts` cap, and merge conflicts use the separate `autoFixConflicts` gate. Conflict fixes are additionally gated by `!fixDispatched`, so an earlier successful human/review/build fix dispatch in the same PR discovery pass suppresses the conflict fix until a later pass.
40
+ Inside `discoverFromPrs()`, ADO and GitHub projects first resolve their own provider poll gate (`adoPollEnabled` or `ghPollEnabled`). PR-derived automation is inert when that provider's polling is off, so cached build, vote, conflict, and comment state cannot trigger new dispatches. The shared dispatch toggles (`autoReviewPrs`, `autoReReviewPrs`, `autoFixReviewFeedback`, `autoFixHumanComments`, `autoFixBuilds`, and `autoFixConflicts`) apply to both providers. `evalLoop` gates the minion review loop: initial minion reviews, minion re-reviews, and minion review-feedback fixes. Human-feedback fixes are evaluated outside `evalLoop`. Conflict fixes are additionally gated by `!fixDispatched`, so an earlier successful human/review/build fix dispatch in the same PR discovery pass suppresses the conflict fix until a later pass.
41
41
 
42
42
  ### Source 2: PRD Gap Analysis (via `materializePlansAsWorkItems`)
43
43
 
@@ -54,7 +54,7 @@ When multiple problems coexist, earlier triggers get the first chance to enqueue
54
54
 
55
55
  ### C. Build failures (`buildStatus === 'failing'`)
56
56
 
57
- - Gate: `buildFixAttempts < maxBuildFixAttempts` (default 3) + grace period expired
57
+ - Gate: provider polling enabled (`adoPollEnabled` or `ghPollEnabled`) + `autoFixBuilds` + `buildStatus === 'failing'` + grace period expired
58
58
  - **Grace period** (`_buildFixPushedAt`): after fix dispatches, waits `buildFixGracePeriod` (default 10min, configurable in `ENGINE_DEFAULTS`) for CI to run before re-dispatching. Cleared when poller detects build status transition (CI actually ran).
59
59
  - **Error logs**: GitHub fetches annotations (failures only, not warnings) + Actions job log (always). ADO queries builds API directly (not status checks), fetches build timeline → failed task logs (up to 10 per build, up to 10 failing pipelines).
60
60
  - **Build-fix escalation**: after 3 failed attempts, writes an inbox alert, sets `buildFixEscalated = true`, and stops *only this trigger* (auto-dispatch for build fixes). The counter resets when the build recovers. Independent of `_evalEscalated`.
@@ -63,7 +63,7 @@ When multiple problems coexist, earlier triggers get the first chance to enqueue
63
63
 
64
64
  ### D. Merge conflicts (`_mergeConflict`)
65
65
 
66
- - Gate: `autoFixConflicts` + `status === 'active'` + `_mergeConflict` + `!fixDispatched`
66
+ - Gate: provider polling enabled (`adoPollEnabled` or `ghPollEnabled`) + `autoFixConflicts` + `status === 'active'` + `_mergeConflict` + `!fixDispatched`
67
67
  - Routes to the PR author to resolve target-branch conflicts
68
68
  - Runs after review, human, and build triggers; if any earlier trigger enqueued a fix for this PR, the conflict fix waits for a later discovery pass
69
69
 
package/engine/cli.js CHANGED
@@ -1181,8 +1181,9 @@ const commands = {
1181
1181
  project_name: targetProject.name || 'Unknown',
1182
1182
  project_path: targetProject.localPath || '',
1183
1183
  main_branch: targetProject.localPath ? shared.resolveMainBranch(targetProject.localPath, targetProject.mainBranch) : (targetProject.mainBranch || 'main'),
1184
- ado_org: targetProject.adoOrg || 'Unknown',
1185
- ado_project: targetProject.adoProject || 'Unknown',
1184
+ ado_org: targetProject.repoHost === 'ado' ? (targetProject.adoOrg || 'Unknown') : '',
1185
+ ado_project: targetProject.repoHost === 'ado' ? (targetProject.adoProject || 'Unknown') : '',
1186
+ github_org: targetProject.repoHost === 'github' ? (targetProject.githubOrg || targetProject.adoOrg || '') : '',
1186
1187
  repo_name: targetProject.repoName || 'Unknown',
1187
1188
  team_root: MINIONS_DIR,
1188
1189
  date: e.dateStamp(),
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "runtime": "copilot",
3
3
  "models": null,
4
- "cachedAt": "2026-05-04T23:03:44.791Z"
4
+ "cachedAt": "2026-05-05T00:49:43.073Z"
5
5
  }
package/engine/github.js CHANGED
@@ -5,7 +5,7 @@
5
5
  */
6
6
 
7
7
  const shared = require('./shared');
8
- const { exec, execAsync, getProjects, projectPrPath, projectWorkItemsPath, safeJson, safeWrite, mutateJsonFileLocked, MINIONS_DIR, getPrLinks, backfillPrPrdItems, log, ts, dateStamp, PR_STATUS, PR_POLLABLE_STATUSES, createThrottleTracker } = shared;
8
+ const { exec, execAsync, getProjects, projectPrPath, projectWorkItemsPath, safeJson, safeWrite, mutateJsonFileLocked, MINIONS_DIR, getPrLinks, backfillPrPrdItems, log, ts, dateStamp, PR_STATUS, PR_POLLABLE_STATUSES, createThrottleTracker, getProjectOrg } = shared;
9
9
  const { getPrs } = require('./queries');
10
10
  const path = require('path');
11
11
 
@@ -33,7 +33,7 @@ function isGitHub(project) {
33
33
 
34
34
  /** Get GitHub owner/repo slug from project config (e.g. "x3-design/Bebop_Workspaces") */
35
35
  function getRepoSlug(project) {
36
- const org = project.adoOrg || '';
36
+ const org = getProjectOrg(project);
37
37
  const repo = project.repoName || '';
38
38
  if (!org || !repo) return null;
39
39
  return `${org}/${repo}`;
@@ -10,7 +10,7 @@ const path = require('path');
10
10
  const shared = require('./shared');
11
11
  const queries = require('./queries');
12
12
 
13
- const { safeJson, safeRead, getProjects, log, ts, dateStamp, truncateTextBytes, ENGINE_DEFAULTS, WI_STATUS, WORK_TYPE, PR_STATUS, DISPATCH_RESULT } = shared;
13
+ const { safeJson, safeRead, getProjects, log, ts, dateStamp, truncateTextBytes, ENGINE_DEFAULTS, WI_STATUS, WORK_TYPE, PR_STATUS, DISPATCH_RESULT, getProjectOrg } = shared;
14
14
  const { getConfig, getDispatch, getNotes, getAgentCharter, getPrs, getKnowledgeBaseIndex, AGENTS_DIR } = queries;
15
15
 
16
16
  const MINIONS_DIR = shared.MINIONS_DIR;
@@ -29,7 +29,7 @@ function getPrCreateInstructions(project) {
29
29
  const host = getRepoHost(project);
30
30
  const repoId = project?.repositoryId || '';
31
31
  if (host === 'github') {
32
- const org = project?.adoOrg || '';
32
+ const org = getProjectOrg(project);
33
33
  const repo = project?.repoName || '';
34
34
  const mainBranch = project?.localPath ? shared.resolveMainBranch(project.localPath, project.mainBranch) : (project?.mainBranch || 'main');
35
35
  return `Use \`gh pr create\` to create a pull request:\n` +
@@ -56,7 +56,7 @@ function getPrCommentInstructions(project) {
56
56
  const host = getRepoHost(project);
57
57
  const repoId = project?.repositoryId || '';
58
58
  if (host === 'github') {
59
- const org = project?.adoOrg || '';
59
+ const org = getProjectOrg(project);
60
60
  const repo = project?.repoName || '';
61
61
  return `Use \`gh pr comment\` to post a comment on the PR:\n` +
62
62
  `- Write the Markdown comment to a temporary file, then run: \`gh pr comment <number> --body-file <body-file.md> --repo ${org}/${repo}\`\n` +
@@ -75,7 +75,7 @@ function getPrCommentInstructions(project) {
75
75
  function getPrFetchInstructions(project) {
76
76
  const host = getRepoHost(project);
77
77
  if (host === 'github') {
78
- const org = project?.adoOrg || '';
78
+ const org = getProjectOrg(project);
79
79
  const repo = project?.repoName || '';
80
80
  const mainBranch = project?.localPath ? shared.resolveMainBranch(project.localPath, project.mainBranch) : (project?.mainBranch || 'main');
81
81
  return `Use \`gh pr view\` to fetch PR status:\n` +
@@ -100,7 +100,7 @@ function getPrVoteInstructions(project) {
100
100
  const host = getRepoHost(project);
101
101
  const repoId = project?.repositoryId || '';
102
102
  if (host === 'github') {
103
- const org = project?.adoOrg || '';
103
+ const org = getProjectOrg(project);
104
104
  const repo = project?.repoName || '';
105
105
  return `**IMPORTANT: GitHub blocks self-approval** — all agents share the same credentials, so \`--approve\` and \`--request-changes\` will fail with "can't approve your own PR." Use \`--comment\` instead.\n\n` +
106
106
  `Submit your review verdict using \`gh pr review\` with \`--comment\`:\n` +
@@ -411,13 +411,15 @@ function renderPlaybook(type, vars) {
411
411
  ...dispatchProject,
412
412
  adoOrg: vars.ado_org || vars.adoOrg || dispatchProject.adoOrg,
413
413
  adoProject: vars.ado_project || vars.adoProject || dispatchProject.adoProject,
414
+ githubOrg: vars.github_org || vars.githubOrg || dispatchProject.githubOrg,
414
415
  repoName: vars.repo_name || vars.repoName || dispatchProject.repoName,
415
416
  repoHost: vars.repo_host || vars.repoHost || dispatchProject.repoHost,
416
417
  };
417
418
  const repoHost = getRepoHost(renderProject);
418
419
  const projectVars = {
419
420
  project_name: renderProject.name || 'Unknown Project',
420
- ado_org: renderProject.adoOrg || 'Unknown',
421
+ ado_org: repoHost === 'ado' ? (renderProject.adoOrg || 'Unknown') : '',
422
+ github_org: repoHost === 'github' ? getProjectOrg(renderProject) : '',
421
423
  ado_project: renderProject.adoProject || 'Unknown',
422
424
  repo_name: renderProject.repoName || 'Unknown',
423
425
  repo_host: repoHost,
@@ -503,7 +505,7 @@ function buildSystemPrompt(agentId, config, project) {
503
505
 
504
506
  // Project context (fixed size)
505
507
  prompt += `## Project: ${project.name || 'Unknown Project'}\n\n`;
506
- prompt += `- Repo: ${project.repoName || 'Unknown'} (${project.adoOrg || 'Unknown'}/${project.adoProject || 'Unknown'})\n`;
508
+ prompt += `- Repo: ${project.repoName || 'Unknown'} (${getProjectOrg(project) || 'Unknown'}${project.repoHost === 'ado' ? '/' + (project.adoProject || 'Unknown') : ''})\n`;
507
509
  prompt += `- Repo ID: ${project.repositoryId || ''}\n`;
508
510
  prompt += `- Repo host: ${getRepoHostLabel(project)}\n`;
509
511
  prompt += `- Main branch: ${project.mainBranch || 'main'}\n\n`;
@@ -648,8 +650,9 @@ function buildBaseVars(agentId, config, project) {
648
650
  team_root: MINIONS_DIR,
649
651
  repo_id: project?.repositoryId || '',
650
652
  project_name: project?.name || 'Unknown Project',
651
- ado_org: project?.adoOrg || 'Unknown',
652
- ado_project: project?.adoProject || 'Unknown',
653
+ ado_org: project?.repoHost === 'ado' ? (project?.adoOrg || 'Unknown') : '',
654
+ ado_project: project?.repoHost === 'ado' ? (project?.adoProject || 'Unknown') : '',
655
+ github_org: project?.repoHost === 'github' ? getProjectOrg(project) : '',
653
656
  repo_name: project?.repoName || 'Unknown',
654
657
  repo_host: getRepoHost(project),
655
658
  main_branch: project?.mainBranch || 'main',
@@ -332,17 +332,20 @@ function buildPrUrlBase({ repoHost, org, project, repoName, prUrlBase }) {
332
332
 
333
333
  function buildProjectEntry({ name, description, localPath, repoHost, repositoryId, org, project, repoName, mainBranch, prUrlBase }) {
334
334
  const safeName = (name || 'project').replace(/[^a-zA-Z0-9._-]/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '').slice(0, 60) || 'project';
335
+ const host = repoHost || 'github';
336
+ const isAdo = host === 'ado';
335
337
  return {
336
338
  name: safeName,
337
339
  description: description || '',
338
340
  localPath: (localPath || '').replace(/\\/g, '/'),
339
- repoHost: repoHost || 'github',
340
- repositoryId: repositoryId || '',
341
- adoOrg: org || '',
342
- adoProject: project || '',
341
+ repoHost: host,
342
+ repositoryId: isAdo ? (repositoryId || '') : '',
343
+ adoOrg: isAdo ? (org || '') : '',
344
+ adoProject: isAdo ? (project || '') : '',
345
+ githubOrg: !isAdo ? (org || '') : '',
343
346
  repoName: repoName || name,
344
347
  mainBranch: mainBranch || 'main',
345
- prUrlBase: buildPrUrlBase({ repoHost, org, project, repoName, prUrlBase }),
348
+ prUrlBase: buildPrUrlBase({ repoHost: host, org, project, repoName, prUrlBase }),
346
349
  workSources: {
347
350
  pullRequests: { enabled: true, cooldownMinutes: 30 },
348
351
  workItems: { enabled: true, cooldownMinutes: 0 },
package/engine/shared.js CHANGED
@@ -1477,6 +1477,13 @@ function nextWorkItemId(items, prefix) {
1477
1477
 
1478
1478
  // ── ADO URL ──────────────────────────────────────────────────────────────────
1479
1479
 
1480
+ /** Return the org/owner for a project regardless of host. Prefers host-specific field, falls back to adoOrg for backward compat. */
1481
+ function getProjectOrg(project) {
1482
+ if (!project) return '';
1483
+ if (project.repoHost === 'github') return project.githubOrg || project.adoOrg || '';
1484
+ return project.adoOrg || '';
1485
+ }
1486
+
1480
1487
  function getAdoOrgBase(project) {
1481
1488
  if (project.prUrlBase) {
1482
1489
  const devAzure = project.prUrlBase.match(/^(https?:\/\/dev\.azure\.com\/[^/]+)/i);
@@ -1922,7 +1929,7 @@ function getProjectPrScope(project) {
1922
1929
  if (host === 'github') {
1923
1930
  const parsed = parseGitHubPrUrl(project.prUrlBase || '');
1924
1931
  if (parsed?.scope) return parsed.scope;
1925
- const owner = normalizePrScopeSegment(project.adoOrg);
1932
+ const owner = normalizePrScopeSegment(getProjectOrg(project));
1926
1933
  const repo = normalizePrScopeSegment(project.repoName);
1927
1934
  return owner && repo ? `github:${owner}/${repo}` : '';
1928
1935
  }
@@ -2680,6 +2687,7 @@ module.exports = {
2680
2687
  mergePrLinkItems, // exported for testing
2681
2688
  upsertPullRequestRecord,
2682
2689
  nextWorkItemId,
2690
+ getProjectOrg,
2683
2691
  getAdoOrgBase,
2684
2692
  sanitizePath,
2685
2693
  sanitizeBranch,
package/engine.js CHANGED
@@ -2450,7 +2450,7 @@ async function discoverFromPrs(config, project) {
2450
2450
  // awaiting a stale-vote re-review or has build-fix retries escalated.
2451
2451
  const humanFixKey = `human-fix-${project?.name || 'default'}-${prDisplayId}`;
2452
2452
  const hasCoalescedFeedback = (dispatchCooldowns.get(humanFixKey)?.pendingContexts || []).length > 0;
2453
- if (autoFixHumanComments && (pr.humanFeedback?.pendingFix || hasCoalescedFeedback) && !fixDispatched) {
2453
+ if (pollEnabled && autoFixHumanComments && (pr.humanFeedback?.pendingFix || hasCoalescedFeedback) && !fixDispatched) {
2454
2454
  const key = humanFixKey;
2455
2455
  let staleCoalesced = [];
2456
2456
  const alreadyDispatched = isAlreadyDispatched(key);
@@ -2544,9 +2544,9 @@ async function discoverFromPrs(config, project) {
2544
2544
  if (item) { newWork.push(item); }
2545
2545
  }
2546
2546
 
2547
- // PRs with changes requested → route back to author for fix
2548
- // Gate on evalLoopEnabled — the review→fix cycle is the eval loop
2549
- if (evalLoopEnabled && autoFixReviewFeedback && reviewStatus === 'changes-requested' && !awaitingReReview && !fixDispatched) {
2547
+ // PRs with changes requested → route back to author for fix.
2548
+ // Gate on evalLoopEnabled and provider polling — the review→fix cycle depends on fresh vote state.
2549
+ if (evalLoopEnabled && pollEnabled && autoFixReviewFeedback && reviewStatus === 'changes-requested' && !awaitingReReview && !fixDispatched) {
2550
2550
  const key = `fix-${project?.name || 'default'}-${prDisplayId}`;
2551
2551
  if (fixThrottled || isAlreadyDispatched(key) || isOnCooldown(key, cooldownMs)) continue;
2552
2552
  const agentId = resolveAgent('fix', config, { authorAgent: pr.agent });
@@ -2571,7 +2571,7 @@ async function discoverFromPrs(config, project) {
2571
2571
  if (Date.now() - new Date(pr._buildFixPushedAt).getTime() < gracePeriodMs) continue;
2572
2572
  }
2573
2573
  const autoFixBuilds = config.engine?.autoFixBuilds ?? ENGINE_DEFAULTS.autoFixBuilds;
2574
- if (autoFixBuilds && pr.status === PR_STATUS.ACTIVE && pr.buildStatus === 'failing') {
2574
+ if (pollEnabled && autoFixBuilds && pr.status === PR_STATUS.ACTIVE && pr.buildStatus === 'failing') {
2575
2575
  const key = `build-fix-${project?.name || 'default'}-${prDisplayId}`;
2576
2576
  if (fixThrottled || isAlreadyDispatched(key) || isOnCooldown(key, cooldownMs)) continue;
2577
2577
 
@@ -2661,9 +2661,9 @@ async function discoverFromPrs(config, project) {
2661
2661
  }
2662
2662
  }
2663
2663
 
2664
- // PRs with merge conflicts — dispatch fix to resolve (gated by autoFixConflicts)
2664
+ // PRs with merge conflicts — dispatch fix to resolve (gated by provider polling + autoFixConflicts)
2665
2665
  const autoFixConflicts = config.engine?.autoFixConflicts ?? ENGINE_DEFAULTS.autoFixConflicts;
2666
- if (autoFixConflicts && pr.status === PR_STATUS.ACTIVE && pr._mergeConflict && !fixDispatched) {
2666
+ if (pollEnabled && autoFixConflicts && pr.status === PR_STATUS.ACTIVE && pr._mergeConflict && !fixDispatched) {
2667
2667
  const key = `conflict-fix-${project?.name || 'default'}-${prDisplayId}`;
2668
2668
  // Suppress re-dispatch for 10 min after last attempt — ADO/GitHub recomputes
2669
2669
  // mergeStatus asynchronously (1–5 min lag), so the flag may stay set even after
@@ -3191,7 +3191,9 @@ function buildProjectContext(projects, assignedProject, isFanOut, agentName, age
3191
3191
  const projectList = projects.map(p => {
3192
3192
  let line = `### ${p.name}\n`;
3193
3193
  line += `- **Path:** ${p.localPath}\n`;
3194
- line += `- **Repo:** ${p.adoOrg}/${p.adoProject}/${p.repoName} (ID: ${p.repositoryId || 'unknown'}, host: ${getRepoHostLabel(p)})\n`;
3194
+ line += p.repoHost === 'github'
3195
+ ? `- **Repo:** ${p.githubOrg || p.adoOrg || ''}/${p.repoName} (host: ${getRepoHostLabel(p)})\n`
3196
+ : `- **Repo:** ${p.adoOrg}/${p.adoProject}/${p.repoName} (ID: ${p.repositoryId || 'unknown'}, host: ${getRepoHostLabel(p)})\n`;
3195
3197
  if (p.description) line += `- **What it is:** ${p.description}\n`;
3196
3198
  return line;
3197
3199
  }).join('\n');
package/minions.js CHANGED
@@ -183,8 +183,12 @@ function listProjects() {
183
183
  console.log(` ${p.name}`);
184
184
  if (p.description) console.log(` Desc: ${p.description}`);
185
185
  console.log(` Path: ${p.localPath} ${exists ? '' : '(NOT FOUND)'}`);
186
- console.log(` Repo: ${p.adoOrg}/${p.adoProject}/${p.repoName} (${p.repoHost || 'ado'})`);
187
- console.log(` ID: ${p.repositoryId || 'none'}`);
186
+ if (p.repoHost === 'github') {
187
+ console.log(` Repo: ${p.githubOrg || p.adoOrg || ''}/${p.repoName} (github)`);
188
+ } else {
189
+ console.log(` Repo: ${p.adoOrg}/${p.adoProject}/${p.repoName} (${p.repoHost || 'ado'})`);
190
+ console.log(` ID: ${p.repositoryId || 'none'}`);
191
+ }
188
192
  console.log('');
189
193
  }
190
194
  rl.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1719",
3
+ "version": "0.1.1721",
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"