@yemi33/minions 0.1.401 → 0.1.403

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,11 +1,17 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.401 (2026-04-06)
3
+ ## 0.1.403 (2026-04-06)
4
+
5
+ ### Fixes
6
+ - version check works on pure npm installs without package.json in ~/.minions
7
+
8
+ ## 0.1.402 (2026-04-06)
4
9
 
5
10
  ### Features
6
11
  - pipeline stages detect and link inbox notes as artifacts
7
12
 
8
13
  ### Fixes
14
+ - prevent auto-review of human PRs + add unlink button
9
15
  - reconcilePrs only auto-tracks PRs linked to minions work items
10
16
  - auto-detect main branch when configured mainBranch doesn't exist
11
17
  - engine restart button shows toast + green checkmark, suppresses stale banner 30s
package/bin/minions.js CHANGED
@@ -233,9 +233,9 @@ function init() {
233
233
  '.npmignore', '.gitignore', '.github',
234
234
  ]);
235
235
 
236
- // Files that are always overwritten (engine code)
236
+ // Files that are always overwritten (engine code + version metadata)
237
237
  const alwaysUpdate = (name) =>
238
- name.endsWith('.js') || name.endsWith('.html');
238
+ name.endsWith('.js') || name.endsWith('.html') || name === 'package.json';
239
239
 
240
240
  // Files that should be added if missing but never overwritten (user customizations)
241
241
  const neverOverwrite = (name) =>
@@ -28,12 +28,13 @@ function prRow(pr) {
28
28
  '<td><span class="pr-badge ' + buildClass + '">' + escHtml(buildLabel) + '</span></td>' +
29
29
  '<td><span class="pr-badge ' + statusClass + '">' + escHtml(statusLabel) + '</span></td>' +
30
30
  '<td><span class="pr-date">' + escHtml((pr.created || '—').slice(0, 16).replace('T', ' ')) + '</span></td>' +
31
+ '<td><button class="pr-pager-btn" style="font-size:9px;padding:1px 5px;color:var(--red);border-color:var(--red)" data-pr-id="' + escHtml(String(prId)) + '" onclick="event.stopPropagation();unlinkPr(this.dataset.prId)" title="Remove from tracking">x</button></td>' +
31
32
  '</tr>';
32
33
  }
33
34
 
34
35
  function prTableHtml(rows) {
35
36
  return '<div class="pr-table-wrap"><table class="pr-table"><thead><tr>' +
36
- '<th>PR</th><th>Title</th><th>Agent</th><th>Branch</th><th>Review</th><th>Signed Off By</th><th>Build</th><th>Status</th><th>Created</th>' +
37
+ '<th>PR</th><th>Title</th><th>Agent</th><th>Branch</th><th>Review</th><th>Signed Off By</th><th>Build</th><th>Status</th><th>Created</th><th></th>' +
37
38
  '</tr></thead><tbody>' + rows + '</tbody></table></div>';
38
39
  }
39
40
 
@@ -150,4 +151,17 @@ async function _submitLinkPr() {
150
151
  } catch (e) { alert('Error: ' + e.message); openAddPrModal(); }
151
152
  }
152
153
 
153
- window.MinionsPrs = { prRow, prTableHtml, renderPrs, prPrev, prNext, openAllPrs, openModal, openAddPrModal };
154
+ async function unlinkPr(id) {
155
+ if (!confirm('Remove ' + id + ' from tracking?')) return;
156
+ try {
157
+ const res = await fetch('/api/pull-requests/delete', {
158
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
159
+ body: JSON.stringify({ id })
160
+ });
161
+ if (!res.ok) { const d = await res.json().catch(() => ({})); alert('Failed: ' + (d.error || 'unknown')); return; }
162
+ showToast('cmd-toast', id + ' removed', true);
163
+ refresh();
164
+ } catch (e) { alert('Error: ' + e.message); }
165
+ }
166
+
167
+ window.MinionsPrs = { prRow, prTableHtml, renderPrs, prPrev, prNext, openAllPrs, openModal, openAddPrModal, unlinkPr };
package/dashboard.js CHANGED
@@ -13,7 +13,7 @@ const llm = require('./engine/llm');
13
13
 
14
14
  // Dashboard version stamp — captured at module load so it reflects the code actually running
