@yemi33/minions 0.1.680 → 0.1.682

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,5 +1,13 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.682 (2026-04-09)
4
+
5
+ ### Features
6
+ - horizontal node chain pipeline visualization (TDD)
7
+
8
+ ### Fixes
9
+ - pipeline node chain overlap — truncate labels, remove old stageFlow
10
+
3
11
  ## 0.1.678 (2026-04-09)
4
12
 
5
13
  ### Fixes
@@ -176,6 +176,82 @@ function _buildProgressBar(stages, run, options) {
176
176
  '</div>';
177
177
  }
178
178
 
179
+ var _nodeIcons = { task: '\u2699', meeting: '\uD83D\uDCAC', plan: '\uD83D\uDCCB', 'merge-prs': '\uD83D\uDD04', condition: '\u2753', wait: '\u23F8', parallel: '\u2693', schedule: '\u23F0', api: '\uD83C\uDF10' };
180
+
181
+ function _buildNodeChain(stages, run, options) {
182
+ var compact = options && options.compact;
183
+ var pipeline = options && options.pipeline;
184
+ var html = '<div class="pl-node-chain">';
185
+
186
+ for (var i = 0; i < stages.length; i++) {
187
+ var s = stages[i];
188
+ var stageRun = run?.stages?.[s.id];
189
+ var st = stageRun?.status || 'pending';
190
+ var cls = st === 'completed' ? 'complete' : st === 'running' ? 'running' : st === 'failed' ? 'failed' : st === 'waiting-human' ? 'waiting' : 'pending';
191
+ var icon = _nodeIcons[s.type] || '\u2699';
192
+ var isCondition = s.type === 'condition';
193
+ var isWait = s.type === 'wait';
194
+
195
+ // Arrow before node (except first)
196
+ if (i > 0) html += '<div class="pl-node-arrow">\u2192</div>';
197
+
198
+ html += '<div class="pl-node">';
199
+ var label = compact ? (s.id || '').slice(0, 16) : (s.title || s.id || '').slice(0, 24);
200
+ html += '<div class="pl-node-box ' + cls + (isCondition ? ' condition' : '') + '" title="' + escHtml((s.title || s.id) + ': ' + st) + '">';
201
+ html += icon + ' ' + escHtml(label);
202
+ if (isWait && s.duration) html += ' ' + escHtml(s.duration);
203
+ html += '</div>';
204
+
205
+ // Meta line (agent, timing) — skip in compact mode
206
+ if (!compact) {
207
+ var meta = [];
208
+ var agent = stageRun?.agent || s.agent;
209
+ if (agent) meta.push(escHtml(agent));
210
+ if (st === 'completed' && stageRun?.completedAt) meta.push(timeSinceStr(new Date(stageRun.completedAt)));
211
+ if (st === 'running' && stageRun?.startedAt) meta.push(timeSinceStr(new Date(stageRun.startedAt)));
212
+ // Artifact counts
213
+ var arts = stageRun?.artifacts || {};
214
+ var artCounts = [];
215
+ if (arts.workItems?.length) artCounts.push(arts.workItems.length + ' WI');
216
+ if (arts.prs?.length) artCounts.push(arts.prs.length + ' PR');
217
+ if (arts.notes?.length) artCounts.push(arts.notes.length + ' notes');
218
+ if (artCounts.length) meta.push(artCounts.join(', '));
219
+ if (meta.length) html += '<div class="pl-node-meta">' + meta.join(' \u00b7 ') + '</div>';
220
+ }
221
+
222
+ // Condition fork labels
223
+ if (isCondition) {
224
+ html += '<div class="pl-node-meta" style="font-style:italic">';
225
+ if (s.onMet) html += '\u2714 ' + escHtml(s.onMet);
226
+ if (s.onMet && s.onUnmet) html += ' / ';
227
+ if (s.onUnmet) html += '\u2718 ' + escHtml(s.onUnmet);
228
+ html += '</div>';
229
+ }
230
+
231
+ html += '</div>';
232
+ }
233
+
234
+ // Stop/exit condition terminal node
235
+ var stopWhen = pipeline?.stopWhen;
236
+ if (stopWhen) {
237
+ html += '<div class="pl-node-arrow">\u2192</div>';
238
+ html += '<div class="pl-node"><div class="pl-node-box pl-node-stop">\u23F9 Stop</div>';
239
+ html += '<div class="pl-node-meta">' + escHtml(stopWhen) + '</div></div>';
240
+ }
241
+
242
+ html += '</div>';
243
+
244
+ // Loop indicator
245
+ if (pipeline?.trigger?.cron) {
246
+ var runCount = (pipeline.runs || []).length;
247
+ html += '<div class="pl-node-loop">\u21BA Loop (' + escHtml(_cronToHuman(pipeline.trigger.cron)) + ')';
248
+ if (runCount > 0) html += ' \u00b7 Run ' + runCount;
249
+ html += '</div>';
250
+ }
251
+
252
+ return html;
253
+ }
254
+
179
255
  function renderPipelines(pipelines) {
180
256
  _pipelinesData = pipelines || [];
181
257
  const el = document.getElementById('pipelines-content');
@@ -207,7 +283,7 @@ function renderPipelines(pipelines) {
207
283
  var progressHtml = '';
208
284
  var displayRun = activeRun || lastRun;
209
285
  if (displayRun && (p.stages || []).length > 0) {
210
- progressHtml = _buildProgressBar(p.stages || [], displayRun);
286
+ progressHtml = _buildNodeChain(p.stages || [], displayRun, { compact: true, pipeline: p });
211
287
  }
212
288
 
213
289
  // Monitored resources (pipeline-level + stage-level, compact on card)
@@ -224,7 +300,6 @@ function renderPipelines(pipelines) {
224
300
  (p.enabled === false ? '<span style="font-size:9px;color:var(--red)"' + (p._stopReason ? ' title="' + escHtml(p._stopReason) + '"' : '') + '>' + (p._stoppedBy ? 'AUTO-STOPPED' : 'DISABLED') + '</span>' : '') +
225
301
  '</div>' +
226
302
  '</div>' +
227
- '<div style="margin-top:6px;display:flex;gap:4px;align-items:center;flex-wrap:wrap">' + stageFlow + '</div>' +
228
303
  resourcesHtml +
229
304
  progressHtml +
230
305
  '</div>';
@@ -256,7 +331,7 @@ function openPipelineDetail(id) {
256
331
  // Stage detail with progress bar
257
332
  var detailRun = activeRun || (p.runs || []).slice(-1)[0];
258
333
  if (detailRun && (p.stages || []).length > 0) {
259
- html += _buildProgressBar(p.stages || [], detailRun, { height: '8px', detailLabel: true });
334
+ html += _buildNodeChain(p.stages || [], detailRun, { compact: false, pipeline: p });
260
335
  }
261
336
  // Pipeline-level monitored resources (full view in detail)
262
337
  var pipelineResources = _collectMonitoredResources(p);
@@ -192,6 +192,19 @@
192
192
  .pl-prog-seg.pending { background: transparent; }
193
193
  @keyframes plSegPulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } }
194
194
  .pl-progress-label { display: flex; gap: 8px; align-items: center; margin-top: 4px; font-size: 10px; }
195
+ .pl-node-chain { display: flex; align-items: flex-start; gap: 2px; overflow-x: auto; padding: 8px 0; }
196
+ .pl-node { display: flex; flex-direction: column; align-items: center; flex-shrink: 0; }
197
+ .pl-node-box { padding: 4px 8px; border-radius: 6px; border: 2px solid var(--border); background: var(--surface2); text-align: center; font-size: 10px; transition: border-color 0.2s; white-space: nowrap; }
198
+ .pl-node-box.complete { border-color: var(--green); background: rgba(63,185,80,0.08); }
199
+ .pl-node-box.running { border-color: var(--blue); animation: plSegPulse 1.5s ease-in-out infinite; }
200
+ .pl-node-box.failed { border-color: var(--red); background: rgba(248,81,73,0.08); }
201
+ .pl-node-box.waiting { border-color: var(--yellow); }
202
+ .pl-node-box.pending { border-color: var(--border); opacity: 0.6; }
203
+ .pl-node-box.condition { border-style: dashed; }
204
+ .pl-node-box.pl-node-stop { border-style: dotted; border-color: var(--muted); opacity: 0.7; }
205
+ .pl-node-arrow { display: flex; align-items: center; padding: 0 2px; color: var(--muted); font-size: 12px; flex-shrink: 0; margin-top: 8px; }
206
+ .pl-node-meta { font-size: 9px; color: var(--muted); margin-top: 2px; text-align: center; max-width: 120px; overflow: hidden; text-overflow: ellipsis; }
207
+ .pl-node-loop { font-size: 10px; color: var(--muted); margin-top: 6px; display: flex; align-items: center; gap: 6px; }
195
208
  .prd-items-list { display: flex; flex-direction: column; gap: 3px; max-height: 400px; overflow-y: auto; padding: 0 8px; }
196
209
  .prd-item-row { display: flex; align-items: center; gap: 8px; padding: 4px 8px; border-radius: var(--radius-sm); font-size: var(--text-base); background: var(--surface2); border: 1px solid var(--border); border-left: 3px solid var(--border); }
197
210
  .prd-item-row.st-done { border-left-color: var(--green); }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.680",
3
+ "version": "0.1.682",
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"