@yemi33/minions 0.1.1708 → 0.1.1709
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 +5 -0
- package/engine/cli.js +22 -0
- package/engine/copilot-models.json +1 -1
- package/engine/shared.js +39 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
package/engine/cli.js
CHANGED
|
@@ -379,6 +379,28 @@ const commands = {
|
|
|
379
379
|
// refactor. No disk write — the on-disk config still carries `ccModel`.
|
|
380
380
|
try { shared.applyLegacyCcModelMigration(config, { logger: e.log }); }
|
|
381
381
|
catch (err) { e.log('warn', `legacy ccModel migration failed: ${err.message}`); }
|
|
382
|
+
|
|
383
|
+
// Auto-heal projects missing workSources (cloned-repo / hand-rolled-config
|
|
384
|
+
// footgun): without this block, discoverFromWorkItems / discoverFromPrs
|
|
385
|
+
// bail silently and the engine looks healthy but never dispatches. The
|
|
386
|
+
// disk-side mutation re-derives heal state from the on-disk copy so we
|
|
387
|
+
// don't clobber a concurrent dashboard write between the in-memory check
|
|
388
|
+
// and the lock acquire. skipWriteIfUnchanged makes the write a no-op when
|
|
389
|
+
// nothing needed healing (e.g. dashboard already fixed it).
|
|
390
|
+
try {
|
|
391
|
+
const heal = shared.backfillProjectWorkSourceDefaults(config);
|
|
392
|
+
if (heal.changed) {
|
|
393
|
+
const configPath = path.join(shared.MINIONS_DIR, 'config.json');
|
|
394
|
+
shared.mutateJsonFileLocked(configPath, (onDisk) => {
|
|
395
|
+
shared.backfillProjectWorkSourceDefaults(onDisk);
|
|
396
|
+
return onDisk;
|
|
397
|
+
}, { defaultValue: {}, skipWriteIfUnchanged: true });
|
|
398
|
+
for (const h of heal.healed) {
|
|
399
|
+
e.log('info', `Auto-healed project "${h.project}" — backfilled missing workSources: ${h.sources.join(', ')}`);
|
|
400
|
+
}
|
|
401
|
+
console.log(` Auto-healed ${heal.healed.length} project(s) with missing workSources defaults — engine will now dispatch their work.`);
|
|
402
|
+
}
|
|
403
|
+
} catch (err) { e.log('warn', `workSources auto-heal failed: ${err.message}`); }
|
|
382
404
|
const interval = config.engine?.tickInterval || shared.ENGINE_DEFAULTS.tickInterval;
|
|
383
405
|
|
|
384
406
|
const { getProjects } = require('./shared');
|
package/engine/shared.js
CHANGED
|
@@ -1185,6 +1185,44 @@ function projectWorkSourceWarnings(config, getDataCounts) {
|
|
|
1185
1185
|
return warnings;
|
|
1186
1186
|
}
|
|
1187
1187
|
|
|
1188
|
+
/**
|
|
1189
|
+
* Boot-time auto-heal for the cloned-repo / hand-rolled-config footgun: any
|
|
1190
|
+
* project missing a `workSources.workItems` or `workSources.pullRequests`
|
|
1191
|
+
* sub-block gets the dashboard's default backfilled. We only touch *missing*
|
|
1192
|
+
* sub-blocks — an explicit `enabled: false` is treated as user intent and
|
|
1193
|
+
* left alone.
|
|
1194
|
+
*
|
|
1195
|
+
* Pure helper — mutates `config` in place and returns
|
|
1196
|
+
* `{ changed: boolean, healed: Array<{ project, sources }> }` so the caller
|
|
1197
|
+
* can decide whether to persist + log. Returns `{ changed: false, healed: [] }`
|
|
1198
|
+
* for null/empty/malformed input.
|
|
1199
|
+
*/
|
|
1200
|
+
function backfillProjectWorkSourceDefaults(config) {
|
|
1201
|
+
const result = { changed: false, healed: [] };
|
|
1202
|
+
if (!config || typeof config !== 'object') return result;
|
|
1203
|
+
const projects = Array.isArray(config.projects) ? config.projects : [];
|
|
1204
|
+
for (const project of projects) {
|
|
1205
|
+
if (!project || typeof project !== 'object') continue;
|
|
1206
|
+
const filled = [];
|
|
1207
|
+
if (!project.workSources || typeof project.workSources !== 'object') {
|
|
1208
|
+
project.workSources = {};
|
|
1209
|
+
}
|
|
1210
|
+
if (!project.workSources.pullRequests) {
|
|
1211
|
+
project.workSources.pullRequests = { enabled: true, cooldownMinutes: 30 };
|
|
1212
|
+
filled.push('pullRequests');
|
|
1213
|
+
}
|
|
1214
|
+
if (!project.workSources.workItems) {
|
|
1215
|
+
project.workSources.workItems = { enabled: true, cooldownMinutes: 0 };
|
|
1216
|
+
filled.push('workItems');
|
|
1217
|
+
}
|
|
1218
|
+
if (filled.length > 0) {
|
|
1219
|
+
result.changed = true;
|
|
1220
|
+
result.healed.push({ project: project.name, sources: filled });
|
|
1221
|
+
}
|
|
1222
|
+
}
|
|
1223
|
+
return result;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1188
1226
|
// ─── Status & Type Constants ─────────────────────────────────────────────────
|
|
1189
1227
|
|
|
1190
1228
|
const WI_STATUS = {
|
|
@@ -2581,6 +2619,7 @@ module.exports = {
|
|
|
2581
2619
|
applyLegacyCcModelMigration, _resetLegacyCcModelMigrationFlag,
|
|
2582
2620
|
runtimeConfigWarnings,
|
|
2583
2621
|
projectWorkSourceWarnings,
|
|
2622
|
+
backfillProjectWorkSourceDefaults,
|
|
2584
2623
|
WI_STATUS, DONE_STATUSES, PLAN_TERMINAL_STATUSES, WORK_TYPE, PLAN_STATUS, PRD_ITEM_STATUS, PRD_MATERIALIZABLE, PR_STATUS, PR_POLLABLE_STATUSES, PR_PENDING_REASON, DISPATCH_RESULT, trackReviewMetric, queuePlanToPrd,
|
|
2585
2624
|
WATCH_STATUS, WATCH_TARGET_TYPE, WATCH_CONDITION, WATCH_ABSOLUTE_CONDITIONS,
|
|
2586
2625
|
PIPELINE_STATUS, STAGE_TYPE, MEETING_STATUS, AGENT_STATUS,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1709",
|
|
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"
|