@yemi33/minions 0.1.174 → 0.1.176

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,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.176 (2026-04-02)
4
+
5
+ ### Engine
6
+ - engine/meeting.js
7
+
8
+ ### Dashboard
9
+ - dashboard/js/settings.js
10
+
11
+ ## 0.1.175 (2026-04-02)
12
+
13
+ ### Engine
14
+ - engine/cli.js
15
+
16
+ ### Dashboard
17
+ - dashboard/js/refresh.js
18
+ - dashboard/layout.html
19
+
20
+ ### Other
21
+ - minions.js
22
+
3
23
  ## 0.1.174 (2026-04-02)
4
24
 
5
25
  ### Dashboard
@@ -97,7 +97,9 @@ function _processStatusUpdate(data) {
97
97
  }
98
98
  document.getElementById('ts').textContent = new Date(data.timestamp).toLocaleTimeString();
99
99
  const engineState = (data.engine && data.engine.state) ? data.engine.state : 'stopped';
100
- document.getElementById('setup-banner').style.display = (!data.initialized && engineState !== 'stopped') ? 'block' : 'none';
100
+ // Show setup banner if no projects linked (the key onboarding step)
101
+ const noProjects = !data.projects || data.projects.length === 0;
102
+ document.getElementById('setup-banner').style.display = (noProjects && engineState !== 'stopped') ? 'block' : 'none';
101
103
  renderAgents(data.agents);
102
104
  renderPrdProgress(data.prdProgress);
103
105
  _cachePrdItems(data.prdProgress);
