@yemi33/minions 0.1.923 → 0.1.925

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,6 +1,6 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.923 (2026-04-13)
3
+ ## 0.1.925 (2026-04-13)
4
4
 
5
5
  ### Features
6
6
  - add /api/work-items/reopen endpoint and reopen-work-item CC action (#982)
@@ -19,6 +19,8 @@
19
19
  - add red dot notification on CC tab when response completes (#934) (#946)
20
20
 
21
21
  ### Fixes
22
+ - doc-chat Stop button actually works — release server guard on disconnect
23
+ - CC streaming auto-retries fresh session when resume fails
22
24
  - 429 retry on abort race applies to all sends, not just queued
23
25
  - show actionable failure context instead of Unknown error (#1003)
24
26
  - prioritize error_max_turns over permission-blocked in classifyFailure (#1001)
@@ -340,6 +340,9 @@ function qaAbort() {
340
340
  _qaAbortController.abort();
341
341
  _qaAbortController = null;
342
342
  }
343
+ // Force-reset processing state so UI isn't stuck if abort races with response
344
+ _qaProcessing = false;
345
+ _qaQueue = [];
343
346
  }
344
347
 
345
348
  function toggleDocChat() {
package/dashboard.js CHANGED
@@ -2935,6 +2935,9 @@ What would you like to discuss or change? When you're happy, say "approve" and I
2935
2935
  return jsonReply(res, 429, { error: 'This document is already being processed — wait for the current response.' });
2936
2936
  }
2937
2937
  docChatInFlight.add(docKey);
2938
+ // Release guard if client disconnects (abort/navigation) so next request isn't blocked
2939
+ let _clientDisconnected = false;
2940
+ req.on('close', () => { _clientDisconnected = true; docChatInFlight.delete(docKey); });
2938
2941
 
2939
2942
  try {
2940
2943
  const canEdit = !!body.filePath;
@@ -3493,17 +3496,38 @@ What would you like to discuss or change? When you're happy, say "approve" and I
3493
3496
  trackUsage('command-center', result.usage);
3494
3497
 
3495
3498
  // Handle failure — non-zero exit with text = max_turns or partial success, still usable
3499
+ if (!result.text && wasResume && result.code !== 0) {
3500
+ // Resume failed (stale/expired session) — auto-retry as fresh session
3501
+ console.log(`[CC-stream] Resume failed (code=${result.code}) — retrying fresh`);
3502
+ const freshPreamble = buildCCStatePreamble();
3503
+ const freshPrompt = (freshPreamble ? freshPreamble + '\n\n---\n\n' : '') + body.message;
3504
+ const retryPromise = callLLMStreaming(freshPrompt, CC_STATIC_SYSTEM_PROMPT, {
3505
+ timeout: 900000, label: 'command-center', model: streamModel, maxTurns: ccMaxTurns,
3506
+ allowedTools: 'Bash,Read,Write,Edit,Glob,Grep,WebFetch,WebSearch',
3507
+ effort: streamEffort, direct: true,
3508
+ onChunk: (text) => {
3509
+ const actIdx = text.indexOf('===ACTIONS===');
3510
+ const display = actIdx >= 0 ? text.slice(0, actIdx).trim() : text;
3511
+ try { res.write('data: ' + JSON.stringify({ type: 'chunk', text: display }) + '\n\n'); } catch {}
3512
+ },
3513
+ onToolUse: (name, input) => {
3514
+ try { res.write('data: ' + JSON.stringify({ type: 'tool', name, input: typeof input === 'string' ? input.slice(0, 200) : JSON.stringify(input).slice(0, 200) }) + '\n\n'); } catch {}
3515
+ }
3516
+ });
3517
+ _ccStreamAbort = retryPromise.abort;
3518
+ const retryResult = await retryPromise;
3519
+ trackUsage('command-center', retryResult.usage);
3520
+ if (retryResult.text) {
3521
+ // Fresh session succeeded — use retryResult from here
3522
+ Object.assign(result, retryResult);
3523
+ }
3524
+ }
3496
3525
  if (!result.text) {
3497
3526
  const debugInfo = result.code !== 0 ? `(exit code ${result.code})` : '(empty response)';
3498
3527
  const stderrTail = (result.stderr || '').trim().split('\n').filter(Boolean).slice(-3).join(' | ');
3499
3528
  console.error(`[CC-stream] Failed: code=${result.code}, stderr=${(result.stderr || '').slice(0, 500)}, stdout_tail=${(result.raw || '').slice(-500)}`);
3500
- // If resuming a session failed, auto-reset so next attempt starts fresh
3501
- const retryHint = wasResume && result.code !== 0
3502
- ? 'Session was reset — send your message again to start fresh.'
3503
- : 'Send your message again to retry.';
3504
- // Return null sessionId on resume failure so client clears the stale session
3505
- const errorSessionId = (wasResume && result.code !== 0) ? null : tabSessionId;
3506
- 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');
3529
+ const retryHint = 'Send your message again to retry.';
3530
+ res.write('data: ' + JSON.stringify({ type: 'done', text: `I had trouble processing that ${debugInfo}. ${stderrTail ? 'Detail: ' + stderrTail : ''}\n\n${retryHint}`, actions: [], sessionId: null }) + '\n\n');
3507
3531
  _ccStreamEnded = true; res.end();
3508
3532
  return;
3509
3533
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.923",
3
+ "version": "0.1.925",
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"