@yemi33/minions 0.1.755 → 0.1.757

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,13 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.755 (2026-04-09)
3
+ ## 0.1.757 (2026-04-09)
4
4
 
5
5
  ### Features
6
6
  - show branch strategy badge on PRD group header
7
7
 
8
8
  ### Fixes
9
+ - restored thinking UX matches original exactly (same bubble, layout)
10
+ - skip merged dependency branches instead of failing worktree setup
9
11
  - restore same thinking UX when switching back to processing tab
10
12
  - show thinking indicator when switching back to a processing tab
11
13
  - CC messages go to originating tab, not whichever tab is visible
@@ -135,30 +135,28 @@ function ccSwitchTab(id) {
135
135
  for (var i = 0; i < tab.messages.length; i++) {
136
136
  ccAddMessage(tab.messages[i].role, tab.messages[i].html, true);
137
137
  }
138
- // If this tab is still processing, show the same thinking UX as during send
138
+ // If this tab is still processing, restore the same thinking UX via addMessage (identical to original)
139
139
  if (tab._sending) {
140
140
  var dotPulse = '<span style="display:inline-flex;gap:3px;margin-left:6px;vertical-align:middle"><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite"></span><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite;animation-delay:0.2s"></span><span style="width:4px;height:4px;background:var(--blue);border-radius:50%;animation:dotPulse 1.2s infinite;animation-delay:0.4s"></span></span>';
141
- var elapsed = tab._sendStartedAt ? Math.floor((Date.now() - tab._sendStartedAt) / 1000) : 0;
141
+ var restoreStart = tab._sendStartedAt || Date.now();
142
142
  var phases = [[0,'Thinking...'],[3000,'Reading minions context...'],[8000,'Analyzing...'],[15000,'Using tools to dig deeper...'],[30000,'Still working (multi-turn)...'],[60000,'Deep research in progress...']];
143
- var elapsedMs = elapsed * 1000;
144
- var phaseText = 'Thinking...';
145
- for (var pi = phases.length - 1; pi >= 0; pi--) { if (elapsedMs >= phases[pi][0]) { phaseText = phases[pi][1]; break; } }
146
- var thinking = document.createElement('div');
147
- thinking.id = 'cc-restore-thinking';
148
- thinking.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:11px;color:var(--muted);align-self:flex-start;background:var(--surface2);border:1px solid var(--border);position:relative;max-width:95%';
149
- thinking.innerHTML = '<div>' + dotPulse + ' <span id="cc-restore-phase">' + phaseText + '</span> <span id="cc-restore-time" style="font-size:10px;color:var(--border)">' + elapsed + 's</span>' +
150
- ' <button onclick="ccAbort()" style="font-size:9px;padding:2px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--red);cursor:pointer;margin-left:6px">Stop</button></div>';
151
- el.appendChild(thinking);
143
+ function _restoreThinkingHtml() {
144
+ var ms = Date.now() - restoreStart;
145
+ var label = 'Thinking...';
146
+ for (var pi = phases.length - 1; pi >= 0; pi--) { if (ms >= phases[pi][0]) { label = phases[pi][1]; break; } }
147
+ var secs = Math.floor(ms / 1000);
148
+ return '<div style="display:flex;align-items:center;gap:6px"><span style="color:var(--muted);font-size:11px">' + label + '</span>' + dotPulse + '<span style="margin-left:auto;font-size:10px;color:var(--muted)">' + secs + 's</span>' +
149
+ '<button onclick="ccAbort()" style="font-size:9px;padding:2px 8px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--red);cursor:pointer;margin-left:4px">Stop</button></div>';
150
+ }
151
+ // Create as assistant message bubble (same as original)
152
+ ccAddMessage('assistant', _restoreThinkingHtml(), true);
153
+ var restoreDiv = el.lastElementChild;
154
+ restoreDiv.id = 'cc-restore-thinking';
152
155
  el.scrollTop = el.scrollHeight;
153
- // Live update timer and phase
154
- var restoreStart = tab._sendStartedAt || Date.now();
155
156
  var restoreInterval = setInterval(function() {
156
- var phaseEl = document.getElementById('cc-restore-phase');
157
- var timeEl = document.getElementById('cc-restore-time');
158
- if (!phaseEl || !timeEl || !tab._sending) { clearInterval(restoreInterval); var re = document.getElementById('cc-restore-thinking'); if (re) re.remove(); return; }
159
- var ms = Date.now() - restoreStart;
160
- timeEl.textContent = Math.floor(ms / 1000) + 's';
161
- for (var p = phases.length - 1; p >= 0; p--) { if (ms >= phases[p][0]) { phaseEl.textContent = phases[p][1]; break; } }
157
+ var re = document.getElementById('cc-restore-thinking');
158
+ if (!re || !tab._sending) { clearInterval(restoreInterval); if (re) re.remove(); return; }
159
+ re.innerHTML = (typeof llmCopyBtn === 'function' ? '' : '') + _restoreThinkingHtml();
162
160
  }, 1000);
163
161
  }
164
162
  ccRenderTabBar();
package/engine.js CHANGED
@@ -454,7 +454,13 @@ async function spawnAgent(dispatchItem, config) {
454
454
  // Fetch all dependency branches in parallel (git fetches are independent)
455
455
  const fetchable = depBranches.filter(d => !_failedRefCache.has(d.branch));
456
456
  const unfetchable = depBranches.filter(d => _failedRefCache.has(d.branch));
457
- for (const { branch: depBranch } of unfetchable) {
457
+ const allPrsForDeps = unfetchable.length > 0 ? shared.getProjects(config).reduce((acc, p) => acc.concat(safeJson(shared.projectPrPath(p)) || []), []) : [];
458
+ for (const { branch: depBranch, prId } of unfetchable) {
459
+ const pr = allPrsForDeps.find(p => p.id === prId);
460
+ if (pr && (pr.status === 'merged' || pr.status === 'closed')) {
461
+ log('info', `Dependency ${depBranch} (${prId}) already merged — skipping, changes already in main`);
462
+ continue;
463
+ }
458
464
  log('warn', `Skipping dependency ${depBranch} — already failed to fetch this tick`);
459
465
  depMergeFailed = true;
460
466
  }
@@ -463,17 +469,26 @@ async function spawnAgent(dispatchItem, config) {
463
469
  execAsync(`git fetch origin "${depBranch}"`, { ..._gitOpts, cwd: rootDir }).then(() => depBranch)
464
470
  )
465
471
  );
472
+ const hasFetchFailures = fetchResults.some(r => r.status === 'rejected');
473
+ const allPrsForFetch = hasFetchFailures ? shared.getProjects(config).reduce((acc, p) => acc.concat(safeJson(shared.projectPrPath(p)) || []), []) : [];
466
474
  for (let i = 0; i < fetchResults.length; i++) {
467
475
  if (fetchResults[i].status === 'rejected') {
468
476
  const failedBranch = fetchable[i].branch;
477
+ const failedPrId = fetchable[i].prId;
478
+ const pr = allPrsForFetch.find(p => p.id === failedPrId);
479
+ if (pr && (pr.status === 'merged' || pr.status === 'closed')) {
480
+ log('info', `Dependency ${failedBranch} (${failedPrId}) already merged — skipping, changes already in main`);
481
+ continue;
482
+ }
469
483
  _failedRefCache.add(failedBranch);
470
484
  log('warn', `Failed to fetch dependency ${failedBranch}: ${fetchResults[i].reason?.message}`);
471
485
  depMergeFailed = true;
472
486
  }
473
487
  }
474
- // Merge fetched branches sequentially (merges modify the worktree)
488
+ // Merge successfully-fetched branches sequentially (merges modify the worktree)
489
+ const fetched = fetchable.filter((_, i) => fetchResults[i].status === 'fulfilled');
475
490
  if (!depMergeFailed) {
476
- for (const { branch: depBranch, prId } of fetchable) {
491
+ for (const { branch: depBranch, prId } of fetched) {
477
492
  try {
478
493
  await execAsync(`git merge "origin/${depBranch}" --no-edit`, { ..._gitOpts, cwd: worktreePath });
479
494
  log('info', `Merged dependency branch ${depBranch} (${prId}) into worktree ${branchName}`);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.755",
3
+ "version": "0.1.757",
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"