@@ -162,7 +164,16 @@ async function refresh() {
162
164
  refresh();
163
165
 
164
166
  // Poll for status updates (SSE caused HTTP/1.1 connection exhaustion — CC fetch would fail)
165
- setInterval(refresh, 4000);
167
+ var _refreshTimer = setInterval(refresh, 4000);
168
+ document.addEventListener('visibilitychange', function() {
169
+ if (document.hidden) {
170
+ clearInterval(_refreshTimer);
171
+ _refreshTimer = null;
172
+ } else if (!_refreshTimer) {
173
+ refresh();
174
+ _refreshTimer = setInterval(refresh, 4000);
175
+ }
176
+ });
166
177
 
167
178
  // Wire sidebar navigation
168
179
  document.querySelectorAll('.sidebar-link').forEach(link => {
@@ -66,6 +66,7 @@ async function openSettings() {
66
66
 
67
67
  // Add save button to modal header actions (next to copy/close)
68
68
  const actions = document.querySelector('.modal-header-actions');
69
+ if (!actions) return;
69
70
  const existingSaveBtn = document.getElementById('modal-settings-save');
70
71
  if (!existingSaveBtn) {
71
72
  const saveBtn = document.createElement('button');
@@ -21,7 +21,7 @@
21
21
  <div class="engine-alert" id="engine-alert"></div>
22
22
 
23
23
  <!-- Command Center Drawer -->
24
- <div id="cc-drawer" style="display:none;position:fixed;top:0;right:0;bottom:0;width:420px;background:var(--surface);border-left:1px solid var(--border);z-index:300;flex-direction:column;overscroll-behavior:contain">
24
+ <div id="cc-drawer" style="display:none;position:fixed;top:0;right:0;bottom:0;width:420px;background:var(--surface);border-left:1px solid var(--border);z-index:350;flex-direction:column;overscroll-behavior:contain">
25
25
  <div id="cc-resize-handle" class="cc-resize-handle"></div>
26
26
  <div style="padding:12px 16px;border-bottom:1px solid var(--border);display:flex;align-items:center;justify-content:space-between">
27
27
  <div style="display:flex;align-items:center;gap:8px">
@@ -48,10 +48,13 @@
48
48
  <div id="projects-list" style="display:flex;gap:8px;flex-wrap:wrap;">—</div>
49
49
  </div>
50
50
 
51
- <div id="setup-banner" style="display:none;margin:16px 24px;padding:16px 20px;background:var(--surface2);border:1px dashed var(--blue);border-radius:8px;text-align:center;color:var(--text)">
52
- <div style="font-size:18px;margin-bottom:6px">Welcome to Minions</div>
53
- <div style="color:var(--muted);font-size:13px;margin-bottom:10px">Your minions hasn't been initialized yet. Run the following command to get started:</div>
54
- <code style="background:var(--bg);padding:6px 16px;border-radius:4px;font-size:14px;color:var(--blue);border:1px solid var(--border)">minions init</code>
51
+ <div id="setup-banner" style="display:none;margin:16px 24px;padding:16px 20px;background:var(--surface2);border:1px dashed var(--blue);border-radius:8px;color:var(--text)">
52
+ <div style="font-size:18px;margin-bottom:6px;text-align:center">Getting Started</div>
53
+ <div style="color:var(--muted);font-size:13px;margin-bottom:12px;text-align:center">No projects linked yet. Link a project so agents know what code to work on.</div>
54
+ <div style="display:flex;flex-direction:column;gap:8px;align-items:center">
55
+ <code style="background:var(--bg);padding:6px 16px;border-radius:4px;font-size:13px;color:var(--blue);border:1px solid var(--border)">minions add &lt;path-to-your-repo&gt;</code>
56
+ <div style="font-size:11px;color:var(--muted)">Then try: <code style="background:var(--bg);padding:2px 6px;border-radius:3px;font-size:11px">minions work "Explore the codebase"</code> or use the Command Center above</div>
57
+ </div>
55
58
  </div>
56
59
 
57
60
  <!-- Layout replaced by page-layout sidebar navigation -->
package/engine/cli.js CHANGED
@@ -92,6 +92,10 @@ const commands = {
92
92
 
93
93
  const { getProjects } = require('./shared');
94
94
  const projects = getProjects(config);
95
+ if (projects.length === 0) {
96
+ console.log(' \x1b[33mNo projects configured.\x1b[0m Link one with: minions add <path-to-repo>');
97
+ console.log(' Agents can still work on tasks via the Command Center without a project.');
98
+ }
95
99
  for (const p of projects) {
96
100
  const root = p.localPath ? path.resolve(p.localPath) : null;
97
101
  if (!root || !fs.existsSync(root)) {
@@ -322,6 +326,7 @@ const commands = {
322
326
 
323
327
  // File-change-driven work discovery — trigger tick when work-items or PRDs change
324
328
  const _watchedFiles = new Set();
329
+ let _globalDebounce = null;
325
330
  function watchForWorkChanges() {
326
331
  const filesToWatch = [
327
332
  path.join(MINIONS_DIR, 'work-items.json'),
@@ -344,13 +349,12 @@ const commands = {
344
349
  if (_watchedFiles.has(filePath)) continue;
345
350
  _watchedFiles.add(filePath);
346
351
  try {
347
- let _debounce = null;
348
352
  fs.watchFile(filePath, { interval: 2000 }, () => {
349
- // Debouncemultiple rapid writes should only trigger one tick
350
- if (_debounce) return;
351
- _debounce = setTimeout(() => {
352
- _debounce = null;
353
- e.log('info', `File change detected: ${path.basename(filePath)} — triggering tick`);
353
+ // Global debounce coalesce rapid multi-file changes into one tick
354
+ if (_globalDebounce) clearTimeout(_globalDebounce);
355
+ _globalDebounce = setTimeout(() => {
356
+ _globalDebounce = null;
357
+ e.log('info', `File change detected — triggering tick`);
354
358
  e.tick();
355
359
  }, 1000);
356
360
  });
package/engine/meeting.js CHANGED
@@ -28,7 +28,14 @@ function getMeetings() {
28
28
 
29
29
  function getMeeting(id) {
30
30
  const filePath = path.join(MEETINGS_DIR, id + '.json');
31
- return safeJson(filePath);
31
+ const m = safeJson(filePath);
32
+ if (m) {
33
+ if (!m.findings) m.findings = {};
34
+ if (!m.debate) m.debate = {};
35
+ if (!m.humanNotes) m.humanNotes = [];
36
+ if (!m.participants) m.participants = [];
37
+ }
38
+ return m;
32
39
  }
33
40
 
34
41
  function saveMeeting(meeting) {
package/minions.js CHANGED
@@ -393,8 +393,15 @@ async function initMinions({ skipScan = false, scanRoot, scanDepth } = {}) {
393
393
  const config = loadConfig();
394
394
  if (!config.projects) config.projects = [];
395
395
  const removedPlaceholders = cleanupPlaceholderProjects(config);
396
- if (!config.engine) config.engine = { ...ENGINE_DEFAULTS };
397
- if (!config.claude) config.claude = { ...DEFAULT_CLAUDE };
396
+ // Merge defaults fills in new fields from upgrades while preserving user customizations
397
+ if (!config.engine) config.engine = {};
398
+ for (const [k, v] of Object.entries(ENGINE_DEFAULTS)) {
399
+ if (config.engine[k] === undefined) config.engine[k] = v;
400
+ }
401
+ if (!config.claude) config.claude = {};
402
+ for (const [k, v] of Object.entries(DEFAULT_CLAUDE)) {
403
+ if (config.claude[k] === undefined) config.claude[k] = v;
404
+ }
398
405
  if (!config.agents || Object.keys(config.agents).length === 0) {
399
406
  config.agents = { ...DEFAULT_AGENTS };
400
407
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.174",
3
+ "version": "0.1.176",
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"
@@ -1,5 +0,0 @@
1
- <section class="prd-panel" id="prd-section">
2
- <h2>PRD <span class="count" id="prd-progress-count">0%</span> <span id="prd-badge"></span> <span id="archive-btns"></span></h2>
3
- <div id="prd-content"><p class="prd-pending">No PRD found.</p></div>
4
- <div id="prd-progress-content" style="margin-top:12px"></div>
5
- </section>