@yemi33/minions 0.1.204 → 0.1.206

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,18 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.206 (2026-04-02)
4
+
5
+ ### Other
6
+ - minions.js
7
+
8
+ ## 0.1.205 (2026-04-02)
9
+
10
+ ### Engine
11
+ - engine/queries.js
12
+
13
+ ### Dashboard
14
+ - dashboard/js/render-agents.js
15
+
3
16
  ## 0.1.204 (2026-04-02)
4
17
 
5
18
  ### Other
@@ -11,6 +11,8 @@ function renderAgents(agents) {
11
11
  </div>
12
12
  <div class="agent-role">${a.role}</div>
13
13
  <div class="agent-action" title="${escHtml(a.lastAction)}">${escHtml(a.lastAction)}</div>
14
+ ${a._warning ? `<div style="margin-top:4px;padding:4px 8px;background:rgba(210,153,34,0.15);border:1px solid rgba(210,153,34,0.3);border-radius:4px;font-size:10px;color:var(--yellow)">&#x26A0; ${escHtml(a._warning)}</div>` : ''}
15
+ ${a._permissionMode && a._permissionMode !== 'bypassPermissions' && !a._warning ? `<div style="margin-top:4px;font-size:9px;color:var(--muted)">Permission mode: ${escHtml(a._permissionMode)}</div>` : ''}
14
16
  ${a.resultSummary ? `<div class="agent-result" title="${escHtml(a.resultSummary)}">${renderMd(a.resultSummary.slice(0, 200))}${a.resultSummary.length > 200 ? '...' : ''}</div>` : ''}
15
17
  </div>
16
18
  `).join('');
package/engine/queries.js CHANGED
@@ -118,7 +118,7 @@ function getAgentStatus(agentId) {
118
118
  // Check active dispatch
119
119
  const active = (dispatch.active || []).find(d => d.agent === agentId);
120
120
  if (active) {
121
- return {
121
+ const result = {
122
122
  status: 'working',
123
123
  task: active.task || '',
124
124
  dispatch_id: active.id,
@@ -126,6 +126,27 @@ function getAgentStatus(agentId) {
126
126
  branch: active.meta?.branch || '',
127
127
  started_at: active.started_at || active.created_at || null,
128
128
  };
129
+ // Detect permission-waiting: check live output for non-bypass permission mode
130
+ try {
131
+ const liveLog = shared.safeRead(path.join(AGENTS_DIR, agentId, 'live-output.log'));
132
+ if (liveLog) {
133
+ // Check init message for permission mode
134
+ const initMatch = liveLog.match(/"permissionMode"\s*:\s*"([^"]+)"/);
135
+ if (initMatch && initMatch[1] !== 'bypassPermissions') {
136
+ result._permissionMode = initMatch[1];
137
+ }
138
+ // Check if agent has been silent for >60s (possible permission prompt wait)
139
+ const lastLine = liveLog.trimEnd().split('\n').pop();
140
+ if (lastLine && lastLine.includes('"type":"assistant"') && lastLine.includes('"tool_use"')) {
141
+ const liveStat = fs.statSync(path.join(AGENTS_DIR, agentId, 'live-output.log'));
142
+ const silentMs = Date.now() - liveStat.mtimeMs;
143
+ if (silentMs > 60000 && result._permissionMode) {
144
+ result._warning = 'Possibly waiting for permission approval — agent is not in bypass mode';
145
+ }
146
+ }
147
+ }
148
+ } catch { /* optional — don't block status */ }
149
+ return result;
129
150
  }
130
151
 
131
152
  // Check most recent completed dispatch (within last 5 minutes → show done/error)
@@ -218,6 +239,8 @@ function getAgents(config) {
218
239
  ...a, status: s.status, lastAction,
219
240
  currentTask: (s.task || '').slice(0, 200),
220
241
  resultSummary: (s.resultSummary || '').slice(0, 500),
242
+ _warning: s._warning || null,
243
+ _permissionMode: s._permissionMode || null,
221
244
  chartered, inboxCount: inboxFiles.length
222
245
  };
223
246
  });
package/minions.js CHANGED
@@ -281,25 +281,34 @@ function findGitRepos(rootDir, maxDepth = 3) {
281
281
  }
282
282
 
283
283
  async function scanAndAdd({ root, depth } = {}) {
284
- let scanRoot;
284
+ let scanRoots;
285
285
  if (root) {
286
- scanRoot = path.resolve(root);
286
+ scanRoots = [path.resolve(root)];
287
287
  } else {
288
288
  const homeDir = process.env.USERPROFILE || process.env.HOME || '';
289
- const answer = await ask('Where are your projects?', homeDir);
290
- scanRoot = path.resolve(answer);
289
+ const answer = await ask('Where are your projects? (comma-separate for multiple)', homeDir);
290
+ scanRoots = answer.split(',').map(s => path.resolve(s.trim())).filter(Boolean);
291
291
  }
292
- if (!fs.existsSync(scanRoot)) {
293
- console.log(` Directory not found: ${scanRoot}\n`);
292
+ // Validate all paths
293
+ const validRoots = [];
294
+ for (const r of scanRoots) {
295
+ if (fs.existsSync(r)) { validRoots.push(r); }
296
+ else { console.log(` Directory not found (skipping): ${r}`); }
297
+ }
298
+ if (validRoots.length === 0) {
299
+ console.log(' No valid directories to scan.\n');
294
300
  rl.close();
295
301
  return;
296
302
  }
297
303
  const maxDepth = depth !== undefined ? (parseInt(depth, 10) || 4) : 4;
298
304
 
299
- console.log(`\n Scanning for git repos in: ${scanRoot}`);
300
- console.log(` Max depth: ${maxDepth}\n`);
301
-
302
- const repos = findGitRepos(scanRoot, maxDepth);
305
+ let repos = [];
306
+ for (const scanRoot of validRoots) {
307
+ console.log(`\n Scanning: ${scanRoot} (depth ${maxDepth})`);
308
+ repos.push(...findGitRepos(scanRoot, maxDepth));
309
+ }
310
+ // Deduplicate by resolved path
311
+ repos = [...new Map(repos.map(r => [path.resolve(r), r])).values()];
303
312
  if (repos.length === 0) {
304
313
  console.log(' No git repositories found.\n');
305
314
  rl.close();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.204",
3
+ "version": "0.1.206",
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"