@yemi33/minions 0.1.280 → 0.1.282

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,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.282 (2026-04-03)
4
+
5
+ ### Fixes
6
+ - thinking indicator shows immediately when user sends message
7
+
8
+ ## 0.1.281 (2026-04-03)
9
+
10
+ ### Other
11
+ - refactor: remove duplicate thinking indicator — single source via updateStreamDiv
12
+
3
13
  ## 0.1.280 (2026-04-03)
4
14
 
5
15
  ### Features
@@ -153,17 +153,6 @@ async function _ccDoSend(message, skipUserMsg) {
153
153
  var existingQueueEl = document.getElementById('cc-queue-indicator');
154
154
  if (existingQueueEl) existingQueueEl.remove();
155
155
 
156
- // Show thinking indicator with timer + queue count
157
- const queueCount = _ccQueue.length;
158
- const queueBadge = queueCount > 0 ? ' <span style="font-size:9px;background:var(--surface);padding:1px 5px;border-radius:8px;border:1px solid var(--border)">+' + queueCount + ' queued</span>' : '';
159
- const thinking = document.createElement('div');
160
- thinking.id = 'cc-thinking';
161
- thinking.style.cssText = 'padding:8px 12px;border-radius:8px;font-size:11px;color:var(--muted);align-self:flex-start;display:flex;align-items:center;gap:8px';
162
- thinking.innerHTML = '<span class="dot-pulse" style="display:inline-flex;gap:3px"><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> <span id="cc-thinking-text">Thinking...</span> <span id="cc-thinking-time" style="font-size:10px;color:var(--border)"></span>' + queueBadge;
163
- document.getElementById('cc-messages').appendChild(thinking);
164
- const ccMsgs = document.getElementById('cc-messages');
165
- ccMsgs.scrollTop = ccMsgs.scrollHeight;
166
-
167
156
  const ccStartTime = Date.now();
168
157
  const phases = [
169
158
  [0, 'Thinking...'],
@@ -175,45 +164,15 @@ async function _ccDoSend(message, skipUserMsg) {
175
164
  [180000, 'Still going (this is unusually long)...'],
176
165
  [300000, 'Timing out soon...'],
177
166
  ];
178
- const ccTimer = setInterval(() => {
179
- const elapsed = Date.now() - ccStartTime;
180
- const secs = Math.floor(elapsed / 1000);
181
- const timeEl = document.getElementById('cc-thinking-time');
182
- const textEl = document.getElementById('cc-thinking-text');
183
- if (timeEl) timeEl.textContent = secs + 's';
184
- if (textEl) {
185
- for (let i = phases.length - 1; i >= 0; i--) {
186
- if (elapsed >= phases[i][0]) { textEl.textContent = phases[i][1]; break; }
187
- }
188
- }
189
- }, 500);
190
-
191
- try {
192
- // Stream response via SSE — shows text as it arrives
193
- const res = await fetch('/api/command-center/stream', {
194
- method: 'POST', headers: { 'Content-Type': 'application/json' },
195
- body: JSON.stringify({ message }),
196
- signal: _ccAbortController ? _ccAbortController.signal : AbortSignal.timeout(960000)
197
- });
198
167
 
199
- if (!res.ok) {
200
- clearInterval(ccTimer);
201
- thinking.remove();
202
- const errText = await res.text();
203
- ccAddMessage('assistant', '<span style="color:var(--red)">' + escHtml(errText || 'CC error') + '</span>' +
204
- (errText.includes('busy') ? ' <button onclick="ccNewSession()" style="margin-top:4px;padding:3px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--blue);cursor:pointer;font-size:10px">Reset CC</button>' : ''));
205
- return;
206
- }
168
+ // Streaming state — declared before try so updateStreamDiv works during fetch
169
+ let streamedText = '';
170
+ let toolsUsed = [];
207
171
 
208
- // Use a temporary streaming div for live updates, then replace with ccAddMessage on completion
209
- clearInterval(ccTimer);
210
- try { thinking.remove(); } catch { /* may already be removed */ }
211
- // Add a temporary placeholder via ccAddMessage so it gets proper styling
212
- ccAddMessage('assistant', '<span style="color:var(--muted);font-size:11px">Thinking...</span>', true);
213
- const msgs = document.getElementById('cc-messages');
214
- const streamDiv = msgs.lastElementChild; // the message we just added
215
- let streamedText = '';
216
- let toolsUsed = [];
172
+ // Show thinking immediately before fetch starts
173
+ ccAddMessage('assistant', '<span style="color:var(--muted);font-size:11px">Thinking...</span>', true);
174
+ const msgs = document.getElementById('cc-messages');
175
+ const streamDiv = msgs.lastElementChild;
217
176
  const 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>';
218
177
  function _getThinkingPhase() {
219
178
  var elapsed = Date.now() - ccStartTime;
@@ -242,10 +201,25 @@ async function _ccDoSend(message, skipUserMsg) {
242
201
  if (_ccQueue.length > 0) _renderQueueIndicator();
243
202
  if (msgs.scrollHeight - msgs.scrollTop - msgs.clientHeight < 150) msgs.scrollTop = msgs.scrollHeight;
244
203
  }
245
-
246
- // Periodically update thinking phase text + timer
204
+ // Start phase timer immediately so thinking text updates while waiting for SSE
247
205
  const phaseTimer = setInterval(updateStreamDiv, 1000);
248
206
 
207
+ try {
208
+ // Stream response via SSE — shows text as it arrives
209
+ const res = await fetch('/api/command-center/stream', {
210
+ method: 'POST', headers: { 'Content-Type': 'application/json' },
211
+ body: JSON.stringify({ message }),
212
+ signal: _ccAbortController ? _ccAbortController.signal : AbortSignal.timeout(960000)
213
+ });
214
+
215
+ if (!res.ok) {
216
+ clearInterval(phaseTimer); streamDiv.remove();
217
+ const errText = await res.text();
218
+ ccAddMessage('assistant', '<span style="color:var(--red)">' + escHtml(errText || 'CC error') + '</span>' +
219
+ (errText.includes('busy') ? ' <button onclick="ccNewSession()" style="margin-top:4px;padding:3px 10px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--blue);cursor:pointer;font-size:10px">Reset CC</button>' : ''));
220
+ return;
221
+ }
222
+
249
223
  const reader = res.body.getReader();
250
224
  const decoder = new TextDecoder();
251
225
  let buf = '';
@@ -318,8 +292,6 @@ async function _ccDoSend(message, skipUserMsg) {
318
292
  }
319
293
  }
320
294
  } catch (e) {
321
- clearInterval(ccTimer);
322
- try { thinking.remove(); } catch { /* may already be removed */ }
323
295
  const retryId = 'cc-retry-' + Date.now();
324
296
  ccAddMessage('assistant', '<span style="color:var(--red)">Error: ' + escHtml(e.message) + '</span>' +
325
297
  '<button id="' + retryId + '" onclick="ccRetryLast()" style="margin-top:6px;padding:4px 12px;background:var(--surface2);border:1px solid var(--border);border-radius:4px;color:var(--blue);cursor:pointer;font-size:11px">Retry</button>');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.280",
3
+ "version": "0.1.282",
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"