@yemi33/minions 0.1.961 → 0.1.963
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 +3 -3
- package/dashboard.js +17 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.963 (2026-04-14)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
6
|
- add quality standard reminder to all agent and CC prompts
|
|
@@ -25,6 +25,8 @@
|
|
|
25
25
|
- fix dashboard plan-pause nested lock violation (#968)
|
|
26
26
|
|
|
27
27
|
### Fixes
|
|
28
|
+
- CC streaming 'tabId' TDZ error on new tab first message
|
|
29
|
+
- fix tabId scope and close-event lock race in CC handlers
|
|
28
30
|
- fix CC queued message 'already processing' and thinking UX stacking
|
|
29
31
|
- enforce --timeout 1 on all azureauth calls to prevent agent orphans (#1063)
|
|
30
32
|
- cancel steering kill watcher on resume spawn (#1052) (#1062)
|
|
@@ -43,8 +45,6 @@
|
|
|
43
45
|
- await discoverPipelineWork instead of fire-and-forget .catch (#1020)
|
|
44
46
|
- add unhandledRejection/uncaughtException handlers to engine process (#1019)
|
|
45
47
|
- show doc-chat badges on Notes and KB items (#1016)
|
|
46
|
-
- steering kill on no-session re-queues dispatch instead of erroring (#1015)
|
|
47
|
-
- inject cached ADO token into spawned agents (#998) (#1012)
|
|
48
48
|
|
|
49
49
|
### Other
|
|
50
50
|
- refactor(dashboard): extract _releaseCCTab helper and CC_LOCK_WAIT_MS constant
|
package/dashboard.js
CHANGED
|
@@ -3396,12 +3396,13 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3396
3396
|
|
|
3397
3397
|
async function handleCommandCenter(req, res) {
|
|
3398
3398
|
if (checkRateLimit('command-center', 10)) return jsonReply(res, 429, { error: 'Rate limited — max 10 requests/minute' });
|
|
3399
|
+
let tabId;
|
|
3399
3400
|
try {
|
|
3400
3401
|
const body = await readBody(req);
|
|
3401
3402
|
if (!body.message) return jsonReply(res, 400, { error: 'message required' });
|
|
3402
3403
|
|
|
3403
3404
|
// Per-tab concurrency guard
|
|
3404
|
-
|
|
3405
|
+
tabId = body.tabId || 'default';
|
|
3405
3406
|
if (ccInFlightTabs.has(tabId)) {
|
|
3406
3407
|
await new Promise(r => setTimeout(r, CC_LOCK_WAIT_MS));
|
|
3407
3408
|
if (ccInFlightTabs.has(tabId)) {
|
|
@@ -3472,10 +3473,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3472
3473
|
|
|
3473
3474
|
async function handleCommandCenterStream(req, res) {
|
|
3474
3475
|
if (checkRateLimit('command-center', 10)) { res.statusCode = 429; res.end('Rate limited'); return; }
|
|
3476
|
+
let tabId;
|
|
3475
3477
|
try {
|
|
3476
3478
|
const body = await readBody(req);
|
|
3477
3479
|
if (!body.message) { res.statusCode = 400; res.end('message required'); return; }
|
|
3478
|
-
|
|
3480
|
+
tabId = body.tabId || 'default';
|
|
3479
3481
|
if (ccInFlightTabs.has(tabId)) {
|
|
3480
3482
|
// Previous request still in-flight — abort its LLM (handles keep-alive abort where close event didn't fire)
|
|
3481
3483
|
const prevAbort = ccInFlightAborts.get(tabId);
|
|
@@ -3490,12 +3492,16 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3490
3492
|
res.writeHead(200, { 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', 'Connection': 'keep-alive' });
|
|
3491
3493
|
let _ccStreamAbort = null;
|
|
3492
3494
|
let _ccStreamEnded = false;
|
|
3493
|
-
// Kill LLM process immediately if client disconnects mid-stream
|
|
3495
|
+
// Kill LLM process immediately if client disconnects mid-stream.
|
|
3496
|
+
// Guard with !_ccStreamEnded: when the stream ends normally, finally already released the lock;
|
|
3497
|
+
// without the guard, this close event (which fires after res.end) could wipe a new request's lock.
|
|
3494
3498
|
req.on('close', () => {
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
+
if (!_ccStreamEnded) {
|
|
3500
|
+
_releaseCCTab(tabId);
|
|
3501
|
+
if (_ccStreamAbort) {
|
|
3502
|
+
console.log(`[CC-stream] Client disconnected for tab ${tabId} — aborting LLM`);
|
|
3503
|
+
_ccStreamAbort();
|
|
3504
|
+
}
|
|
3499
3505
|
}
|
|
3500
3506
|
});
|
|
3501
3507
|
|
|
@@ -3580,11 +3586,11 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3580
3586
|
// Persist tab→session mapping (no global ccSession mutation)
|
|
3581
3587
|
const now = Date.now();
|
|
3582
3588
|
const responseSessionId = result.sessionId || tabSessionId;
|
|
3583
|
-
const
|
|
3584
|
-
if (
|
|
3589
|
+
const _persistTabId = body.tabId;
|
|
3590
|
+
if (_persistTabId && responseSessionId) {
|
|
3585
3591
|
try {
|
|
3586
3592
|
const sessions = shared.safeJsonArr(CC_SESSIONS_PATH);
|
|
3587
|
-
const existing = sessions.find(s => s.id ===
|
|
3593
|
+
const existing = sessions.find(s => s.id === _persistTabId);
|
|
3588
3594
|
const preview = (body.message || '').slice(0, 80);
|
|
3589
3595
|
if (existing) {
|
|
3590
3596
|
existing.sessionId = responseSessionId;
|
|
@@ -3593,7 +3599,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
3593
3599
|
existing.preview = preview;
|
|
3594
3600
|
existing._promptHash = _ccPromptHash;
|
|
3595
3601
|
} else {
|
|
3596
|
-
sessions.push({ id:
|
|
3602
|
+
sessions.push({ id: _persistTabId, title: (body.message || 'New chat').slice(0, 40), sessionId: responseSessionId, createdAt: new Date(now).toISOString(), lastActiveAt: new Date(now).toISOString(), turnCount: 1, preview, _promptHash: _ccPromptHash });
|
|
3597
3603
|
}
|
|
3598
3604
|
safeWrite(CC_SESSIONS_PATH, sessions);
|
|
3599
3605
|
} catch { /* non-critical */ }
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.963",
|
|
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"
|