@yemi33/minions 0.1.1045 → 0.1.1046

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,9 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1045 (2026-04-16)
3
+ ## 0.1.1046 (2026-04-16)
4
+
5
+ ### Fixes
6
+ - harden settings save and migrate pr poll config
4
7
 
5
8
  ### Other
6
9
  - Harden loop watch conversion
@@ -1,14 +1,18 @@
1
1
  // settings.js — Settings panel functions extracted from dashboard.html
2
2
 
3
+ let _settingsData = null;
4
+
3
5
  async function openSettings() {
4
6
  document.getElementById('modal-title').textContent = 'Settings';
5
7
  document.getElementById('modal-body').innerHTML = '<p style="color:var(--muted)">Loading...</p>';
6
8
  document.getElementById('modal').classList.add('open');
7
9
 
10
+ _settingsData = null;
8
11
  let data;
9
12
  try {
10
13
  const res = await fetch('/api/settings');
11
14
  data = await res.json();
15
+ _settingsData = data;
12
16
  } catch (e) { showToast('cmd-toast', 'Failed to load settings: ' + e.message, false); return; }
13
17
 
14
18
  const e = data.engine || {};
@@ -56,8 +60,8 @@ async function openSettings() {
56
60
  settingsToggle('GitHub Polling', 'set-ghPollEnabled', e.ghPollEnabled !== false, 'Poll GitHub PR status and comments each tick (reconciliation always runs)') +
57
61
  '</div>' +
58
62
  '<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:16px">' +
59
- settingsField('PR Status Poll Frequency', 'set-adoPollStatusEvery', e.adoPollStatusEvery || 6, 'ticks', 'Poll PR build/review/merge status every N ticks for both ADO and GitHub (~6 min at default tick rate)') +
60
- settingsField('PR Comments Poll Frequency', 'set-adoPollCommentsEvery', e.adoPollCommentsEvery || 12, 'ticks', 'Poll PR human comments every N ticks for both ADO and GitHub (~12 min at default tick rate)') +
63
+ 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)') +
64
+ 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)') +
61
65
  '</div>' +
62
66
  '<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:16px">' +
63
67
  settingsField('Eval Max Iterations', 'set-evalMaxIterations', e.evalMaxIterations || 3, '', 'Max review→fix cycles before escalating (1-10)') +
@@ -258,8 +262,8 @@ async function saveSettings() {
258
262
  autoCompletePrs: document.getElementById('set-autoCompletePrs').checked,
259
263
  adoPollEnabled: document.getElementById('set-adoPollEnabled').checked,
260
264
  ghPollEnabled: document.getElementById('set-ghPollEnabled').checked,
261
- adoPollStatusEvery: document.getElementById('set-adoPollStatusEvery').value,
262
- adoPollCommentsEvery: document.getElementById('set-adoPollCommentsEvery').value,
265
+ prPollStatusEvery: document.getElementById('set-prPollStatusEvery').value,
266
+ prPollCommentsEvery: document.getElementById('set-prPollCommentsEvery').value,
263
267
  evalMaxIterations: document.getElementById('set-evalMaxIterations').value,
264
268
  evalMaxCost: document.getElementById('set-evalMaxCost').value || null,
265
269
  maxBuildFixAttempts: document.getElementById('set-maxBuildFixAttempts').value,
@@ -305,7 +309,8 @@ async function saveSettings() {
305
309
  agentsPayload[id][field] = el.value;
306
310
  });
307
311
 
