@yemi33/minions 0.1.608 → 0.1.610
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 +18 -1
- package/engine/cli.js +3 -1
- package/engine/queries.js +51 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.610 (2026-04-08)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- worktree count now checks for .git file instead of any directory
|
|
7
|
+
|
|
8
|
+
## 0.1.609 (2026-04-08)
|
|
9
|
+
|
|
10
|
+
### Fixes
|
|
11
|
+
- show lifetime completed count instead of capped dispatch window
|
|
4
12
|
|
|
5
13
|
### Other
|
|
6
14
|
- docs: add CC/doc-chat flow section, fix stale claims in CLAUDE.md
|
package/dashboard.js
CHANGED
|
@@ -176,7 +176,24 @@ function _countWorktrees() {
|
|
|
176
176
|
const root = p.localPath ? path.resolve(p.localPath) : null;
|
|
177
177
|
if (!root) continue;
|
|
178
178
|
const wtRoot = path.resolve(root, config.engine?.worktreeRoot || shared.ENGINE_DEFAULTS.worktreeRoot);
|
|
179
|
-
try {
|
|
179
|
+
try {
|
|
180
|
+
for (const dir of fs.readdirSync(wtRoot)) {
|
|
181
|
+
const dirPath = path.join(wtRoot, dir);
|
|
182
|
+
try { if (!fs.statSync(dirPath).isDirectory()) continue; } catch { continue; }
|
|
183
|
+
// A git worktree has a .git file (not directory) in its root
|
|
184
|
+
if (fs.existsSync(path.join(dirPath, '.git'))) {
|
|
185
|
+
count++;
|
|
186
|
+
} else {
|
|
187
|
+
// Parent directory — scan subdirs for nested worktrees
|
|
188
|
+
try {
|
|
189
|
+
for (const sub of fs.readdirSync(dirPath)) {
|
|
190
|
+
const subPath = path.join(dirPath, sub);
|
|
191
|
+
try { if (fs.statSync(subPath).isDirectory() && fs.existsSync(path.join(subPath, '.git'))) count++; } catch {}
|
|
192
|
+
}
|
|
193
|
+
} catch {}
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
} catch {}
|
|
180
197
|
}
|
|
181
198
|
return count;
|
|
182
199
|
} catch { return 0; }
|
package/engine/cli.js
CHANGED
|
@@ -556,7 +556,9 @@ const commands = {
|
|
|
556
556
|
}
|
|
557
557
|
|
|
558
558
|
console.log('');
|
|
559
|
-
|
|
559
|
+
const metrics = shared.safeJson(path.join(__dirname, 'metrics.json')) || {};
|
|
560
|
+
const lifetimeCompleted = Object.entries(metrics).filter(([k]) => !k.startsWith('_')).reduce((sum, [, m]) => sum + (m.tasksCompleted || 0) + (m.tasksErrored || 0), 0);
|
|
561
|
+
console.log(`Dispatch: ${dispatch.pending.length} pending | ${(dispatch.active || []).length} active | ${lifetimeCompleted} completed`);
|
|
560
562
|
console.log(`Active processes: ${e.activeProcesses.size}`);
|
|
561
563
|
|
|
562
564
|
const metricsPath = path.join(ENGINE_DIR, 'metrics.json');
|
package/engine/queries.js
CHANGED
|
@@ -94,7 +94,9 @@ function invalidateDispatchCache() { _dispatchCache = null; _dispatchCacheAt = 0
|
|
|
94
94
|
function getDispatchQueue() {
|
|
95
95
|
const d = getDispatch();
|
|
96
96
|
const allCompleted = d.completed || [];
|
|
97
|
-
|
|
97
|
+
// Lifetime total from metrics (dispatch.completed is capped at 100)
|
|
98
|
+
const metrics = safeJson(path.join(ENGINE_DIR, 'metrics.json')) || {};
|
|
99
|
+
d.completedTotal = Object.entries(metrics).filter(([k]) => !k.startsWith('_')).reduce((sum, [, m]) => sum + (m.tasksCompleted || 0) + (m.tasksErrored || 0), 0);
|
|
98
100
|
d.completed = allCompleted.slice(-20);
|
|
99
101
|
return d;
|
|
100
102
|
}
|
|
@@ -122,7 +124,54 @@ function getEngineLog() {
|
|
|
122
124
|
}
|
|
123
125
|
|
|
124
126
|
function getMetrics() {
|
|
125
|
-
|
|
127
|
+
const metrics = safeJson(path.join(ENGINE_DIR, 'metrics.json')) || {};
|
|
128
|
+
|
|
129
|
+
// Enrich agent PR counts from pull-requests.json (source of truth)
|
|
130
|
+
const allPrs = getPullRequests();
|
|
131
|
+
const prCountByAgent = {};
|
|
132
|
+
const prApprovedByAgent = {};
|
|
133
|
+
const prRejectedByAgent = {};
|
|
134
|
+
for (const pr of allPrs) {
|
|
135
|
+
const agent = (pr.agent || '').toLowerCase();
|
|
136
|
+
if (!agent || agent.startsWith('temp-')) continue;
|
|
137
|
+
prCountByAgent[agent] = (prCountByAgent[agent] || 0) + 1;
|
|
138
|
+
if (pr.reviewStatus === 'approved' || pr.status === 'merged') prApprovedByAgent[agent] = (prApprovedByAgent[agent] || 0) + 1;
|
|
139
|
+
if (pr.reviewStatus === 'rejected') prRejectedByAgent[agent] = (prRejectedByAgent[agent] || 0) + 1;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Enrich agent runtime from completed dispatch entries
|
|
143
|
+
const dispatch = getDispatch();
|
|
144
|
+
const runtimeByAgent = {};
|
|
145
|
+
const runtimeCountByAgent = {};
|
|
146
|
+
for (const d of (dispatch.completed || [])) {
|
|
147
|
+
const agent = d.agent;
|
|
148
|
+
if (!agent || agent.startsWith('temp-')) continue;
|
|
149
|
+
if (d.started_at && d.completed_at) {
|
|
150
|
+
const ms = new Date(d.completed_at).getTime() - new Date(d.started_at).getTime();
|
|
151
|
+
if (ms > 0) {
|
|
152
|
+
runtimeByAgent[agent] = (runtimeByAgent[agent] || 0) + ms;
|
|
153
|
+
runtimeCountByAgent[agent] = (runtimeCountByAgent[agent] || 0) + 1;
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
// Apply enrichments to agent metrics
|
|
159
|
+
for (const [agentId, m] of Object.entries(metrics)) {
|
|
160
|
+
if (agentId.startsWith('_')) continue;
|
|
161
|
+
const lower = agentId.toLowerCase();
|
|
162
|
+
if (prCountByAgent[lower] !== undefined) {
|
|
163
|
+
m.prsCreated = prCountByAgent[lower];
|
|
164
|
+
m.prsApproved = prApprovedByAgent[lower] || 0;
|
|
165
|
+
m.prsRejected = prRejectedByAgent[lower] || 0;
|
|
166
|
+
}
|
|
167
|
+
if (runtimeByAgent[agentId]) {
|
|
168
|
+
// Use dispatch history as source of truth — it has full history
|
|
169
|
+
m.totalRuntimeMs = runtimeByAgent[agentId];
|
|
170
|
+
m.timedTasks = runtimeCountByAgent[agentId];
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
return metrics;
|
|
126
175
|
}
|
|
127
176
|
|
|
128
177
|
// ── Inbox ───────────────────────────────────────────────────────────────────
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.610",
|
|
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"
|