@yemi33/minions 0.1.1005 → 0.1.1006
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 +2 -2
- package/engine/cleanup.js +17 -3
- package/engine/cooldown.js +12 -2
- package/engine/shared.js +1 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.1006 (2026-04-16)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
|
+
- cap pendingContexts in cooldowns.json to prevent bloat (#1126)
|
|
6
7
|
- fix stopAfter=0 watch expiry — run forever for all conditions (#1117)
|
|
7
8
|
- fix doc-chat Clear chat not persisting session deletion to localStorage (#1102)
|
|
8
9
|
- remove DEFAULTS alias from timeout.js (#1101)
|
|
@@ -22,7 +23,6 @@
|
|
|
22
23
|
- reassign tasks when preferred agent is busy too long
|
|
23
24
|
- wire agentBusyReassignMs into settings UI and persist
|
|
24
25
|
- ADO throttle detection, poll guards, and dashboard banner (#1051)
|
|
25
|
-
- gate auto-fix conflict dispatch behind autoFixConflicts flag
|
|
26
26
|
|
|
27
27
|
### Fixes
|
|
28
28
|
- harden repo-scoped PR identity handling
|
package/engine/cleanup.js
CHANGED
|
@@ -8,7 +8,7 @@ const path = require('path');
|
|
|
8
8
|
const shared = require('./shared');
|
|
9
9
|
const queries = require('./queries');
|
|
10
10
|
|
|
11
|
-
const { exec, execSilent, log, ts } = shared;
|
|
11
|
+
const { exec, execSilent, log, ts, ENGINE_DEFAULTS } = shared;
|
|
12
12
|
const { safeJson, safeWrite, safeReadDir, mutateWorkItems, getProjects, projectWorkItemsPath, projectPrPath,
|
|
13
13
|
sanitizeBranch, KB_CATEGORIES } = shared;
|
|
14
14
|
const { getDispatch, getAgentStatus } = queries;
|
|
@@ -597,11 +597,23 @@ function runCleanup(config, verbose = false) {
|
|
|
597
597
|
} catch (e) { log('warn', 'prune doc-sessions: ' + e.message); }
|
|
598
598
|
|
|
599
599
|
// 11. Cap cooldowns.json — keep at most 500 entries (on top of 24h TTL in cooldown.js)
|
|
600
|
+
// Also trim pendingContexts arrays to ENGINE_DEFAULTS.maxPendingContexts to prevent bloat.
|
|
600
601
|
cleaned.cooldowns = 0;
|
|
602
|
+
cleaned.pendingContextsTrimmed = 0;
|
|
601
603
|
try {
|
|
602
604
|
const cooldownPath = path.join(ENGINE_DIR, 'cooldowns.json');
|
|
603
605
|
const cooldowns = safeJson(cooldownPath);
|
|
604
606
|
if (cooldowns && typeof cooldowns === 'object') {
|
|
607
|
+
let dirty = false;
|
|
608
|
+
// Trim oversized pendingContexts arrays (one-time migration + ongoing cap)
|
|
609
|
+
const pendingCtxCap = ENGINE_DEFAULTS.maxPendingContexts;
|
|
610
|
+
for (const v of Object.values(cooldowns)) {
|
|
611
|
+
if (Array.isArray(v.pendingContexts) && v.pendingContexts.length > pendingCtxCap) {
|
|
612
|
+
v.pendingContexts = v.pendingContexts.slice(-pendingCtxCap);
|
|
613
|
+
cleaned.pendingContextsTrimmed++;
|
|
614
|
+
dirty = true;
|
|
615
|
+
}
|
|
616
|
+
}
|
|
605
617
|
const entries = Object.entries(cooldowns);
|
|
606
618
|
const COOLDOWN_CAP = 500;
|
|
607
619
|
if (entries.length > COOLDOWN_CAP) {
|
|
@@ -610,6 +622,8 @@ function runCleanup(config, verbose = false) {
|
|
|
610
622
|
const keep = Object.fromEntries(entries.slice(0, COOLDOWN_CAP));
|
|
611
623
|
cleaned.cooldowns = entries.length - COOLDOWN_CAP;
|
|
612
624
|
safeWrite(cooldownPath, keep);
|
|
625
|
+
} else if (dirty) {
|
|
626
|
+
safeWrite(cooldownPath, cooldowns);
|
|
613
627
|
}
|
|
614
628
|
}
|
|
615
629
|
} catch (e) { log('warn', 'cap cooldowns: ' + e.message); }
|
|
@@ -653,8 +667,8 @@ function runCleanup(config, verbose = false) {
|
|
|
653
667
|
}
|
|
654
668
|
} catch { /* optional — file may not exist */ }
|
|
655
669
|
|
|
656
|
-
if (cleaned.ccSessions + cleaned.docSessions + cleaned.cooldowns + cleaned.pidFiles > 0) {
|
|
657
|
-
log('info', `Cleanup (resources): ${cleaned.ccSessions} cc-sessions, ${cleaned.docSessions} doc-sessions, ${cleaned.cooldowns} cooldowns, ${cleaned.pidFiles} PID files`);
|
|
670
|
+
if (cleaned.ccSessions + cleaned.docSessions + cleaned.cooldowns + cleaned.pidFiles + cleaned.pendingContextsTrimmed > 0) {
|
|
671
|
+
log('info', `Cleanup (resources): ${cleaned.ccSessions} cc-sessions, ${cleaned.docSessions} doc-sessions, ${cleaned.cooldowns} cooldowns, ${cleaned.pendingContextsTrimmed} pendingCtx trimmed, ${cleaned.pidFiles} PID files`);
|
|
658
672
|
}
|
|
659
673
|
|
|
660
674
|
return cleaned;
|
package/engine/cooldown.js
CHANGED
|
@@ -7,7 +7,7 @@ const path = require('path');
|
|
|
7
7
|
const shared = require('./shared');
|
|
8
8
|
const queries = require('./queries');
|
|
9
9
|
|
|
10
|
-
const { safeJson, safeWrite, log } = shared;
|
|
10
|
+
const { safeJson, safeWrite, log, ENGINE_DEFAULTS } = shared;
|
|
11
11
|
const { ENGINE_DIR } = queries;
|
|
12
12
|
|
|
13
13
|
const COOLDOWN_PATH = path.join(ENGINE_DIR, 'cooldowns.json');
|
|
@@ -37,6 +37,13 @@ function saveCooldowns() {
|
|
|
37
37
|
for (const [k, v] of dispatchCooldowns) {
|
|
38
38
|
if (now - v.timestamp > 24 * 60 * 60 * 1000) dispatchCooldowns.delete(k);
|
|
39
39
|
}
|
|
40
|
+
// Trim pendingContexts arrays before writing to prevent bloat
|
|
41
|
+
const cap = ENGINE_DEFAULTS.maxPendingContexts;
|
|
42
|
+
for (const [, v] of dispatchCooldowns) {
|
|
43
|
+
if (Array.isArray(v.pendingContexts) && v.pendingContexts.length > cap) {
|
|
44
|
+
v.pendingContexts = v.pendingContexts.slice(-cap);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
40
47
|
const obj = Object.fromEntries(dispatchCooldowns);
|
|
41
48
|
try {
|
|
42
49
|
safeWrite(COOLDOWN_PATH, obj);
|
|
@@ -61,8 +68,11 @@ function setCooldown(key) {
|
|
|
61
68
|
|
|
62
69
|
function setCooldownWithContext(key, context) {
|
|
63
70
|
const existing = dispatchCooldowns.get(key);
|
|
64
|
-
|
|
71
|
+
let pendingContexts = existing?.pendingContexts || [];
|
|
65
72
|
if (context) pendingContexts.push(context);
|
|
73
|
+
// Cap to last N entries to prevent unbounded growth (cooldowns.json bloat)
|
|
74
|
+
const cap = ENGINE_DEFAULTS.maxPendingContexts;
|
|
75
|
+
if (pendingContexts.length > cap) pendingContexts = pendingContexts.slice(-cap);
|
|
66
76
|
dispatchCooldowns.set(key, {
|
|
67
77
|
timestamp: Date.now(),
|
|
68
78
|
failures: existing?.failures || 0,
|
package/engine/shared.js
CHANGED
|
@@ -569,6 +569,7 @@ const ENGINE_DEFAULTS = {
|
|
|
569
569
|
ccModel: 'sonnet', // model for Command Center and doc-chat (sonnet, haiku, opus)
|
|
570
570
|
ccEffort: null, // effort level for CC/doc-chat (null, 'low', 'medium', 'high')
|
|
571
571
|
heartbeatTimeouts: {}, // populated after WORK_TYPE is defined (below)
|
|
572
|
+
maxPendingContexts: 20, // cap pendingContexts arrays in cooldowns.json to prevent unbounded growth
|
|
572
573
|
ccMaxTurns: 50, // max tool-use turns for CC/doc-chat before CLI stops
|
|
573
574
|
// Teams integration — config.teams shape: { enabled, appId, appPassword, certPath, privateKeyPath, tenantId, notifyEvents, ccMirror, inboxPollInterval }
|
|
574
575
|
// Auth modes: (1) appId + appPassword (client secret), or (2) appId + certPath + privateKeyPath + tenantId (certificate)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1006",
|
|
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"
|