@yemi33/minions 0.1.677 → 0.1.678

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,8 +1,9 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.677 (2026-04-09)
3
+ ## 0.1.678 (2026-04-09)
4
4
 
5
5
  ### Fixes
6
+ - plan/PRD button consistency, remove auto-archive, UX fixes
6
7
  - abort button shows 'Aborting...' then becomes 'Run Now'
7
8
 
8
9
  ## 0.1.676 (2026-04-09)
@@ -207,10 +207,10 @@ function renderPlans(plans) {
207
207
 
208
208
  let actions = '';
209
209
  if (needsAction) {
210
- // Approve/Reject target the PRD .json file (not the .md plan) since the API parses it as JSON
211
210
  const actionTarget = prdFile || p.file;
211
+ const actionLabel = effectiveStatus === 'paused' ? 'Resume' : 'Approve';
212
212
  actions = '<div class="plan-card-actions" onclick="event.stopPropagation()">' +
213
- '<button class="plan-btn approve" onclick="planApprove(\'' + escHtml(actionTarget) + '\')">Approve</button>' +
213
+ '<button class="plan-btn approve" onclick="planApprove(\'' + escHtml(actionTarget) + '\')">' + actionLabel + '</button>' +
214
214
  '<button class="plan-btn reject" onclick="planReject(\'' + escHtml(actionTarget) + '\')">Reject</button>' +
215
215
  '</div>';
216
216
  } else if (isRevision) {
@@ -220,7 +220,8 @@ function renderPlans(plans) {
220
220
  const executeBtn = isDraft && (effectiveStatus === 'active' || effectiveStatus === 'draft') && !isArchived && !prdFile ? '<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px;color:var(--green);font-weight:600" ' +
221
221
  'onclick="event.stopPropagation();planExecute(\'' + escHtml(p.file) + '\',\'' + escHtml(p.project) + '\',this)">Execute</button>' : '';
222
222
  const showPause = effectiveStatus === 'dispatched' && prdFile && !isArchived;
223
- const showResume = (effectiveStatus === 'paused' || effectiveStatus === 'awaiting-approval') && prdFile && !isArchived;
223
+ // Resume pill not needed paused state is handled by the actions block above
224
+ const showResume = false;
224
225
  const verifyWi = allWi.find(w => w.itemType === 'verify' && w.sourcePlan === prdFile);
225
226
  const hasVerifyWi = !!verifyWi;
226
227
  const showVerify = effectiveStatus === 'completed' && prdFile && !isArchived && !hasVerifyWi;
@@ -228,7 +229,7 @@ function renderPlans(plans) {
228
229
  'onclick="event.stopPropagation();planPause(\'' + escHtml(prdFile) + '\',this)">Pause</button>' : '';
229
230
  const resumeBtn = showResume
230
231
  ? '<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px;color:var(--green)" ' +
231
- 'onclick="event.stopPropagation();planApprove(\'' + escHtml(prdFile) + '\',this)">' + (effectiveStatus === 'awaiting-approval' ? 'Approve' : 'Resume') + '</button>'
232
+ 'onclick="event.stopPropagation();planApprove(\'' + escHtml(prdFile) + '\',this)">Resume</button>'
232
233
  : '';
233
234
  const verifyBtn = showVerify ? '<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px;color:var(--green)" ' +
234
235
  'onclick="event.stopPropagation();triggerVerify(\'' + escHtml(prdFile) + '\',this)">Verify</button>' : '';
@@ -433,18 +434,29 @@ function _renderPlanModal(normalizedFile, raw, lastMod) {
433
434
  (w.planFile === normalizedFile || w.sourcePlan === normalizedFile ||
434
435
  (linkedPrdFile && w.sourcePlan === linkedPrdFile))
435
436
  );
436
- const prdCompleted = wi.some(w => w.type === 'plan-to-prd' && w.status === 'done' && w.planFile === normalizedFile);
437
- const hasPrd = (window._lastStatus?.plans || []).some(p => p.sourcePlan === normalizedFile && p.format === 'prd');
438
- const modalShowResume = isPaused;
437
+ const prdConversion = wi.find(w => w.type === 'plan-to-prd' && w.status === 'done' && w.planFile === normalizedFile);
438
+ const linkedPrd = (window._lastStatus?.plans || []).find(p => p.sourcePlan === normalizedFile && p.format === 'prd');
439
+ const hasPrd = !!linkedPrd;
440
+ // Plan-to-prd conversion done is not "completed" — the PRD still needs approval and execution
441
+ const prdCompleted = prdConversion && linkedPrd && linkedPrd.status === 'completed';
442
+ const linkedPrdAwaiting = linkedPrd && (linkedPrd.status === 'awaiting-approval' || linkedPrd.status === 'paused');
443
+ const modalShowResume = isPaused || linkedPrdAwaiting;
439
444
  const modalExecuteBtn = isMdPlan && !modalShowResume && !hasActiveWork && !prdCompleted && !hasPrd ? '<button class="pr-pager-btn" style="font-size:10px;padding:2px 10px;color:var(--green);font-weight:600" ' +
440
445
  'onclick="planExecute(\'' + escHtml(normalizedFile) + '\',\'\',this)">Execute</button>' : '';
441
446
  const modalCompletedLabel = prdCompleted && !hasActiveWork ? '<span style="font-size:10px;color:var(--green);font-weight:600">Completed</span>' : '';
447
+ const modalAwaitingLabel = linkedPrdAwaiting && !hasActiveWork && !prdCompleted ? '<span style="font-size:10px;color:var(--yellow);font-weight:600">Awaiting Approval</span>' : '';
442
448
  const modalInProgressLabel = hasActiveWork ? '<span style="font-size:10px;color:var(--blue)">In Progress</span>' : '';
443
449
  const isModalCompleted = planStatus === 'completed';
444
450
  const modalPauseBtn = isActive && !isMdPlan && !isModalCompleted ? '<button class="pr-pager-btn" style="font-size:10px;padding:2px 10px;color:var(--yellow)" ' +
445
451
  'onclick="planPause(\'' + escHtml(normalizedFile) + '\',this)">Pause</button>' : '';
446
- const modalResumeBtn = isPaused ? '<button class="pr-pager-btn" style="font-size:10px;padding:2px 10px;color:var(--green)" ' +
447
- 'onclick="planApprove(\'' + escHtml(normalizedFile) + '\',this)">Resume</button>' : '';
452
+ const modalApproveTarget = linkedPrdAwaiting ? linkedPrd.file : normalizedFile;
453
+ const isActuallyPaused = planStatus === 'paused' || linkedPrd?.status === 'paused';
454
+ const modalApproveLabel = isActuallyPaused ? 'Resume' : 'Approve';
455
+ const showRejectInModal = linkedPrdAwaiting || planStatus === 'awaiting-approval';
456
+ const modalResumeBtn = modalShowResume ? '<button class="pr-pager-btn" style="font-size:10px;padding:2px 10px;color:var(--green)" ' +
457
+ 'onclick="planApprove(\'' + escHtml(modalApproveTarget) + '\',this)">' + modalApproveLabel + '</button>' +
458
+ (showRejectInModal ? ' <button class="pr-pager-btn" style="font-size:10px;padding:2px 10px;color:var(--red)" ' +
459
+ 'onclick="planReject(\'' + escHtml(modalApproveTarget) + '\')">Reject</button>' : '') : '';
448
460
  const modalVerifyWi = (window._lastWorkItems || []).find(w => w.itemType === 'verify' && w.sourcePlan === normalizedFile);
449
461
  const modalVerifyBtn = isModalCompleted && !modalVerifyWi ? '<button class="pr-pager-btn" style="font-size:10px;padding:2px 10px;color:var(--green)" ' +
450
462
  'onclick="triggerVerify(\'' + escHtml(normalizedFile) + '\',this)">Verify</button>' : '';
@@ -453,7 +465,7 @@ function _renderPlanModal(normalizedFile, raw, lastMod) {
453
465
  'onclick="planArchive(\'' + escHtml(normalizedFile) + '\')">Archive</button>';
454
466
  const lastModLabel = lastMod ? '<div style="font-size:10px;color:var(--muted);font-weight:400;margin-top:2px">Last updated: ' + new Date(lastMod).toLocaleString() + '</div>' : '';
455
467
  const actionBtns = '<div style="display:flex;gap:4px;flex-wrap:wrap;margin-top:4px">' +
456
- (modalCompletedLabel || '') + (modalInProgressLabel || '') + (modalExecuteBtn || '') + (modalPauseBtn || '') + (modalResumeBtn || '') + (modalVerifyBtn || '') + (modalVerifyInfo || '') +
468
+ (modalCompletedLabel || '') + (modalAwaitingLabel || '') + (modalInProgressLabel || '') + (modalExecuteBtn || '') + (modalPauseBtn || '') + (modalResumeBtn || '') + (modalVerifyBtn || '') + (modalVerifyInfo || '') +
457
469
  ' ' + modalArchiveBtn +
458
470
  ' <button class="pr-pager-btn" style="font-size:10px;padding:2px 10px;color:var(--red)" ' +
459
471
  'onclick="planDelete(\'' + escHtml(normalizedFile) + '\')">Delete</button>' +
@@ -549,10 +561,15 @@ async function planDelete(file) {
549
561
  }
550
562
 
551
563
  async function planArchive(file, btn) {
564
+ var isPrd = file.endsWith('.json');
565
+ var confirmMsg = isPrd
566
+ ? 'Archive this PRD? The linked source plan will also be archived.'
567
+ : 'Archive this plan?';
568
+ if (!confirm(confirmMsg)) return;
552
569
  _stopPlanPoll();
553
570
  markDeleted('plan:' + file);
554
571
  try { closeModal(); } catch { /* may not be open */ }
555
- showToast('cmd-toast', 'Plan archived', true);
572
+ showToast('cmd-toast', 'Archiving...', true);
556
573
  try {
557
574
  const res = await fetch('/api/plans/archive', {
558
575
  method: 'POST', headers: { 'Content-Type': 'application/json' },
@@ -1245,18 +1245,7 @@ async function runPostCompletionHooks(dispatchItem, agentId, code, stdout, confi
1245
1245
  // Plan chaining removed — user must explicitly execute plan-to-prd after reviewing the plan
1246
1246
  if (effectiveSuccess && meta?.item?.sourcePlan) checkPlanCompletion(meta, config);
1247
1247
 
1248
- // After verify completes, archive the plan
1249
- if (effectiveSuccess && meta?.item?.itemType === 'verify' && meta?.item?.sourcePlan) {
1250
- try {
1251
- const vPlanFile = meta.item.sourcePlan;
1252
- const vPlanPath = path.join(PRD_DIR, vPlanFile);
1253
- const vPlan = safeJson(vPlanPath);
1254
- if (vPlan) {
1255
- const vProjects = shared.getProjects(config);
1256
- archivePlan(vPlanFile, vPlan, vProjects, config);
1257
- }
1258
- } catch (err) { log('warn', `Verify archive: ${err.message}`); }
1259
- }
1248
+ // Archive is manual user archives plans from the dashboard when ready
1260
1249
 
1261
1250
  // Clean up worktree for non-shared-branch tasks after completion
1262
1251
  if (meta?.branch && meta?.branchStrategy !== 'shared-branch') {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.677",
3
+ "version": "0.1.678",
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"