@yemi33/minions 0.1.593 → 0.1.595
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 +3 -1
- package/dashboard/js/render-pipelines.js +71 -0
- package/dashboard.js +4 -2
- package/engine.js +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.595 (2026-04-08)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
- show worktree count and engine quick stats on engine page
|
|
7
7
|
|
|
8
8
|
### Fixes
|
|
9
|
+
- bump fix task max-turns from 50 to 75
|
|
10
|
+
- Pipeline UI show monitored resources in pipeline card (closes #523) (#542)
|
|
9
11
|
- move 'When to Stop' after Build/Test in implement playbook
|
|
10
12
|
- per-type maxTurns bypassed when config has default maxTurns=100
|
|
11
13
|
|
|
@@ -5,6 +5,62 @@ let _pipelinePollId = null;
|
|
|
5
5
|
let _pipelinePollInterval = null;
|
|
6
6
|
function _stopPipelinePoll() { if (_pipelinePollInterval) { clearInterval(_pipelinePollInterval); _pipelinePollInterval = null; } _pipelinePollId = null; }
|
|
7
7
|
|
|
8
|
+
/**
|
|
9
|
+
* Collect all monitoredResources from a pipeline (pipeline-level + all stages).
|
|
10
|
+
* Returns a deduplicated array of resource objects.
|
|
11
|
+
*/
|
|
12
|
+
function _collectMonitoredResources(pipeline) {
|
|
13
|
+
var seen = new Set();
|
|
14
|
+
var result = [];
|
|
15
|
+
function add(r) {
|
|
16
|
+
var key = typeof r === 'string' ? r : (r.url || r.label || JSON.stringify(r));
|
|
17
|
+
if (seen.has(key)) return;
|
|
18
|
+
seen.add(key);
|
|
19
|
+
result.push(typeof r === 'string' ? { label: r, url: r } : r);
|
|
20
|
+
}
|
|
21
|
+
(pipeline.monitoredResources || []).forEach(add);
|
|
22
|
+
(pipeline.stages || []).forEach(function(s) { (s.monitoredResources || []).forEach(add); });
|
|
23
|
+
return result;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Render monitored resources as compact pills on a pipeline card or stage detail.
|
|
28
|
+
* Supports both string resources (URLs/IDs) and objects with {type, label, url}.
|
|
29
|
+
* @param {Array} resources - array of resource strings or {type?, label, url?} objects
|
|
30
|
+
* @param {Object} [options] - { compact: true } limits display and shows "+N more"
|
|
31
|
+
* @returns {string} HTML string
|
|
32
|
+
*/
|
|
33
|
+
function _renderMonitoredResources(resources, options) {
|
|
34
|
+
if (!resources || resources.length === 0) return '';
|
|
35
|
+
var compact = options && options.compact;
|
|
36
|
+
var maxShow = compact ? 4 : resources.length;
|
|
37
|
+
var shown = resources.slice(0, maxShow);
|
|
38
|
+
var overflow = resources.length - maxShow;
|
|
39
|
+
|
|
40
|
+
var iconMap = { pr: '🔀', workitem: '⚙', url: '🔗', issue: '🐛' };
|
|
41
|
+
var pillStyle = 'display:inline-flex;align-items:center;gap:2px;padding:1px 6px;border-radius:10px;font-size:10px;text-decoration:none;' +
|
|
42
|
+
'color:var(--text);background:color-mix(in srgb, var(--muted) 10%, transparent);border:1px solid color-mix(in srgb, var(--muted) 20%, transparent);max-width:220px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap';
|
|
43
|
+
|
|
44
|
+
var pills = shown.map(function(r) {
|
|
45
|
+
var res = typeof r === 'string' ? { label: r, url: r.startsWith('http') ? r : '' } : r;
|
|
46
|
+
var icon = iconMap[res.type] || (res.url ? '🔗' : '📌');
|
|
47
|
+
var label = res.label || res.url || '(resource)';
|
|
48
|
+
// Truncate label for compact view
|
|
49
|
+
var displayLabel = compact && label.length > 28 ? label.slice(0, 26) + '…' : label;
|
|
50
|
+
if (res.url) {
|
|
51
|
+
return '<a href="' + escHtml(res.url) + '" target="_blank" rel="noopener" style="' + pillStyle + ';cursor:pointer" onclick="event.stopPropagation()" title="' + escHtml(label) + '">' + icon + ' ' + escHtml(displayLabel) + '</a>';
|
|
52
|
+
}
|
|
53
|
+
return '<span style="' + pillStyle + ';cursor:default" title="' + escHtml(label) + '">' + icon + ' ' + escHtml(displayLabel) + '</span>';
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
if (overflow > 0) {
|
|
57
|
+
pills.push('<span style="' + pillStyle + ';cursor:default;opacity:0.7" title="' + overflow + ' more resource' + (overflow !== 1 ? 's' : '') + '">+' + overflow + ' more</span>');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
var heading = compact ? '' : '<span style="font-size:10px;color:var(--muted);margin-right:4px">Monitoring:</span>';
|
|
61
|
+
return '<div style="margin-top:4px;display:flex;flex-wrap:wrap;gap:3px;align-items:center">' + heading + pills.join('') + '</div>';
|
|
62
|
+
}
|
|
63
|
+
|
|
8
64
|
/**
|
|
9
65
|
* Render clickable artifact links for a pipeline stage.
|
|
10
66
|
* Each artifact type gets an icon and navigates to the relevant detail view.
|
|
@@ -154,6 +210,10 @@ function renderPipelines(pipelines) {
|
|
|
154
210
|
progressHtml = _buildProgressBar(p.stages || [], displayRun);
|
|
155
211
|
}
|
|
156
212
|
|
|
213
|
+
// Monitored resources (pipeline-level + stage-level, compact on card)
|
|
214
|
+
var allResources = _collectMonitoredResources(p);
|
|
215
|
+
var resourcesHtml = _renderMonitoredResources(allResources, { compact: true });
|
|
216
|
+
|
|
157
217
|
return '<div style="background:var(--surface);border:1px solid var(--border);border-radius:8px;padding:12px 16px;margin-bottom:8px;cursor:pointer" onclick="openPipelineDetail(\'' + escHtml(p.id) + '\')">' +
|
|
158
218
|
'<div style="display:flex;justify-content:space-between;align-items:center">' +
|
|
159
219
|
'<strong style="font-size:13px">' + escHtml(p.title) + '</strong>' +
|
|
@@ -164,6 +224,7 @@ function renderPipelines(pipelines) {
|
|
|
164
224
|
'</div>' +
|
|
165
225
|
'</div>' +
|
|
166
226
|
'<div style="margin-top:6px;display:flex;gap:4px;align-items:center;flex-wrap:wrap">' + stageFlow + '</div>' +
|
|
227
|
+
resourcesHtml +
|
|
167
228
|
progressHtml +
|
|
168
229
|
'</div>';
|
|
169
230
|
}).join('');
|
|
@@ -196,6 +257,15 @@ function openPipelineDetail(id) {
|
|
|
196
257
|
if (detailRun && (p.stages || []).length > 0) {
|
|
197
258
|
html += _buildProgressBar(p.stages || [], detailRun, { height: '8px', detailLabel: true });
|
|
198
259
|
}
|
|
260
|
+
// Pipeline-level monitored resources (full view in detail)
|
|
261
|
+
var pipelineResources = _collectMonitoredResources(p);
|
|
262
|
+
if (pipelineResources.length > 0) {
|
|
263
|
+
html += '<div style="border:1px solid color-mix(in srgb, var(--blue) 20%, transparent);border-radius:6px;padding:6px 10px;background:color-mix(in srgb, var(--blue) 4%, transparent)">' +
|
|
264
|
+
'<span style="font-size:10px;font-weight:600;color:var(--blue)">📡 Monitored Resources</span>' +
|
|
265
|
+
_renderMonitoredResources(pipelineResources) +
|
|
266
|
+
'</div>';
|
|
267
|
+
}
|
|
268
|
+
|
|
199
269
|
html += '<h4 style="font-size:12px;color:var(--blue);margin:0">Stages</h4>';
|
|
200
270
|
(p.stages || []).forEach(function(s, i) {
|
|
201
271
|
var stageRun = activeRun?.stages?.[s.id] || {};
|
|
@@ -209,6 +279,7 @@ function openPipelineDetail(id) {
|
|
|
209
279
|
'<span style="color:' + statusColor + ';font-size:10px;font-weight:600">' + stageStatus.toUpperCase() + '</span>' +
|
|
210
280
|
'</div>' +
|
|
211
281
|
'<div style="font-size:10px;color:var(--muted);margin-top:4px">Type: ' + escHtml(s.type) + ' | Depends on: ' + escHtml(deps) + (s.agent ? ' | Agent: ' + escHtml(s.agent) : '') + '</div>' +
|
|
282
|
+
_renderMonitoredResources(s.monitoredResources || []) +
|
|
212
283
|
_renderArtifactLinks(stageRun.artifacts) +
|
|
213
284
|
(stageRun.output ? '<div style="margin-top:6px;font-size:11px;max-height:150px;overflow-y:auto">' + renderMd(stageRun.output.slice(0, 500)) + '</div>' : '') +
|
|
214
285
|
(stageStatus === 'waiting-human' ? '<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px;color:var(--green);border-color:var(--green);margin-top:6px" onclick="_continuePipeline(\'' + escHtml(id) + '\',\'' + escHtml(s.id) + '\',this)">Continue</button>' : '') +
|
package/dashboard.js
CHANGED
|
@@ -3952,17 +3952,18 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3952
3952
|
const result = pipelines.map(p => ({ ...p, runs: (runs[p.id] || []).slice(-5) }));
|
|
3953
3953
|
return jsonReply(res, 200, result);
|
|
3954
3954
|
}},
|
|
3955
|
-
{ method: 'POST', path: '/api/pipelines', desc: 'Create a pipeline', params: 'id, title, stages[], trigger?', handler: async (req, res) => {
|
|
3955
|
+
{ method: 'POST', path: '/api/pipelines', desc: 'Create a pipeline', params: 'id, title, stages[], trigger?, monitoredResources?', handler: async (req, res) => {
|
|
3956
3956
|
const body = await readBody(req);
|
|
3957
3957
|
if (!body.id || !body.title || !body.stages) return jsonReply(res, 400, { error: 'id, title, and stages required' });
|
|
3958
3958
|
const { savePipeline, getPipeline } = require('./engine/pipeline');
|
|
3959
3959
|
if (getPipeline(body.id)) return jsonReply(res, 409, { error: 'Pipeline already exists' });
|
|
3960
3960
|
const pipeline = { id: body.id, title: body.title, stages: body.stages, trigger: body.trigger || {}, enabled: body.enabled !== false };
|
|
3961
|
+
if (Array.isArray(body.monitoredResources) && body.monitoredResources.length > 0) pipeline.monitoredResources = body.monitoredResources;
|
|
3961
3962
|
savePipeline(pipeline);
|
|
3962
3963
|
invalidateStatusCache();
|
|
3963
3964
|
return jsonReply(res, 200, { ok: true, id: pipeline.id });
|
|
3964
3965
|
}},
|
|
3965
|
-
{ method: 'POST', path: '/api/pipelines/update', desc: 'Update a pipeline', params: 'id, title?, stages?, trigger?, enabled?', handler: async (req, res) => {
|
|
3966
|
+
{ method: 'POST', path: '/api/pipelines/update', desc: 'Update a pipeline', params: 'id, title?, stages?, trigger?, enabled?, monitoredResources?', handler: async (req, res) => {
|
|
3966
3967
|
const body = await readBody(req);
|
|
3967
3968
|
if (!body.id) return jsonReply(res, 400, { error: 'id required' });
|
|
3968
3969
|
const { getPipeline, savePipeline } = require('./engine/pipeline');
|
|
@@ -3972,6 +3973,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3972
3973
|
if (body.stages !== undefined) pipeline.stages = body.stages;
|
|
3973
3974
|
if (body.trigger !== undefined) pipeline.trigger = body.trigger;
|
|
3974
3975
|
if (body.enabled !== undefined) pipeline.enabled = body.enabled;
|
|
3976
|
+
if (body.monitoredResources !== undefined) pipeline.monitoredResources = body.monitoredResources;
|
|
3975
3977
|
savePipeline(pipeline);
|
|
3976
3978
|
invalidateStatusCache();
|
|
3977
3979
|
return jsonReply(res, 200, { ok: true });
|
package/engine.js
CHANGED
|
@@ -151,7 +151,7 @@ const _MAX_TURNS_BY_TYPE = {
|
|
|
151
151
|
[WORK_TYPE.EXPLORE]: 30, [WORK_TYPE.ASK]: 20, [WORK_TYPE.REVIEW]: 30,
|
|
152
152
|
[WORK_TYPE.DECOMPOSE]: 15, [WORK_TYPE.PLAN]: 30, [WORK_TYPE.PLAN_TO_PRD]: 20,
|
|
153
153
|
[WORK_TYPE.MEETING]: 30,
|
|
154
|
-
[WORK_TYPE.IMPLEMENT]: 75, [WORK_TYPE.IMPLEMENT_LARGE]: 75, [WORK_TYPE.FIX]:
|
|
154
|
+
[WORK_TYPE.IMPLEMENT]: 75, [WORK_TYPE.IMPLEMENT_LARGE]: 75, [WORK_TYPE.FIX]: 75,
|
|
155
155
|
[WORK_TYPE.TEST]: 50, [WORK_TYPE.VERIFY]: 100, [WORK_TYPE.DOCS]: 30,
|
|
156
156
|
};
|
|
157
157
|
function _maxTurnsForType(type, engineConfig) {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.595",
|
|
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"
|