@yemi33/minions 0.1.475 → 0.1.476

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,8 +1,9 @@
1
1
  # Changelog
2
2
 
3
- ## 0.1.475 (2026-04-07)
3
+ ## 0.1.476 (2026-04-07)
4
4
 
5
5
  ### Features
6
+ - Optimize getAgentStatus() to read only head+tail of live-output.log
6
7
  - Fix unlocked metrics.json in lifecycle.js post-merge hook
7
8
  - Fix unlocked metrics.json read-modify-write in trackEngineUsage
8
9
  - Limit SSE initial live-stream payload to last 64KB
package/engine/queries.js CHANGED
@@ -13,6 +13,35 @@ const { safeRead, safeReadDir, safeJson, safeWrite, getProjects,
13
13
  projectWorkItemsPath, projectPrPath, parseSkillFrontmatter, KB_CATEGORIES,
14
14
  WI_STATUS } = shared;
15
15
 
16
+ /**
17
+ * Read the first `bytes` and last `bytes` of a file efficiently using byte offsets.
18
+ * For files <= 2*bytes, reads the whole file. Returns { head, tail } strings.
19
+ * Returns { head: '', tail: '' } on any error.
20
+ */
21
+ function readHeadTail(filePath, bytes = 1024) {
22
+ try {
23
+ const stat = fs.statSync(filePath);
24
+ const size = stat.size;
25
+ if (size === 0) return { head: '', tail: '' };
26
+ if (size <= bytes * 2) {
27
+ const full = fs.readFileSync(filePath, 'utf8');
28
+ return { head: full, tail: full };
29
+ }
30
+ const fd = fs.openSync(filePath, 'r');
31
+ try {
32
+ const headBuf = Buffer.alloc(bytes);
33
+ fs.readSync(fd, headBuf, 0, bytes, 0);
34
+ const tailBuf = Buffer.alloc(bytes);
35
+ fs.readSync(fd, tailBuf, 0, bytes, size - bytes);
36
+ return { head: headBuf.toString('utf8'), tail: tailBuf.toString('utf8') };
37
+ } finally {
38
+ fs.closeSync(fd);
39
+ }
40
+ } catch {
41
+ return { head: '', tail: '' };
42
+ }
43
+ }
44
+
16
45
  // ── Paths ───────────────────────────────────────────────────────────────────
17
46
 
18
47
  const MINIONS_DIR = shared.MINIONS_DIR;
@@ -130,19 +159,20 @@ function getAgentStatus(agentId) {
130
159
  branch: active.meta?.branch || '',
131
160
  started_at: active.started_at || active.created_at || null,
132
161
  };
133
- // Detect permission-waiting: check live output for non-bypass permission mode
162
+ // Detect permission-waiting: read only head+tail of live-output.log (max 2KB total)
134
163
  try {
135
- const liveLog = shared.safeRead(path.join(AGENTS_DIR, agentId, 'live-output.log'));
136
- if (liveLog) {
137
- // Check init message for permission mode
138
- const initMatch = liveLog.match(/"permissionMode"\s*:\s*"([^"]+)"/);
164
+ const liveLogPath = path.join(AGENTS_DIR, agentId, 'live-output.log');
165
+ const { head, tail } = readHeadTail(liveLogPath, 1024);
166
+ if (head) {
167
+ // Check init message (in head) for permission mode
168
+ const initMatch = head.match(/"permissionMode"\s*:\s*"([^"]+)"/);
139
169
  if (initMatch && initMatch[1] !== 'bypassPermissions') {
140
170
  result._permissionMode = initMatch[1];
141
171
  }
142
- // Check if agent has been silent for >60s (possible permission prompt wait)
143
- const lastLine = liveLog.trimEnd().split('\n').pop();
172
+ // Check if agent has been silent for >60s (use tail for recent activity)
173
+ const lastLine = tail.trimEnd().split('\n').pop();
144
174
  if (lastLine && lastLine.includes('"type":"assistant"') && lastLine.includes('"tool_use"')) {
145
- const liveStat = fs.statSync(path.join(AGENTS_DIR, agentId, 'live-output.log'));
175
+ const liveStat = fs.statSync(liveLogPath);
146
176
  const silentMs = Date.now() - liveStat.mtimeMs;
147
177
  if (silentMs > 60000 && result._permissionMode) {
148
178
  result._warning = 'Possibly waiting for permission approval — agent is not in bypass mode';
@@ -748,6 +778,7 @@ module.exports = {
748
778
 
749
779
  // Helpers
750
780
  timeSince,
781
+ readHeadTail, // exported for testing
751
782
 
752
783
  // Core state
753
784
  getConfig, getControl, getDispatch, getDispatchQueue,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yemi33/minions",
3
- "version": "0.1.475",
3
+ "version": "0.1.476",
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"