@yemi33/minions 0.1.1731 → 0.1.1732

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,9 +1,13 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.1731 (2026-05-05)
3
+ ## 0.1.1732 (2026-05-05)
4
+
5
+ ### Features
6
+ - fix pipeline cron display (#2087)
7
+
8
+ ## 0.1.1730 (2026-05-05)
4
9
 
5
10
  ### Features
6
- - fix project discovery main branch fallback (#2085)
7
11
  - detect no-op PR fixes (#2077)
8
12
 
9
13
  ## 0.1.1728 (2026-05-05)
@@ -268,6 +268,13 @@ function _buildNodeChain(stages, run, options) {
268
268
  return html;
269
269
  }
270
270
 
271
+ function _renderPipelineTriggerLabel(cron) {
272
+ if (!cron) return 'Manual trigger';
273
+ var human = _cronToHuman(cron);
274
+ var tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
275
+ return escHtml(human) + ' <span style="opacity:0.6">(' + escHtml(tz) + ')</span>';
276
+ }
277
+
271
278
  function renderPipelines(pipelines) {
272
279
  pipelines = (pipelines || []).filter(function(p) { return !isDeleted('pipeline:' + p.id); });
273
280
  _pipelinesData = pipelines;
@@ -331,7 +338,7 @@ function openPipelineDetail(id) {
331
338
  // Status + actions
332
339
  var activeRun = _getPipelineActiveRun(p);
333
340
  html += '<div style="display:flex;justify-content:space-between;align-items:center">' +
334
- '<span style="font-size:10px;color:var(--muted)">' + (p.trigger?.cron ? escHtml(_cronToHuman(p.trigger.cron)) + ' <span style="opacity:0.6">(' + escHtml(p.trigger.cron) + ', ' + escHtml(Intl.DateTimeFormat().resolvedOptions().timeZone) + ')</span>' : 'Manual trigger') + ' · ' + escHtml(_getPipelineStageLabel(p)) + '</span>' +
341
+ '<span style="font-size:10px;color:var(--muted)">' + _renderPipelineTriggerLabel(p.trigger?.cron) + ' · ' + escHtml(_getPipelineStageLabel(p)) + '</span>' +
335
342
  '<div style="display:flex;gap:6px">' +
336
343
  (activeRun
337
344
  ? '<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px;color:var(--red);border-color:var(--red)" onclick="_abortPipeline(\'' + escHtml(id) + '\',this)">Abort</button>' +
@@ -5,14 +5,50 @@
5
5
  const _DAYS = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];
6
6
  const _DAY_NAMES = ['Sundays', 'Mondays', 'Tuesdays', 'Wednesdays', 'Thursdays', 'Fridays', 'Saturdays'];
7
7
 
8
- /** Convert 3-field cron (minute hour dayOfWeek) to human-readable text */
8
+ function _formatCronDowList(days, timeStr, fallback) {
9
+ const normalized = [...new Set(days)].sort((a, b) => a - b);
10
+ const key = normalized.join(',');
11
+ if (key === '0,1,2,3,4,5,6') return 'Daily at ' + timeStr;
12
+ if (key === '1,2,3,4,5') return 'Weekdays at ' + timeStr;
13
+ if (key === '0,6') return 'Weekends at ' + timeStr;
14
+ if (normalized.length === 1) return _DAY_NAMES[normalized[0]] + ' at ' + timeStr;
15
+ if (normalized.length > 1) return normalized.map(d => _DAY_NAMES[d]).join(', ') + ' at ' + timeStr;
16
+ return fallback;
17
+ }
18
+
19
+ function _parseCronDowList(dow, allowSevenAsSunday) {
20
+ if (!dow || typeof dow !== 'string') return null;
21
+ const values = [];
22
+ const parts = dow.split(',');
23
+ for (const part of parts) {
24
+ const token = part.trim();
25
+ if (!/^\d+$/.test(token)) return null;
26
+ let day = parseInt(token, 10);
27
+ if (allowSevenAsSunday && day === 7) day = 0;
28
+ if (day < 0 || day > 6) return null;
29
+ values.push(day);
30
+ }
31
+ return values;
32
+ }
33
+
34
+ function _cronTimeString(minute, hour) {
35
+ const h = parseInt(hour, 10);
36
+ const m = parseInt(minute, 10);
37
+ if (isNaN(h) || isNaN(m)) return null;
38
+ return String(h).padStart(2, '0') + ':' + String(m).padStart(2, '0');
39
+ }
40
+
41
+ /** Convert 3-field Minions cron or common 5-field cron to human-readable text */
9
42
  function _cronToHuman(cron) {
10
43
  if (!cron || typeof cron !== 'string') return cron || '';
11
44
  const parts = cron.trim().split(/\s+/);
12
- if (parts.length !== 3) return cron;
13
- const [minute, hour, dow] = parts;
45
+ if (parts.length !== 3 && parts.length !== 5) return cron;
46
+ const minute = parts[0];
47
+ const hour = parts[1];
48
+ const dow = parts.length === 3 ? parts[2] : parts[4];
14
49
 
15
- if (minute === '*' && hour === '*' && dow === '*') return 'Every minute';
50
+ if (parts.length === 5 && (parts[2] !== '*' || parts[3] !== '*')) return cron;
51
+ if (parts.length === 3 && minute === '*' && hour === '*' && dow === '*') return 'Every minute';
16
52
 
17
53
  const h = parseInt(hour, 10);
18
54
  const m = parseInt(minute, 10);
@@ -26,13 +62,20 @@ function _cronToHuman(cron) {
26
62
  const normalized = dow.split(',').map(d => d.trim()).sort().join(',');
27
63
  if (dow === '1-5' || normalized === '1,2,3,4,5') return 'Weekdays at ' + timeStr;
28
64
  if (normalized === '0,6' || normalized === '6,0') return 'Weekends at ' + timeStr;
65
+ if (parts.length === 5 && (dow === '0-6' || dow === '0-7')) return 'Daily at ' + timeStr;
29
66
 
30
67
  // Single day
31
- const dayNum = parseInt(dow, 10);
32
- if (!isNaN(dayNum) && dayNum >= 0 && dayNum <= 6 && String(dayNum) === dow) {
68
+ let dayNum = parseInt(dow, 10);
69
+ if (parts.length === 5 && dayNum === 7 && dow === '7') dayNum = 0;
70
+ if (!isNaN(dayNum) && dayNum >= 0 && dayNum <= 6 && String(parseInt(dow, 10)) === dow) {
33
71
  return _DAY_NAMES[dayNum] + ' at ' + timeStr;
34
72
  }
35
73
 
74
+ if (parts.length === 5) {
75
+ const days = _parseCronDowList(dow, true);
76
+ if (days) return _formatCronDowList(days, timeStr, cron);
77
+ }
78
+
36
79
  return cron;
37
80
  }
38
81
 
@@ -1,5 +1,5 @@
1
1
  {
2
2
  "runtime": "copilot",
3
3
  "models": null,
4
- "cachedAt": "2026-05-05T09:51:05.191Z"
4
+ "cachedAt": "2026-05-05T09:53:42.976Z"
5
5
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.1731",
3
+ "version": "0.1.1732",
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"