15
15
  const _dashboardVersion = {
16
- codeVersion: (() => { try { return require('./package.json').version; } catch { return null; } })(),
16
+ codeVersion: (() => { try { return require('./package.json').version; } catch {} try { return require('@yemi33/minions/package.json').version; } catch {} return null; })(),
17
17
  codeCommit: (() => { try { return require('child_process').execSync('git rev-parse --short HEAD', { cwd: __dirname, encoding: 'utf8', timeout: 5000, windowsHide: true }).trim(); } catch { return null; } })(),
18
18
  startedAt: new Date().toISOString(),
19
19
  pid: process.pid,
@@ -224,6 +224,10 @@ function getDiskVersion() {
224
224
  delete require.cache[pkgPath]; // bust Node's require cache so npm updates are detected
225
225
  diskVersion = require('./package.json').version;
226
226
  } catch {}
227
+ // Fallback: if no local package.json (e.g. ~/.minions/ missing it), try the npm package root
228
+ if (!diskVersion) {
229
+ try { diskVersion = require('@yemi33/minions/package.json').version; } catch {}
230
+ }
227
231
  let diskCommit = null;
228
232
  try { diskCommit = require('child_process').execSync('git rev-parse --short HEAD', { cwd: MINIONS_DIR, encoding: 'utf8', timeout: 5000, windowsHide: true }).trim(); } catch {}
229
233
  _diskVersionCache = { diskVersion, diskCommit };
@@ -3631,6 +3635,26 @@ What would you like to discuss or change? When you're happy, say "approve" and I
3631
3635
  return jsonReply(res, 200, { ok: true, id: prId });
3632
3636
  }},
3633
3637
 
3638
+ { method: 'POST', path: '/api/pull-requests/delete', desc: 'Remove a PR from tracking', params: 'id, project?', handler: async (req, res) => {
3639
+ const body = await readBody(req);
3640
+ const { id, project: projectName } = body;
3641
+ if (!id) return jsonReply(res, 400, { error: 'id required' });
3642
+ reloadConfig();
3643
+ const projects = shared.getProjects(CONFIG);
3644
+ const targetProject = projectName ? projects.find(p => p.name?.toLowerCase() === projectName.toLowerCase()) : projects[0];
3645
+ const prPath = targetProject ? shared.projectPrPath(targetProject) : path.join(MINIONS_DIR, 'pull-requests.json');
3646
+ let found = false;
3647
+ mutateJsonFileLocked(prPath, (prs) => {
3648
+ if (!Array.isArray(prs)) return prs;
3649
+ const idx = prs.findIndex(p => p.id === id);
3650
+ if (idx >= 0) { prs.splice(idx, 1); found = true; }
3651
+ return prs;
3652
+ }, { defaultValue: [] });
3653
+ if (!found) return jsonReply(res, 404, { error: 'PR not found' });
3654
+ invalidateStatusCache();
3655
+ return jsonReply(res, 200, { ok: true });
3656
+ }},
3657
+
3634
3658
  { method: 'POST', path: '/api/plans/create', desc: 'Create a plan from user-provided content', params: 'title, content, project?', handler: async (req, res) => {
3635
3659
  const body = await readBody(req);
3636
3660
  const { title, content, project: projectName } = body;
package/engine/cli.js CHANGED
@@ -87,6 +87,7 @@ const commands = {
87
87
  // Record version + git commit so dashboard can detect stale engine code
88
88
  let codeVersion = null;
89
89
  try { codeVersion = require('../package.json').version; } catch {}
90
+ if (!codeVersion) { try { codeVersion = require('@yemi33/minions/package.json').version; } catch {} }
90
91
  let codeCommit = null;
91
92
  try { codeCommit = require('child_process').execSync('git rev-parse --short HEAD', { cwd: path.resolve(__dirname, '..'), encoding: 'utf8', timeout: 5000, windowsHide: true }).trim(); } catch {}
92
93
  safeWrite(CONTROL_PATH, { state: 'running', pid: process.pid, started_at: e.ts(), codeVersion, codeCommit });
package/engine.js CHANGED
@@ -1261,9 +1261,14 @@ function discoverFromPrs(config, project) {
1261
1261
  (dispatch.active || []).filter(d => d.meta?.pr?.id).map(d => d.meta.pr.id)
1262
1262
  );
1263
1263
 
1264
+ const knownAgents = new Set(Object.keys(config.agents || {}));
1264
1265
  for (const pr of prs) {
1265
1266
  if (pr.status !== 'active') continue;
1266
1267
  if (activePrIds.has(pr.id)) continue; // Skip PRs with active dispatch (prevent race)
1268
+ // Skip human-authored PRs not linked to any work item — only auto-manage agent PRs
1269
+ // Manually-linked PRs with autoObserve are allowed through (they have _autoObserve flag)
1270
+ const isAgentPr = knownAgents.has((pr.agent || '').toLowerCase()) || (pr.prdItems && pr.prdItems.length > 0) || pr._autoObserve;
1271
+ if (!isAgentPr) continue;
1267
1272
 
1268
1273
  const prNumber = (pr.id || '').replace(/^PR-/, '');
1269
1274
  // Use reviewStatus as single source of truth (synced from ADO/GitHub votes)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.401",
3
+ "version": "0.1.403",
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"