@yemi33/minions 0.1.474 → 0.1.475

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,11 +1,14 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.474 (2026-04-07)
3
+ ## 0.1.475 (2026-04-07)
4
4
 
5
5
  ### Features
6
+ - Fix unlocked metrics.json in lifecycle.js post-merge hook
7
+ - Fix unlocked metrics.json read-modify-write in trackEngineUsage
6
8
  - Limit SSE initial live-stream payload to last 64KB
7
9
 
8
10
  ### Fixes
11
+ - add optional chaining for config.agents in updatePrAfterReview
9
12
  - pass config to updatePrAfterReview to fix test failure
10
13
 
11
14
  ## 0.1.473 (2026-04-07)
@@ -717,7 +717,7 @@ function updatePrAfterReview(agentId, pr, project, config) {
717
717
  if (!pr?.id) return;
718
718
 
719
719
  if (!config) config = getConfig();
720
- const reviewerName = config.agents[agentId]?.name || agentId;
720
+ const reviewerName = config.agents?.[agentId]?.name || agentId;
721
721
  const dispatch = getDispatch();
722
722
  const completedEntry = (dispatch.completed || []).find(d => d.agent === agentId && d.type === 'review');
723
723
 
@@ -853,10 +853,11 @@ async function handlePostMerge(pr, project, config, newStatus) {
853
853
  const agentId = (pr.agent || '').toLowerCase();
854
854
  if (agentId && config.agents?.[agentId]) {
855
855
  const metricsPath = path.join(ENGINE_DIR, 'metrics.json');
856
- const metrics = safeJson(metricsPath) || {};
857
- if (!metrics[agentId]) metrics[agentId] = { tasksCompleted:0, tasksErrored:0, prsCreated:0, prsApproved:0, prsRejected:0, prsMerged:0, reviewsDone:0, lastTask:null, lastCompleted:null };
858
- metrics[agentId].prsMerged = (metrics[agentId].prsMerged || 0) + 1;
859
- shared.safeWrite(metricsPath, metrics);
856
+ mutateJsonFileLocked(metricsPath, (metrics) => {
857
+ if (!metrics[agentId]) metrics[agentId] = { tasksCompleted:0, tasksErrored:0, prsCreated:0, prsApproved:0, prsRejected:0, prsMerged:0, reviewsDone:0, lastTask:null, lastCompleted:null };
858
+ metrics[agentId].prsMerged = (metrics[agentId].prsMerged || 0) + 1;
859
+ return metrics;
860
+ });
860
861
  }
861
862
 
862
863
  const teamsUrl = process.env.TEAMS_PLAN_FLOW_URL;
package/engine/llm.js CHANGED
@@ -5,7 +5,7 @@
5
5
 
6
6
  const path = require('path');
7
7
  const shared = require('./shared');
8
- const { safeRead, safeWrite, safeUnlink, uid, runFile, cleanChildEnv, parseStreamJsonOutput } = shared;
8
+ const { safeWrite, safeUnlink, uid, runFile, cleanChildEnv, parseStreamJsonOutput, mutateJsonFileLocked } = shared;
9
9
 
10
10
  const MINIONS_DIR = path.resolve(__dirname, '..');
11
11
  const ENGINE_DIR = __dirname;
@@ -14,31 +14,30 @@ function trackEngineUsage(category, usage) {
14
14
  if (!usage) return;
15
15
  try {
16
16
  const metricsPath = path.join(ENGINE_DIR, 'metrics.json');
17
- const raw = safeRead(metricsPath);
18
- const metrics = raw ? JSON.parse(raw) : {};
19
-
20
- if (!metrics._engine) metrics._engine = {};
21
- if (!metrics._engine[category]) {
22
- metrics._engine[category] = { calls: 0, costUsd: 0, inputTokens: 0, outputTokens: 0, cacheRead: 0, cacheCreation: 0 };
23
- }
24
- const cat = metrics._engine[category];
25
- cat.calls++;
26
- cat.costUsd += usage.costUsd || 0;
27
- cat.inputTokens += usage.inputTokens || 0;
28
- cat.outputTokens += usage.outputTokens || 0;
29
- cat.cacheRead += usage.cacheRead || 0;
30
- cat.cacheCreation = (cat.cacheCreation || 0) + (usage.cacheCreation || 0);
31
-
32
- const today = new Date().toISOString().slice(0, 10);
33
- if (!metrics._daily) metrics._daily = {};
34
- if (!metrics._daily[today]) metrics._daily[today] = { costUsd: 0, inputTokens: 0, outputTokens: 0, cacheRead: 0, tasks: 0 };
35
- const daily = metrics._daily[today];
36
- daily.costUsd += usage.costUsd || 0;
37
- daily.inputTokens += usage.inputTokens || 0;
38
- daily.outputTokens += usage.outputTokens || 0;
39
- daily.cacheRead += usage.cacheRead || 0;
40
-
41
- safeWrite(metricsPath, metrics);
17
+ mutateJsonFileLocked(metricsPath, (metrics) => {
18
+ if (!metrics._engine) metrics._engine = {};
19
+ if (!metrics._engine[category]) {
20
+ metrics._engine[category] = { calls: 0, costUsd: 0, inputTokens: 0, outputTokens: 0, cacheRead: 0, cacheCreation: 0 };
21
+ }
22
+ const cat = metrics._engine[category];
23
+ cat.calls++;
24
+ cat.costUsd += usage.costUsd || 0;
25
+ cat.inputTokens += usage.inputTokens || 0;
26
+ cat.outputTokens += usage.outputTokens || 0;
27
+ cat.cacheRead += usage.cacheRead || 0;
28
+ cat.cacheCreation = (cat.cacheCreation || 0) + (usage.cacheCreation || 0);
29
+
30
+ const today = new Date().toISOString().slice(0, 10);
31
+ if (!metrics._daily) metrics._daily = {};
32
+ if (!metrics._daily[today]) metrics._daily[today] = { costUsd: 0, inputTokens: 0, outputTokens: 0, cacheRead: 0, tasks: 0 };
33
+ const daily = metrics._daily[today];
34
+ daily.costUsd += usage.costUsd || 0;
35
+ daily.inputTokens += usage.inputTokens || 0;
36
+ daily.outputTokens += usage.outputTokens || 0;
37
+ daily.cacheRead += usage.cacheRead || 0;
38
+
39
+ return metrics;
40
+ });
42
41
  } catch (e) { console.error('metrics update:', e.message); }
43
42
  }
44
43
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.474",
3
+ "version": "0.1.475",
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"