308
- const projectsPayload = (data.projects || []).map(function(p) {
312
+ const currentProjects = (_settingsData && Array.isArray(_settingsData.projects)) ? _settingsData.projects : [];
313
+ const projectsPayload = currentProjects.map(function(p) {
309
314
  return {
310
315
  name: p.name,
311
316
  workSources: {
@@ -14,5 +14,13 @@
14
14
  "reason": "Redundant with evalLoop; evalLoop is the single gate for the review+fix cycle",
15
15
  "locations": ["engine/shared.js ENGINE_DEFAULTS.autoReview", "engine.js discoverFromPrs autoReview variable"],
16
16
  "cleanup": "Removed from ENGINE_DEFAULTS, removed autoReview variable from engine.js, replaced with reviewEnabled = evalLoopEnabled && pollEnabled"
17
+ },
18
+ {
19
+ "id": "ado-poll-frequency-keys",
20
+ "summary": "adoPollStatusEvery and adoPollCommentsEvery renamed to prPollStatusEvery and prPollCommentsEvery",
21
+ "deprecated": "2026-04-16",
22
+ "reason": "These cadence settings gate both ADO and GitHub PR polling, so the ADO-prefixed names are misleading.",
23
+ "locations": ["engine.js read-side fallback from config.engine.adoPollStatusEvery/adoPollCommentsEvery", "dashboard.js handleSettingsRead/handleSettingsUpdate alias fallback for old keys"],
24
+ "cleanup": "Remove the adoPoll* alias fallback reads after existing configs have been migrated to prPollStatusEvery/prPollCommentsEvery."
17
25
  }
18
26
  ]
package/engine/queries.js CHANGED
@@ -9,7 +9,7 @@ const path = require('path');
9
9
  const os = require('os');
10
10
  const shared = require('./shared');
11
11
 
12
- const { safeRead, safeReadDir, safeJson, safeWrite, getProjects,
12
+ const { safeRead, safeReadDir, safeJson, safeWrite, getProjects, mutateJsonFileLocked,
13
13
  projectWorkItemsPath, projectPrPath, parseSkillFrontmatter, KB_CATEGORIES,
14
14
  WI_STATUS, DONE_STATUSES, PRD_ITEM_STATUS, ENGINE_DEFAULTS } = shared;
15
15
 
@@ -99,7 +99,49 @@ function timeSince(ms) {
99
99
 
100
100
  // ── Core State Readers ──────────────────────────────────────────────────────
101
101
 
102
+ let _configPollKeyMigrationChecked = false;
103
+
104
+ function migrateDeprecatedConfigPollKeysOnce() {
105
+ if (_configPollKeyMigrationChecked) return;
106
+ const initial = safeJson(CONFIG_PATH);
107
+ if (!initial || typeof initial !== 'object' || Array.isArray(initial)) {
108
+ _configPollKeyMigrationChecked = true;
109
+ return;
110
+ }
111
+ const engine = initial.engine;
112
+ if (!engine || typeof engine !== 'object' || Array.isArray(engine)) {
113
+ _configPollKeyMigrationChecked = true;
114
+ return;
115
+ }
116
+ const hasOldStatus = engine.adoPollStatusEvery !== undefined;
117
+ const hasOldComments = engine.adoPollCommentsEvery !== undefined;
118
+ if (!hasOldStatus && !hasOldComments) {
119
+ _configPollKeyMigrationChecked = true;
120
+ return;
121
+ }
122
+ try {
123
+ mutateJsonFileLocked(CONFIG_PATH, (config) => {
124
+ if (!config || typeof config !== 'object' || Array.isArray(config)) return config;
125
+ const nextEngine = config.engine;
126
+ if (!nextEngine || typeof nextEngine !== 'object' || Array.isArray(nextEngine)) return config;
127
+ if (nextEngine.prPollStatusEvery === undefined && nextEngine.adoPollStatusEvery !== undefined) {
128
+ nextEngine.prPollStatusEvery = nextEngine.adoPollStatusEvery;
129
+ }
130
+ if (nextEngine.prPollCommentsEvery === undefined && nextEngine.adoPollCommentsEvery !== undefined) {
131
+ nextEngine.prPollCommentsEvery = nextEngine.adoPollCommentsEvery;
132
+ }
133
+ delete nextEngine.adoPollStatusEvery;
134
+ delete nextEngine.adoPollCommentsEvery;
135
+ return config;
136
+ });
137
+ _configPollKeyMigrationChecked = true;
138
+ } catch (e) {
139
+ console.warn('[config] one-time prPoll migration failed:', e.message);
140
+ }
141
+ }
142
+
102
143
  function getConfig() {
144
+ migrateDeprecatedConfigPollKeysOnce();
103
145
  return safeJson(CONFIG_PATH) || {};
104
146
  }
105
147
 
package/engine/shared.js CHANGED
@@ -673,8 +673,8 @@ const ENGINE_DEFAULTS = {
673
673
  buildFixGracePeriod: 600000, // 10min — wait for CI to run after build fix before re-dispatching
674
674
  adoPollEnabled: true, // poll ADO PR status, comments, and reconciliation on each tick cycle
675
675
  ghPollEnabled: true, // poll GitHub PR status, comments, and reconciliation on each tick cycle
676
- adoPollStatusEvery: 6, // poll ADO PR build/review/merge status every N ticks (~6 min at default interval)
677
- adoPollCommentsEvery: 12, // poll ADO PR human comments every N ticks (~12 min at default interval)
676
+ prPollStatusEvery: 12, // poll PR build/review/merge status every N ticks for both ADO and GitHub (~12 min at default interval)
677
+ prPollCommentsEvery: 12, // poll PR human comments every N ticks for both ADO and GitHub (~12 min at default interval)
678
678
  autoCompletePrs: false, // auto-merge PRs when builds green + review approved (opt-in)
679
679
  prMergeMethod: 'squash', // merge method: squash, merge, rebase
680
680
  ignoredCommentAuthors: [], // comments from these authors are auto-closed and never trigger fixes
package/engine.js CHANGED
@@ -3226,13 +3226,19 @@ async function tickInner() {
3226
3226
 
3227
3227
  const adoPollEnabled = config.engine?.adoPollEnabled ?? ENGINE_DEFAULTS.adoPollEnabled;
3228
3228
  const ghPollEnabled = config.engine?.ghPollEnabled ?? ENGINE_DEFAULTS.ghPollEnabled;
3229
- const adoPollStatusEvery = Math.max(1, Number(config.engine?.adoPollStatusEvery) || ENGINE_DEFAULTS.adoPollStatusEvery);
3230
- const adoPollCommentsEvery = Math.max(1, Number(config.engine?.adoPollCommentsEvery) || ENGINE_DEFAULTS.adoPollCommentsEvery);
3229
+ const prPollStatusEvery = Math.max(
3230
+ 1,
3231
+ Number(config.engine?.prPollStatusEvery ?? config.engine?.adoPollStatusEvery) || ENGINE_DEFAULTS.prPollStatusEvery
3232
+ );
3233
+ const prPollCommentsEvery = Math.max(
3234
+ 1,
3235
+ Number(config.engine?.prPollCommentsEvery ?? config.engine?.adoPollCommentsEvery) || ENGINE_DEFAULTS.prPollCommentsEvery
3236
+ );
3231
3237
 
3232
- // 2.6. Poll PR status: build, review, merge (every adoPollStatusEvery ticks, default ~6 minutes)
3238
+ // 2.6. Poll PR status: build, review, merge (every prPollStatusEvery ticks, default ~12 minutes)
3233
3239
  // Awaited so PR state is consistent before discoverWork reads it
3234
3240
  // Also re-polls early if previous tick had ADO auth failures (stale build status recovery)
3235
- if (tickCount % adoPollStatusEvery === 0 || needsAdoPollRetry()) {
3241
+ if (tickCount % prPollStatusEvery === 0 || needsAdoPollRetry()) {
3236
3242
  // Build promise array — enabled+unthrottled polls run concurrently via Promise.allSettled
3237
3243
  const statusPolls = [];
3238
3244
  if (adoPollEnabled && !isAdoThrottled()) {
@@ -3265,8 +3271,8 @@ async function tickInner() {
3265
3271
  } catch (err) { log('warn', `Plan completion check error: ${err?.message || err}`); }
3266
3272
  }
3267
3273
 
3268
- // 2.7. Poll PR threads for human comments (every adoPollCommentsEvery ticks, default ~12 minutes)
3269
- if (tickCount % adoPollCommentsEvery === 0) {
3274
+ // 2.7. Poll PR threads for human comments (every prPollCommentsEvery ticks, default ~12 minutes)
3275
+ if (tickCount % prPollCommentsEvery === 0) {
3270
3276
  // Build promise array — enabled+unthrottled comment polls run concurrently via Promise.allSettled
3271
3277
  const commentPolls = [];
3272
3278
  if (adoPollEnabled && !isAdoThrottled()) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1045",
3
+ "version": "0.1.1046",
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"