@yemi33/minions 0.1.725 → 0.1.727

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.727 (2026-04-09)
4
+
5
+ ### Features
6
+ - make post-verify plan archiving opt-in via autoArchive config
7
+
8
+ ### Fixes
9
+ - reject JSON/UUID fragments as PR titles, self-heal from platform
10
+
3
11
  ## 0.1.725 (2026-04-09)
4
12
 
5
13
  ### Fixes
@@ -183,7 +183,11 @@ function renderPlans(plans) {
183
183
  let prdJsonStatus = p.status || 'active';
184
184
  if (prdFile && p.format !== 'prd') {
185
185
  const linkedPrd = plans.find(pp => pp.file === prdFile && pp.format === 'prd');
186
- if (linkedPrd) prdJsonStatus = linkedPrd.status || prdJsonStatus;
186
+ if (linkedPrd) {
187
+ prdJsonStatus = linkedPrd.status || prdJsonStatus;
188
+ // Propagate archiveReady from PRD to source .md plan card
189
+ if (linkedPrd.archiveReady) p.archiveReady = true;
190
+ }
187
191
  else if (!linkedPrd) {
188
192
  const archivedPrd = archivedPlans.find(pp => pp.file === prdFile && pp.format === 'prd');
189
193
  if (archivedPrd) prdJsonStatus = 'completed';
@@ -245,8 +249,12 @@ function renderPlans(plans) {
245
249
  'onclick="event.stopPropagation();triggerVerify(\'' + escHtml(prdFile) + '\',this)">Verify</button>' : '';
246
250
  const showArchive = !isArchived;
247
251
  const archiveFile = prdFile || p.file;
248
- const archiveBtn = showArchive ? '<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px" ' +
249
- 'onclick="event.stopPropagation();planArchive(\'' + escHtml(archiveFile) + '\',this)">Archive</button>' : '';
252
+ const archiveReady = p.archiveReady && !isArchived;
253
+ const archiveBtn = showArchive ? '<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px' +
254
+ (archiveReady ? ';color:var(--green);font-weight:600;border:1px solid var(--green)' : '') + '" ' +
255
+ 'onclick="event.stopPropagation();planArchive(\'' + escHtml(archiveFile) + '\',this)">' +
256
+ (archiveReady ? '✓ Archive' : 'Archive') + '</button>' : '';
257
+ const archiveReadyBadge = archiveReady ? '<span style="font-size:9px;font-weight:600;padding:1px 6px;border-radius:3px;background:rgba(63,185,80,0.15);color:var(--green);vertical-align:middle" title="Verification passed — ready to archive">Ready to archive</span>' : '';
250
258
  const deleteBtn = !isArchived ? '<button class="pr-pager-btn" style="font-size:9px;padding:2px 8px;color:var(--red)" ' +
251
259
  'onclick="event.stopPropagation();planDelete(\'' + escHtml(p.file) + '\')">Delete</button>' : '';
252
260
 
@@ -263,7 +271,7 @@ function renderPlans(plans) {
263
271
  (p.updatedAt ? '<span title="Last updated: ' + p.updatedAt + '">Updated ' + timeAgo(p.updatedAt) + '</span>' : '') +
264
272
  (p.completedAt ? '<span>' + p.completedAt.slice(0, 10) + '</span>' : '') +
265
273
  (p.generatedBy ? '<span>by ' + escHtml(p.generatedBy) + '</span>' : '') +
266
- executeBtn + pauseBtn + resumeBtn + verifyBtn + (hasVerifyWi ? _renderVerifyBadge(verifyWi) : '') + archiveBtn + deleteBtn +
274
+ executeBtn + pauseBtn + resumeBtn + verifyBtn + (hasVerifyWi ? _renderVerifyBadge(verifyWi) : '') + archiveReadyBadge + archiveBtn + deleteBtn +
267
275
  '</div>' +
268
276
  '</div>' +
269
277
  '</div>' +
@@ -47,6 +47,7 @@ async function openSettings() {
47
47
  settingsToggle('Eval Loop', 'set-evalLoop', e.evalLoop !== false, 'Auto-review implementations and iterate fix cycles until pass') +
48
48
  settingsToggle('Auto-decompose', 'set-autoDecompose', e.autoDecompose !== false, 'Large implement items are auto-split into sub-tasks') +
49
49
  settingsToggle('Allow Temp Agents', 'set-allowTempAgents', !!e.allowTempAgents, 'Spawn ephemeral agents when all permanent agents are busy') +
50
+ settingsToggle('Auto-archive Plans', 'set-autoArchive', !!e.autoArchive, 'Automatically archive plans after verify completes (off = manual archive via dashboard)') +
50
51
  '</div>' +
51
52
  '<div style="display:grid;grid-template-columns:1fr 1fr;gap:8px;margin-bottom:16px">' +
52
53
  settingsField('Eval Max Iterations', 'set-evalMaxIterations', e.evalMaxIterations || 3, '', 'Max review→fix cycles before escalating (1-10)') +
@@ -205,6 +206,7 @@ async function saveSettings() {
205
206
  evalLoop: document.getElementById('set-evalLoop').checked,
206
207
  autoDecompose: document.getElementById('set-autoDecompose').checked,
207
208
  allowTempAgents: document.getElementById('set-allowTempAgents').checked,
209
+ autoArchive: document.getElementById('set-autoArchive').checked,
208
210
  evalMaxIterations: document.getElementById('set-evalMaxIterations').value,
209
211
  evalMaxCost: document.getElementById('set-evalMaxCost').value || null,
210
212
  maxBuildFixAttempts: document.getElementById('set-maxBuildFixAttempts').value,
package/dashboard.js CHANGED
@@ -1941,6 +1941,8 @@ If nothing to do: { "duplicates": [], "reclassify": [], "remove": [] }`;
1941
1941
  requiresApproval: plan.requires_approval || false,
1942
1942
  revisionFeedback: plan.revision_feedback || null,
1943
1943
  sourcePlan: plan.source_plan || null,
1944
+ archiveReady: plan._archiveReady || false,
1945
+ archiveReadyAt: plan._archiveReadyAt || null,
1944
1946
  });
1945
1947
  } catch { /* JSON parse fallback */ }
1946
1948
  } else {
@@ -3555,7 +3557,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
3555
3557
  config.engine.maxTurnsByType = mbt;
3556
3558
  }
3557
3559
  // Boolean fields
3558
- for (const key of ['autoApprovePlans', 'evalLoop', 'autoDecompose', 'allowTempAgents']) {
3560
+ for (const key of ['autoApprovePlans', 'evalLoop', 'autoDecompose', 'allowTempAgents', 'autoArchive']) {
3559
3561
  if (e[key] !== undefined) config.engine[key] = !!e[key];
3560
3562
  }
3561
3563
  // Eval loop settings
package/engine/github.js CHANGED
@@ -229,7 +229,9 @@ async function forEachActiveGhPr(config, callback) {
229
229
  if (pr.title.includes('polling...') || pr.agent === 'human' || pr.description === undefined) {
230
230
  const prData = await ghApi(`/pulls/${prNum}`, slug);
231
231
  if (prData) {
232
- if (pr.title.includes('polling...')) pr.title = (prData.title || pr.title).slice(0, 120);
232
+ if (pr.title.includes('polling...') || /[{}"\[\]]/.test(pr.title) || /^[0-9a-f-]{8,}$/i.test(pr.title)) {
233
+ pr.title = (prData.title || pr.title).slice(0, 120);
234
+ }
233
235
  if (pr.description === undefined) pr.description = (prData.body || '').slice(0, 500);
234
236
  if (pr.agent === 'human' && prData.user?.login) pr.agent = prData.user.login;
235
237
  if (!pr.branch && prData.head?.ref) pr.branch = prData.head.ref;
@@ -657,7 +657,7 @@ function syncPrsFromOutput(output, agentId, meta, config) {
657
657
  let title = meta?.item?.title || '';
658
658
  const titleMatch = output.match(new RegExp(`${prId}[^\\n]*?[—–-]\\s*([^\\n]+)`, 'i'));
659
659
  if (titleMatch) title = titleMatch[1].trim();
660
- if (title.includes('session_id') || title.includes('is_error') || title.includes('uuid') || title.length > 120) {
660
+ if (title.includes('session_id') || title.includes('is_error') || title.includes('uuid') || title.length > 120 || /[{}"\[\]]/.test(title) || /^[0-9a-f-]{8,}$/i.test(title)) {
661
661
  title = meta?.item?.title || '';
662
662
  }
663
663
 
package/engine/shared.js CHANGED
@@ -530,6 +530,7 @@ const ENGINE_DEFAULTS = {
530
530
  allowTempAgents: false, // opt-in: spawn ephemeral agents when all permanent agents are busy
531
531
  autoDecompose: true, // auto-decompose implement:large items into sub-tasks
532
532
  autoApprovePlans: false, // auto-approve PRDs without waiting for human approval
533
+ autoArchive: false, // opt-in: auto-archive plans after verify completes (false = mark ready, user archives manually)
533
534
  autoReview: true, // auto-dispatch review agents for new PRs (disable for manual review workflow)
534
535
  meetingRoundTimeout: 600000, // 10min per meeting round before auto-advance
535
536
  evalLoop: true, // enable review→fix loop after implementation completes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.725",
3
+ "version": "0.1.727",
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"