@yemi33/minions 0.1.990 → 0.1.991
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 +5 -5
- package/dashboard/js/modal-qa.js +4 -1
- package/dashboard/js/settings.js +23 -1
- package/dashboard.js +27 -1
- package/engine/playbook.js +3 -1
- package/engine/watches.js +7 -4
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.991 (2026-04-15)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
|
+
- fix doc-chat Clear chat not persisting session deletion to localStorage (#1102)
|
|
7
|
+
- remove DEFAULTS alias from timeout.js (#1101)
|
|
8
|
+
- Per-project workSources toggles in settings modal (#1096)
|
|
9
|
+
- support project-local playbook overrides (#1094)
|
|
6
10
|
- gate review auto-dispatch on adoPollEnabled and evalLoop config flags (#1092)
|
|
7
11
|
- remove DEFAULTS alias from timeout.js — standardize to ENGINE_DEFAULTS
|
|
8
12
|
- complete watches management — new conditions, CC actions, PROJECTS fix (#1103)
|
|
@@ -19,10 +23,6 @@
|
|
|
19
23
|
- ADO throttle detection, poll guards, and dashboard banner (#1051)
|
|
20
24
|
- gate auto-fix conflict dispatch behind autoFixConflicts flag
|
|
21
25
|
- add PR/build status CLI shim and agent guidance
|
|
22
|
-
- make ADO poll frequency configurable and ungate reconcilePrs
|
|
23
|
-
- update render-work-items.js output viewer to use renderAgentOutput
|
|
24
|
-
- update detail-panel.js Output Log tab to use renderAgentOutput
|
|
25
|
-
- Update command-center.js to capture tool inputs and use formatted summaries
|
|
26
26
|
|
|
27
27
|
### Fixes
|
|
28
28
|
- updatePrAfterReview preserves fixedAt when writing minionsReview
|
package/dashboard/js/modal-qa.js
CHANGED
|
@@ -135,7 +135,10 @@ function clearQaConversation() {
|
|
|
135
135
|
var expandBar = document.getElementById('qa-expand-bar');
|
|
136
136
|
if (wrap) wrap.style.display = 'none';
|
|
137
137
|
if (expandBar) expandBar.style.display = 'none';
|
|
138
|
-
if (_qaSessionKey)
|
|
138
|
+
if (_qaSessionKey) {
|
|
139
|
+
_qaSessions.delete(_qaSessionKey);
|
|
140
|
+
_saveQaSessions();
|
|
141
|
+
}
|
|
139
142
|
}
|
|
140
143
|
|
|
141
144
|
function modalSend() {
|
package/dashboard/js/settings.js
CHANGED
|
@@ -68,6 +68,18 @@ async function openSettings() {
|
|
|
68
68
|
settingsField('Ignored Comment Authors', 'set-ignoredCommentAuthors', (e.ignoredCommentAuthors || []).join(', '), '', 'Comma-separated usernames — comments auto-closed, never trigger fixes') +
|
|
69
69
|
'</div>' +
|
|
70
70
|
|
|
71
|
+
'<h3 style="font-size:13px;color:var(--blue);margin-bottom:8px">Projects</h3>' +
|
|
72
|
+
'<div style="display:flex;flex-direction:column;gap:12px;margin-bottom:16px">' +
|
|
73
|
+
(data.projects || []).map(function(p) {
|
|
74
|
+
return '<div style="border:1px solid var(--border);border-radius:6px;padding:10px 12px">' +
|
|
75
|
+
'<div style="font-size:12px;font-weight:600;margin-bottom:8px">' + escHtml(p.name) + '</div>' +
|
|
76
|
+
'<div style="display:flex;flex-direction:column;gap:6px">' +
|
|
77
|
+
settingsToggle('Discover from PRs', 'set-ws-prs-' + p.name, p.workSources.pullRequests.enabled, 'Auto-discover work from open pull requests') +
|
|
78
|
+
settingsToggle('Discover from Work Items', 'set-ws-wi-' + p.name, p.workSources.workItems.enabled, 'Auto-discover work from ADO/GitHub work items') +
|
|
79
|
+
'</div></div>';
|
|
80
|
+
}).join('') +
|
|
81
|
+
'</div>' +
|
|
82
|
+
|
|
71
83
|
'<h3 style="font-size:13px;color:var(--blue);margin-bottom:8px">Max Turns by Task Type</h3>' +
|
|
72
84
|
'<div style="font-size:10px;color:var(--muted);margin-bottom:6px">How many tool-use turns each task type gets before forced stop. Blank = built-in default.</div>' +
|
|
73
85
|
'<div style="display:grid;grid-template-columns:1fr 1fr 1fr;gap:8px;margin-bottom:16px">' +
|
|
@@ -293,10 +305,20 @@ async function saveSettings() {
|
|
|
293
305
|
agentsPayload[id][field] = el.value;
|
|
294
306
|
});
|
|
295
307
|
|
|
308
|
+
const projectsPayload = (data.projects || []).map(function(p) {
|
|
309
|
+
return {
|
|
310
|
+
name: p.name,
|
|
311
|
+
workSources: {
|
|
312
|
+
pullRequests: { enabled: document.getElementById('set-ws-prs-' + p.name)?.checked ?? true },
|
|
313
|
+
workItems: { enabled: document.getElementById('set-ws-wi-' + p.name)?.checked ?? true }
|
|
314
|
+
}
|
|
315
|
+
};
|
|
316
|
+
});
|
|
317
|
+
|
|
296
318
|
// Save config
|
|
297
319
|
const res = await fetch('/api/settings', {
|
|
298
320
|
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
|
299
|
-
body: JSON.stringify({ engine: enginePayload, claude: claudePayload, agents: agentsPayload, teams: teamsPayload })
|
|
321
|
+
body: JSON.stringify({ engine: enginePayload, claude: claudePayload, agents: agentsPayload, teams: teamsPayload, projects: projectsPayload })
|
|
300
322
|
});
|
|
301
323
|
const result = await res.json();
|
|
302
324
|
if (!res.ok) throw new Error(result.error);
|
package/dashboard.js
CHANGED
|
@@ -3865,6 +3865,13 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3865
3865
|
claude: { ...shared.DEFAULT_CLAUDE, ...(config.claude || {}) },
|
|
3866
3866
|
agents: config.agents || {},
|
|
3867
3867
|
teams: { ...shared.ENGINE_DEFAULTS.teams, ...(config.teams || {}) },
|
|
3868
|
+
projects: (config.projects || []).map(p => ({
|
|
3869
|
+
name: p.name,
|
|
3870
|
+
workSources: {
|
|
3871
|
+
pullRequests: { enabled: p.workSources?.pullRequests?.enabled !== false, cooldownMinutes: p.workSources?.pullRequests?.cooldownMinutes ?? 30 },
|
|
3872
|
+
workItems: { enabled: p.workSources?.workItems?.enabled !== false, cooldownMinutes: p.workSources?.workItems?.cooldownMinutes ?? 0 }
|
|
3873
|
+
}
|
|
3874
|
+
})),
|
|
3868
3875
|
routing,
|
|
3869
3876
|
});
|
|
3870
3877
|
} catch (e) { return jsonReply(res, 500, { error: e.message }); }
|
|
@@ -3977,6 +3984,25 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3977
3984
|
teams._resetAdapter();
|
|
3978
3985
|
}
|
|
3979
3986
|
|
|
3987
|
+
if (body.projects && Array.isArray(body.projects)) {
|
|
3988
|
+
if (!config.projects) config.projects = [];
|
|
3989
|
+
for (const update of body.projects) {
|
|
3990
|
+
const proj = config.projects.find(p => p.name === update.name);
|
|
3991
|
+
if (!proj) continue;
|
|
3992
|
+
if (!proj.workSources) proj.workSources = {};
|
|
3993
|
+
if (update.workSources?.pullRequests !== undefined) {
|
|
3994
|
+
if (!proj.workSources.pullRequests) proj.workSources.pullRequests = { enabled: true, cooldownMinutes: 30 };
|
|
3995
|
+
if (update.workSources.pullRequests.enabled !== undefined)
|
|
3996
|
+
proj.workSources.pullRequests.enabled = !!update.workSources.pullRequests.enabled;
|
|
3997
|
+
}
|
|
3998
|
+
if (update.workSources?.workItems !== undefined) {
|
|
3999
|
+
if (!proj.workSources.workItems) proj.workSources.workItems = { enabled: true, cooldownMinutes: 0 };
|
|
4000
|
+
if (update.workSources.workItems.enabled !== undefined)
|
|
4001
|
+
proj.workSources.workItems.enabled = !!update.workSources.workItems.enabled;
|
|
4002
|
+
}
|
|
4003
|
+
}
|
|
4004
|
+
}
|
|
4005
|
+
|
|
3980
4006
|
safeWrite(configPath, config);
|
|
3981
4007
|
// Refresh in-memory CONFIG so subsequent reads see the update
|
|
3982
4008
|
reloadConfig();
|
|
@@ -4752,7 +4778,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
4752
4778
|
|
|
4753
4779
|
// Settings
|
|
4754
4780
|
{ method: 'GET', path: '/api/settings', desc: 'Return current engine + claude + routing config', handler: handleSettingsRead },
|
|
4755
|
-
{ method: 'POST', path: '/api/settings', desc: 'Update engine + claude + agent + teams config', params: 'engine?, claude?, agents?, teams?', handler: handleSettingsUpdate },
|
|
4781
|
+
{ method: 'POST', path: '/api/settings', desc: 'Update engine + claude + agent + teams + projects config', params: 'engine?, claude?, agents?, teams?, projects?', handler: handleSettingsUpdate },
|
|
4756
4782
|
{ method: 'POST', path: '/api/settings/routing', desc: 'Update routing.md', params: 'content', handler: handleSettingsRouting },
|
|
4757
4783
|
{ method: 'POST', path: '/api/settings/reset', desc: 'Reset engine + claude + agent settings to defaults', handler: handleSettingsReset },
|
|
4758
4784
|
|
package/engine/playbook.js
CHANGED
|
@@ -283,12 +283,14 @@ function resolvePlaybookPath(projectName, playbookType) {
|
|
|
283
283
|
const localPath = path.join(MINIONS_DIR, 'projects', projectName, 'playbooks', `${playbookType}.md`);
|
|
284
284
|
try {
|
|
285
285
|
fs.accessSync(localPath, fs.constants.R_OK);
|
|
286
|
+
log('info', `Using project-local playbook: projects/${projectName}/playbooks/${playbookType}.md`);
|
|
286
287
|
return localPath;
|
|
287
288
|
} catch { /* no local override — fall through to global */ }
|
|
288
289
|
}
|
|
289
290
|
return path.join(PLAYBOOKS_DIR, `${playbookType}.md`);
|
|
290
291
|
}
|
|
291
292
|
|
|
293
|
+
|
|
292
294
|
// ─── Playbook Renderer ──────────────────────────────────────────────────────
|
|
293
295
|
|
|
294
296
|
function renderPlaybook(type, vars) {
|
|
@@ -589,8 +591,8 @@ function buildPrDispatch(agentId, config, project, pr, type, extraVars, taskLabe
|
|
|
589
591
|
}
|
|
590
592
|
|
|
591
593
|
module.exports = {
|
|
592
|
-
renderPlaybook,
|
|
593
594
|
resolvePlaybookPath,
|
|
595
|
+
renderPlaybook,
|
|
594
596
|
validatePlaybookVars,
|
|
595
597
|
PLAYBOOK_REQUIRED_VARS,
|
|
596
598
|
PLAYBOOK_OPTIONAL_VARS,
|
package/engine/watches.js
CHANGED
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
const path = require('path');
|
|
12
12
|
const shared = require('./shared');
|
|
13
13
|
const { safeJson, mutateJsonFileLocked, ts, uid, log, writeToInbox,
|
|
14
|
-
WATCH_STATUS, WATCH_TARGET_TYPE, WATCH_CONDITION } = shared;
|
|
14
|
+
WATCH_STATUS, WATCH_TARGET_TYPE, WATCH_CONDITION, WATCH_ABSOLUTE_CONDITIONS } = shared;
|
|
15
15
|
|
|
16
16
|
// Dynamic path — respects MINIONS_TEST_DIR for test isolation
|
|
17
17
|
function _watchesPath() { return path.join(shared.MINIONS_DIR, 'engine', 'watches.json'); }
|
|
@@ -248,10 +248,13 @@ function checkWatches(config, state) {
|
|
|
248
248
|
log('info', `Watch triggered: ${watch.id} — ${result.message}`);
|
|
249
249
|
|
|
250
250
|
// Expire when stopAfter > 0 and trigger count reaches the limit.
|
|
251
|
-
//
|
|
252
|
-
|
|
251
|
+
// Absolute conditions (merged, build-pass, etc.) auto-expire on first trigger
|
|
252
|
+
// when stopAfter=0 — fire-once semantics. Change-based conditions run forever.
|
|
253
|
+
const isAbsolute = WATCH_ABSOLUTE_CONDITIONS.has(watch.condition);
|
|
254
|
+
if ((watch.stopAfter > 0 && watch.triggerCount >= watch.stopAfter) ||
|
|
255
|
+
(watch.stopAfter === 0 && isAbsolute)) {
|
|
253
256
|
watch.status = WATCH_STATUS.EXPIRED;
|
|
254
|
-
log('info', `Watch expired (stopAfter limit reached): ${watch.id}`);
|
|
257
|
+
log('info', `Watch expired (${isAbsolute && watch.stopAfter === 0 ? 'absolute condition fire-once' : 'stopAfter limit reached'}): ${watch.id}`);
|
|
255
258
|
}
|
|
256
259
|
} else if (watch.onNotMet === 'notify' && watch.owner) {
|
|
257
260
|
// Queue per-poll notification when condition is not yet met — unique key per poll
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.991",
|
|
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"
|