@yemi33/minions 0.1.758 → 0.1.759

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,12 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.758 (2026-04-09)
3
+ ## 0.1.759 (2026-04-09)
4
4
 
5
5
  ### Features
6
6
  - show branch strategy badge on PRD group header
7
7
 
8
8
  ### Fixes
9
+ - eliminate global ccSession corruption, clean up streaming state
9
10
  - restore full streaming state (tools + partial text) on tab switch
10
11
  - restored thinking UX matches original exactly (same bubble, layout)
11
12
  - skip merged dependency branches instead of failing worktree setup
@@ -625,7 +625,7 @@ async function _ccDoSend(message, skipUserMsg) {
625
625
  ' <button onclick="ccNewTab()" style="margin-top:6px;padding:4px 12px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--muted);cursor:pointer;font-size:11px">New Session</button>');
626
626
  }
627
627
  } finally {
628
- if (activeTab) { activeTab._sending = false; activeTab._abortController = null; }
628
+ if (activeTab) { activeTab._sending = false; activeTab._abortController = null; delete activeTab._streamedText; delete activeTab._toolsUsed; delete activeTab._sendStartedAt; }
629
629
  _ccSending = (_ccTabs.some(function(t) { return t._sending; }));
630
630
  try { clearInterval(phaseTimer); } catch { /* may not be defined if error before reader */ }
631
631
  try { localStorage.removeItem('cc-sending'); } catch {}
package/dashboard.js CHANGED
@@ -3329,16 +3329,10 @@ What would you like to discuss or change? When you're happy, say "approve" and I
3329
3329
  req.on('close', () => { ccInFlightTabs.delete(tabId); if (_ccStreamAbort) _ccStreamAbort(); });
3330
3330
 
3331
3331
  try {
3332
- // Session management — per-tab: use sessionId from request if provided
3332
+ // Session management — per-tab: use sessionId from request, don't mutate global ccSession
3333
3333
  const tabSessionId = body.sessionId || null;
3334
- if (tabSessionId) {
3335
- // Resume the tab's specific session
3336
- ccSession = { sessionId: tabSessionId, createdAt: ccSession.createdAt, lastActiveAt: Date.now(), turnCount: ccSession.turnCount || 0, _promptHash: _ccPromptHash };
3337
- } else if (!ccSessionValid()) {
3338
- ccSession = { sessionId: null, createdAt: null, lastActiveAt: null, turnCount: 0 };
3339
- }
3340
- const wasResume = !!tabSessionId || !!(ccSessionValid() && ccSession.sessionId);
3341
- const sessionId = tabSessionId || (wasResume ? ccSession.sessionId : null);
3334
+ const wasResume = !!tabSessionId;
3335
+ const sessionId = tabSessionId || null;
3342
3336
  const preamble = wasResume ? '' : buildCCStatePreamble();
3343
3337
  const prompt = (preamble ? preamble + '\n\n---\n\n' : '') + body.message;
3344
3338
 
@@ -3367,42 +3361,33 @@ What would you like to discuss or change? When you're happy, say "approve" and I
3367
3361
  const stderrTail = (result.stderr || '').trim().split('\n').filter(Boolean).slice(-3).join(' | ');
3368
3362
  console.error(`[CC-stream] Failed: code=${result.code}, stderr=${(result.stderr || '').slice(0, 500)}, stdout_tail=${(result.raw || '').slice(-500)}`);
3369
3363
  // If resuming a session failed, auto-reset so next attempt starts fresh
3370
- let retryHint;
3371
- if (wasResume && result.code !== 0) {
3372
- ccSession = { sessionId: null, createdAt: null, lastActiveAt: null, turnCount: 0 };
3373
- safeWrite(path.join(ENGINE_DIR, 'cc-session.json'), ccSession);
3374
- retryHint = 'Session was reset send your message again to start fresh.';
3375
- } else {
3376
- retryHint = ccSession.sessionId
3377
- ? 'Your session is still active — just send your message again to retry.'
3378
- : 'Try clicking **New Session** and sending your message again.';
3379
- }
3380
- res.write('data: ' + JSON.stringify({ type: 'done', text: `I had trouble processing that ${debugInfo}. ${stderrTail ? 'Detail: ' + stderrTail : ''}\n\n${retryHint}`, actions: [], sessionId: ccSession.sessionId }) + '\n\n');
3364
+ const retryHint = wasResume && result.code !== 0
3365
+ ? 'Session was reset send your message again to start fresh.'
3366
+ : 'Send your message again to retry.';
3367
+ // Return null sessionId on resume failure so client clears the stale session
3368
+ const errorSessionId = (wasResume && result.code !== 0) ? null : tabSessionId;
3369
+ res.write('data: ' + JSON.stringify({ type: 'done', text: `I had trouble processing that ${debugInfo}. ${stderrTail ? 'Detail: ' + stderrTail : ''}\n\n${retryHint}`, actions: [], sessionId: errorSessionId }) + '\n\n');
3381
3370
  res.end();
3382
3371
  return;
3383
3372
  }
3384
3373
 
3385
3374
  // Update session
3375
+ // Persist tab→session mapping (no global ccSession mutation)
3386
3376
  const now = Date.now();
3387
- if (result.sessionId) {
3388
- ccSession = { sessionId: result.sessionId, createdAt: ccSession.createdAt || now, lastActiveAt: now, turnCount: (ccSession.turnCount || 0) + 1, _promptHash: _ccPromptHash };
3389
- safeWrite(path.join(ENGINE_DIR, 'cc-session.json'), ccSession);
3390
- }
3391
-
3392
- // Persist tab→session mapping if tabId provided
3377
+ const responseSessionId = result.sessionId || tabSessionId;
3393
3378
  const tabId = body.tabId;
3394
- if (tabId && ccSession.sessionId) {
3379
+ if (tabId && responseSessionId) {
3395
3380
  try {
3396
3381
  const sessions = shared.safeJsonArr(CC_SESSIONS_PATH);
3397
3382
  const existing = sessions.find(s => s.id === tabId);
3398
3383
  const preview = (body.message || '').slice(0, 80);
3399
3384
  if (existing) {
3400
- existing.sessionId = ccSession.sessionId;
3385
+ existing.sessionId = responseSessionId;
3401
3386
  existing.lastActiveAt = new Date(now).toISOString();
3402
- existing.turnCount = ccSession.turnCount;
3387
+ existing.turnCount = (existing.turnCount || 0) + 1;
3403
3388
  existing.preview = preview;
3404
3389
  } else {
3405
- sessions.push({ id: tabId, title: (body.message || 'New chat').slice(0, 40), sessionId: ccSession.sessionId, createdAt: new Date(now).toISOString(), lastActiveAt: new Date(now).toISOString(), turnCount: ccSession.turnCount, preview });
3390
+ sessions.push({ id: tabId, title: (body.message || 'New chat').slice(0, 40), sessionId: responseSessionId, createdAt: new Date(now).toISOString(), lastActiveAt: new Date(now).toISOString(), turnCount: 1, preview });
3406
3391
  }
3407
3392
  safeWrite(CC_SESSIONS_PATH, sessions);
3408
3393
  } catch { /* non-critical */ }
@@ -3410,7 +3395,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
3410
3395
 
3411
3396
  // Send final result with actions
3412
3397
  const { text: displayText, actions } = parseCCActions(result.text);
3413
- res.write('data: ' + JSON.stringify({ type: 'done', text: displayText, actions, sessionId: ccSession.sessionId, newSession: !wasResume }) + '\n\n');
3398
+ res.write('data: ' + JSON.stringify({ type: 'done', text: displayText, actions, sessionId: responseSessionId, newSession: !wasResume }) + '\n\n');
3414
3399
  res.end();
3415
3400
  } finally {
3416
3401
  ccInFlightTabs.delete(tabId);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.758",
3
+ "version": "0.1.759",
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"