@yemi33/minions 0.1.279 → 0.1.281
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 +9 -1
- package/dashboard/js/command-center.js +18 -34
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.281 (2026-04-03)
|
|
4
|
+
|
|
5
|
+
### Other
|
|
6
|
+
- refactor: remove duplicate thinking indicator — single source via updateStreamDiv
|
|
7
|
+
|
|
8
|
+
## 0.1.280 (2026-04-03)
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
- thinking indicator shows progressive phases with elapsed timer
|
|
4
12
|
|
|
5
13
|
### Fixes
|
|
6
14
|
- doc chat elapsed time no longer overlaps copy button
|
|
@@ -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,18 +164,6 @@ 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
167
|
|
|
191
168
|
try {
|
|
192
169
|
// Stream response via SSE — shows text as it arrives
|
|
@@ -197,8 +174,6 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
197
174
|
});
|
|
198
175
|
|
|
199
176
|
if (!res.ok) {
|
|
200
|
-
clearInterval(ccTimer);
|
|
201
|
-
thinking.remove();
|
|
202
177
|
const errText = await res.text();
|
|
203
178
|
ccAddMessage('assistant', '<span style="color:var(--red)">' + escHtml(errText || 'CC error') + '</span>' +
|
|
204
179
|
(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>' : ''));
|
|
@@ -206,8 +181,6 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
206
181
|
}
|
|
207
182
|
|
|
208
183
|
// 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
184
|
// Add a temporary placeholder via ccAddMessage so it gets proper styling
|
|
212
185
|
ccAddMessage('assistant', '<span style="color:var(--muted);font-size:11px">Thinking...</span>', true);
|
|
213
186
|
const msgs = document.getElementById('cc-messages');
|
|
@@ -215,6 +188,15 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
215
188
|
let streamedText = '';
|
|
216
189
|
let toolsUsed = [];
|
|
217
190
|
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>';
|
|
191
|
+
function _getThinkingPhase() {
|
|
192
|
+
var elapsed = Date.now() - ccStartTime;
|
|
193
|
+
var label = 'Thinking...';
|
|
194
|
+
for (var pi = phases.length - 1; pi >= 0; pi--) {
|
|
195
|
+
if (elapsed >= phases[pi][0]) { label = phases[pi][1]; break; }
|
|
196
|
+
}
|
|
197
|
+
var secs = Math.floor(elapsed / 1000);
|
|
198
|
+
return label + ' <span style="font-size:9px;color:var(--border)">' + secs + 's</span>';
|
|
199
|
+
}
|
|
218
200
|
function updateStreamDiv() {
|
|
219
201
|
var html = '';
|
|
220
202
|
if (toolsUsed.length > 0) {
|
|
@@ -227,13 +209,16 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
227
209
|
if (streamedText) {
|
|
228
210
|
html += renderMd(streamedText);
|
|
229
211
|
}
|
|
230
|
-
html += '<div style="margin-top:' + (streamedText ? '6px' : '0') + '"><span style="color:var(--muted);font-size:11px">
|
|
212
|
+
html += '<div style="margin-top:' + (streamedText ? '6px' : '0') + '"><span style="color:var(--muted);font-size:11px">' + _getThinkingPhase() + dotPulse + '</span></div>';
|
|
231
213
|
streamDiv.innerHTML = html;
|
|
232
214
|
// Re-append queue indicators so they stay below the streaming content
|
|
233
215
|
if (_ccQueue.length > 0) _renderQueueIndicator();
|
|
234
216
|
if (msgs.scrollHeight - msgs.scrollTop - msgs.clientHeight < 150) msgs.scrollTop = msgs.scrollHeight;
|
|
235
217
|
}
|
|
236
218
|
|
|
219
|
+
// Periodically update thinking phase text + timer
|
|
220
|
+
const phaseTimer = setInterval(updateStreamDiv, 1000);
|
|
221
|
+
|
|
237
222
|
const reader = res.body.getReader();
|
|
238
223
|
const decoder = new TextDecoder();
|
|
239
224
|
let buf = '';
|
|
@@ -257,7 +242,7 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
257
242
|
if (msgs.scrollHeight - msgs.scrollTop - msgs.clientHeight < 150) msgs.scrollTop = msgs.scrollHeight;
|
|
258
243
|
} else if (evt.type === 'done') {
|
|
259
244
|
// Replace streaming div with a proper ccAddMessage
|
|
260
|
-
streamDiv.remove();
|
|
245
|
+
clearInterval(phaseTimer); streamDiv.remove();
|
|
261
246
|
// placeholder was added with skipSave=true — nothing to pop
|
|
262
247
|
const ccElapsed = Math.round((Date.now() - ccStartTime) / 1000);
|
|
263
248
|
const rendered = renderMd(evt.text || streamedText || '');
|
|
@@ -267,7 +252,7 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
267
252
|
for (const action of evt.actions) { await ccExecuteAction(action); }
|
|
268
253
|
}
|
|
269
254
|
} else if (evt.type === 'error') {
|
|
270
|
-
streamDiv.remove();
|
|
255
|
+
clearInterval(phaseTimer); streamDiv.remove();
|
|
271
256
|
// placeholder was skipSave — no pop needed
|
|
272
257
|
ccAddMessage('assistant', '<span style="color:var(--red)">' + escHtml(evt.error) + '</span>');
|
|
273
258
|
}
|
|
@@ -281,7 +266,7 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
281
266
|
try {
|
|
282
267
|
const evt = JSON.parse(line.slice(6));
|
|
283
268
|
if (evt.type === 'done') {
|
|
284
|
-
streamDiv.remove();
|
|
269
|
+
clearInterval(phaseTimer); streamDiv.remove();
|
|
285
270
|
// placeholder was skipSave — no pop needed
|
|
286
271
|
const ccElapsed = Math.round((Date.now() - ccStartTime) / 1000);
|
|
287
272
|
const rendered = renderMd(evt.text || streamedText || '');
|
|
@@ -299,21 +284,20 @@ async function _ccDoSend(message, skipUserMsg) {
|
|
|
299
284
|
}
|
|
300
285
|
// If stream ended without a 'done' event, finalize with whatever we have
|
|
301
286
|
if (streamDiv.parentNode) {
|
|
302
|
-
streamDiv.remove();
|
|
287
|
+
clearInterval(phaseTimer); streamDiv.remove();
|
|
303
288
|
if (streamedText) {
|
|
304
289
|
const ccElapsed = Math.round((Date.now() - ccStartTime) / 1000);
|
|
305
290
|
ccAddMessage('assistant', renderMd(streamedText) + '<div style="font-size:9px;color:var(--muted);margin-top:6px;display:flex;justify-content:flex-end;padding-right:30px">' + ccElapsed + 's</div>');
|
|
306
291
|
}
|
|
307
292
|
}
|
|
308
293
|
} catch (e) {
|
|
309
|
-
clearInterval(ccTimer);
|
|
310
|
-
try { thinking.remove(); } catch { /* may already be removed */ }
|
|
311
294
|
const retryId = 'cc-retry-' + Date.now();
|
|
312
295
|
ccAddMessage('assistant', '<span style="color:var(--red)">Error: ' + escHtml(e.message) + '</span>' +
|
|
313
296
|
'<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>');
|
|
314
297
|
} finally {
|
|
315
298
|
_ccSending = false;
|
|
316
299
|
_ccAbortController = null;
|
|
300
|
+
try { clearInterval(phaseTimer); } catch { /* may not be defined if error before reader */ }
|
|
317
301
|
try { localStorage.removeItem('cc-sending'); } catch {}
|
|
318
302
|
// Show notification badge on CC button if drawer is closed
|
|
319
303
|
if (!_ccOpen) showNotifBadge(document.getElementById('cc-toggle-btn'));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.281",
|
|
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"
|