@yemi33/minions 0.1.858 → 0.1.860
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 +3 -1
- package/dashboard/js/render-pipelines.js +2 -1
- package/dashboard.js +3 -2
- package/engine/pipeline.js +10 -0
- package/engine/timeout.js +3 -2
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.860 (2026-04-11)
|
|
4
4
|
|
|
5
5
|
### Fixes
|
|
6
|
+
- set steering state before killImmediate to prevent race
|
|
7
|
+
- pipeline race condition, delete refresh, abort error logging
|
|
6
8
|
- _continuePipeline now calls refresh() to update card list
|
|
7
9
|
- pipeline modal refresh was silently broken — API returns array not object
|
|
8
10
|
- pipeline modal now auto-updates on all action buttons
|
|
@@ -521,7 +521,8 @@ async function _deletePipelineConfirm(id) {
|
|
|
521
521
|
showToast('cmd-toast', 'Pipeline deleted', true);
|
|
522
522
|
try {
|
|
523
523
|
var res = await fetch('/api/pipelines/delete', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ id: id }) });
|
|
524
|
-
if (!res.ok) { showToast('cmd-toast', 'Delete failed', false);
|
|
524
|
+
if (!res.ok) { showToast('cmd-toast', 'Delete failed', false); }
|
|
525
|
+
refresh();
|
|
525
526
|
} catch (e) { showToast('cmd-toast', 'Error: ' + e.message, false); refresh(); }
|
|
526
527
|
}
|
|
527
528
|
|
package/dashboard.js
CHANGED
|
@@ -4446,8 +4446,9 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
4446
4446
|
if (!pipeline) return jsonReply(res, 404, { error: 'Pipeline not found' });
|
|
4447
4447
|
if (getActiveRun(body.id)) return jsonReply(res, 409, { error: 'Pipeline already has an active run' });
|
|
4448
4448
|
const run = startRun(body.id, pipeline);
|
|
4449
|
+
if (!run) return jsonReply(res, 409, { error: 'Pipeline already has an active run' });
|
|
4449
4450
|
invalidateStatusCache();
|
|
4450
|
-
return jsonReply(res, 200, { ok: true, runId: run
|
|
4451
|
+
return jsonReply(res, 200, { ok: true, runId: run?.runId });
|
|
4451
4452
|
}},
|
|
4452
4453
|
{ method: 'POST', path: '/api/pipelines/continue', desc: 'Continue a pipeline past a wait stage', params: 'id, stageId', handler: async (req, res) => {
|
|
4453
4454
|
const body = await readBody(req);
|
|
@@ -4482,7 +4483,7 @@ What would you like to discuss or change? When you're happy, say "approve" and I
|
|
|
4482
4483
|
}
|
|
4483
4484
|
}
|
|
4484
4485
|
});
|
|
4485
|
-
} catch {}
|
|
4486
|
+
} catch (e) { console.error(`Pipeline abort: WI cancel error: ${e.message}`); }
|
|
4486
4487
|
}
|
|
4487
4488
|
const dispatchCleaned = cleanDispatchEntries(d => d.meta?.item?._pipelineRun === run.runId);
|
|
4488
4489
|
invalidateStatusCache();
|
package/engine/pipeline.js
CHANGED
|
@@ -75,14 +75,24 @@ function startRun(pipelineId, pipeline) {
|
|
|
75
75
|
}
|
|
76
76
|
const run = { runId, pipelineId, startedAt: ts(), status: PIPELINE_STATUS.RUNNING, stages };
|
|
77
77
|
|
|
78
|
+
let alreadyActive = false;
|
|
78
79
|
mutateJsonFileLocked(PIPELINE_RUNS_PATH, (data) => {
|
|
79
80
|
if (!data[pipelineId]) data[pipelineId] = [];
|
|
81
|
+
// Guard: skip if there's already an active run (prevents race between ticks)
|
|
82
|
+
if (data[pipelineId].some(r => r.status === PIPELINE_STATUS.RUNNING || r.status === PIPELINE_STATUS.PAUSED)) {
|
|
83
|
+
alreadyActive = true;
|
|
84
|
+
return data;
|
|
85
|
+
}
|
|
80
86
|
// Keep last 10 runs per pipeline
|
|
81
87
|
if (data[pipelineId].length >= 10) data[pipelineId] = data[pipelineId].slice(-9);
|
|
82
88
|
data[pipelineId].push(run);
|
|
83
89
|
return data;
|
|
84
90
|
}, { defaultValue: {} });
|
|
85
91
|
|
|
92
|
+
if (alreadyActive) {
|
|
93
|
+
log('info', `Pipeline ${pipelineId}: skipped startRun — active run already exists`);
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
86
96
|
log('info', `Pipeline ${pipelineId}: started run ${runId}`);
|
|
87
97
|
return run;
|
|
88
98
|
}
|
package/engine/timeout.js
CHANGED
|
@@ -113,11 +113,12 @@ function checkSteering(config) {
|
|
|
113
113
|
|
|
114
114
|
log('info', `Steering: killing ${info.agentId} (${id}) for session resume with human message`);
|
|
115
115
|
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
// Set steering state BEFORE kill — close event may fire synchronously on some platforms
|
|
118
117
|
info._steeringMessage = message;
|
|
119
118
|
info._steeringSessionId = sessionId;
|
|
120
119
|
info._steeringAt = Date.now();
|
|
120
|
+
|
|
121
|
+
shared.killImmediate(info.proc);
|
|
121
122
|
}
|
|
122
123
|
}
|
|
123
124
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.860",
|
|
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"
|