@yemi33/minions 0.1.1817 → 0.1.1819
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 +11 -6
- package/dashboard/js/state.js +8 -1
- package/engine/copilot-models.json +1 -1
- package/engine/spawn-agent.js +23 -46
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.1819 (2026-05-09)
|
|
4
|
+
|
|
5
|
+
### Fixes
|
|
6
|
+
- stop visibility=hidden beacons from racing pagehide and resurrecting closed-tab entries in dashboard-browser.json (#2275)
|
|
7
|
+
|
|
8
|
+
## 0.1.1818 (2026-05-09)
|
|
9
|
+
|
|
10
|
+
### Fixes
|
|
11
|
+
- write [process-exit] sentinel directly to live-output.log instead of bouncing it through stdout (#2266)
|
|
12
|
+
|
|
13
|
+
## 0.1.1816 (2026-05-09)
|
|
4
14
|
|
|
5
15
|
### Features
|
|
6
|
-
- suppress duplicate inline ask dispatch (#2256)
|
|
7
16
|
- correlate CC action failures (#2254)
|
|
8
17
|
|
|
9
|
-
### Other
|
|
10
|
-
- test(shared): add unit tests for project resolution and path comparison helpers (#2268)
|
|
11
|
-
- test(cli): add unit tests for pid/dispatch helpers and help formatter (#2267)
|
|
12
|
-
|
|
13
18
|
## 0.1.1815 (2026-05-09)
|
|
14
19
|
|
|
15
20
|
### Features
|
package/dashboard/js/state.js
CHANGED
|
@@ -127,7 +127,14 @@ function _sendDashboardPresence(closed) {
|
|
|
127
127
|
|
|
128
128
|
window.addEventListener('pagehide', function() { _sendDashboardPresence(true); });
|
|
129
129
|
window.addEventListener('beforeunload', function() { _sendDashboardPresence(true); });
|
|
130
|
-
|
|
130
|
+
// Only ping on becoming visible — hidden->presence beacons race the pagehide close
|
|
131
|
+
// beacon (both fire on tab close in quick succession via sendBeacon, ordering not
|
|
132
|
+
// guaranteed) and can resurrect a just-deleted entry with visibility:"hidden".
|
|
133
|
+
// Hidden tabs naturally expire via the 45s presence window; foreground returns
|
|
134
|
+
// re-fire visibilitychange so we still get a fresh heartbeat when the user comes back.
|
|
135
|
+
document.addEventListener('visibilitychange', function() {
|
|
136
|
+
if (document.visibilityState === 'visible') _sendDashboardPresence(false);
|
|
137
|
+
});
|
|
131
138
|
|
|
132
139
|
function rerenderPrdFromCache() {
|
|
133
140
|
if (!window._lastStatus || !window._lastStatus.prdProgress) return;
|
package/engine/spawn-agent.js
CHANGED
|
@@ -158,55 +158,32 @@ function injectAdoTokenEnvForRepoHost(env, opts) {
|
|
|
158
158
|
return injectAdoTokenEnv(env, opts);
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
-
const PROCESS_EXIT_SENTINEL_FLUSH_TIMEOUT_MS = 2000;
|
|
162
|
-
|
|
163
161
|
function formatProcessExitSentinel(exitCode, signal) {
|
|
164
162
|
return `\n[process-exit] code=${exitCode}${signal ? ` signal=${signal}` : ''}\n`;
|
|
165
163
|
}
|
|
166
164
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
function _writeStdoutWithTimeout(stdout, sentinel, timeoutMs) {
|
|
178
|
-
return new Promise((resolve) => {
|
|
179
|
-
let settled = false;
|
|
180
|
-
const finish = (flushed) => {
|
|
181
|
-
if (settled) return;
|
|
182
|
-
settled = true;
|
|
183
|
-
clearTimeout(timer);
|
|
184
|
-
resolve(flushed);
|
|
185
|
-
};
|
|
186
|
-
const timer = setTimeout(() => finish(false), Math.max(0, timeoutMs));
|
|
187
|
-
try {
|
|
188
|
-
if (!stdout || typeof stdout.write !== 'function') {
|
|
189
|
-
finish(false);
|
|
190
|
-
return;
|
|
191
|
-
}
|
|
192
|
-
stdout.write(sentinel, () => finish(true));
|
|
193
|
-
} catch {
|
|
194
|
-
finish(false);
|
|
195
|
-
}
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
async function writeProcessExitSentinel({
|
|
165
|
+
// The orphan reaper recovers an agent's exit code by scanning live-output.log for
|
|
166
|
+
// `[process-exit] code=N`. The previous design wrote the sentinel to stdout, hoping
|
|
167
|
+
// the engine's stdout consumer (engine.js) would copy it into the file — but when
|
|
168
|
+
// the engine was force-killed during a restart on Windows, the broken pipe
|
|
169
|
+
// silently swallowed the sentinel and the recovery never happened (see #2265 for
|
|
170
|
+
// the read-side recovery; this is the upstream fix). The orphan reaper only reads
|
|
171
|
+
// the file, so the simplest correct thing is to write the file directly. No
|
|
172
|
+
// stdout, no timeouts, no callbacks — one synchronous append.
|
|
173
|
+
function writeProcessExitSentinel({
|
|
200
174
|
exitCode,
|
|
201
175
|
signal = null,
|
|
202
|
-
stdout = process.stdout,
|
|
203
176
|
outputPath = process.env.MINIONS_LIVE_OUTPUT_PATH,
|
|
204
|
-
timeoutMs = PROCESS_EXIT_SENTINEL_FLUSH_TIMEOUT_MS,
|
|
205
177
|
} = {}) {
|
|
206
178
|
const sentinel = formatProcessExitSentinel(exitCode, signal);
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
179
|
+
let fileWritten = false;
|
|
180
|
+
if (outputPath) {
|
|
181
|
+
try {
|
|
182
|
+
fs.appendFileSync(outputPath, sentinel);
|
|
183
|
+
fileWritten = true;
|
|
184
|
+
} catch { /* file unavailable; orphan reaper falls back to runtime result event (#2265) */ }
|
|
185
|
+
}
|
|
186
|
+
return { sentinel, fileWritten };
|
|
210
187
|
}
|
|
211
188
|
|
|
212
189
|
function _appendOutputFallback(outputPath, chunk, prefix = '') {
|
|
@@ -432,19 +409,19 @@ function main() {
|
|
|
432
409
|
}, MCP_STARTUP_TIMEOUT);
|
|
433
410
|
proc.stdout.once('data', () => { gotFirstOutput = true; clearTimeout(startupTimer); });
|
|
434
411
|
|
|
435
|
-
proc.on('close',
|
|
412
|
+
proc.on('close', (code, signal) => {
|
|
436
413
|
clearTimeout(startupTimer);
|
|
437
414
|
const exitCode = normalizeRuntimeExit(code, signal);
|
|
438
|
-
const sentinelResult =
|
|
415
|
+
const sentinelResult = writeProcessExitSentinel({ exitCode, signal });
|
|
439
416
|
fs.appendFileSync(debugPath, `EXIT: code=${exitCode}${signal ? ` signal=${signal}` : ''}\nSTDERR: ${stderrBuf.slice(0, 500)}\n`);
|
|
440
|
-
if (!sentinelResult.
|
|
441
|
-
fs.appendFileSync(debugPath, `EXIT SENTINEL
|
|
417
|
+
if (!sentinelResult.fileWritten) {
|
|
418
|
+
fs.appendFileSync(debugPath, `EXIT SENTINEL: file write failed for ${process.env.MINIONS_LIVE_OUTPUT_PATH}\n`);
|
|
442
419
|
}
|
|
443
420
|
process.exit(exitCode);
|
|
444
421
|
});
|
|
445
|
-
proc.on('error',
|
|
422
|
+
proc.on('error', (err) => {
|
|
446
423
|
fs.appendFileSync(debugPath, `ERROR: ${err.message}\n`);
|
|
447
|
-
|
|
424
|
+
writeProcessExitSentinel({ exitCode: 1 });
|
|
448
425
|
process.exit(1);
|
|
449
426
|
});
|
|
450
427
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1819",
|
|
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"
|