@yemi33/minions 0.1.1632 → 0.1.1634
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 +17 -2
- package/dashboard.js +46 -0
- package/engine/copilot-models.json +1 -1
- package/engine/dispatch.js +102 -73
- package/engine/lifecycle.js +12 -0
- package/engine/playbook.js +2 -1
- package/engine.js +2 -0
- package/package.json +1 -1
- package/playbooks/docs.md +113 -0
- package/playbooks/fix.md +17 -19
- package/playbooks/implement-shared.md +17 -16
- package/playbooks/implement.md +19 -14
- package/playbooks/shared-rules.md +11 -0
- package/playbooks/work-item.md +26 -23
- package/prompts/cc-system.md +2 -0
- package/routing.md +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,9 +1,24 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.1634 (2026-04-30)
|
|
4
|
+
|
|
5
|
+
### Features
|
|
6
|
+
- build-and-test CC action + docs playbook
|
|
7
|
+
|
|
8
|
+
## 0.1.1633 (2026-04-30)
|
|
9
|
+
|
|
10
|
+
### Features
|
|
11
|
+
- prevent completed stderr redispatch
|
|
12
|
+
|
|
13
|
+
### Fixes
|
|
14
|
+
- yemi33/minions#1890
|
|
15
|
+
|
|
16
|
+
### Other
|
|
17
|
+
- docs: relax minions playbook contracts
|
|
18
|
+
|
|
19
|
+
## 0.1.1631 (2026-04-30)
|
|
4
20
|
|
|
5
21
|
### Features
|
|
6
|
-
- guard malformed PR context
|
|
7
22
|
- clear stale pending reason on retry
|
|
8
23
|
|
|
9
24
|
## 0.1.1629 (2026-04-29)
|
package/dashboard.js
CHANGED
|
@@ -25,6 +25,9 @@ const ado = require('./engine/ado');
|
|
|
25
25
|
const gh = require('./engine/github');
|
|
26
26
|
const issues = require('./engine/issues');
|
|
27
27
|
const watchesMod = require('./engine/watches');
|
|
28
|
+
const routing = require('./engine/routing');
|
|
29
|
+
const playbook = require('./engine/playbook');
|
|
30
|
+
const dispatchMod = require('./engine/dispatch');
|
|
28
31
|
const os = require('os');
|
|
29
32
|
|
|
30
33
|
const { safeRead, safeReadDir, safeWrite, safeJson, safeJsonObj, safeJsonArr, safeUnlink, mutateJsonFileLocked, mutateWorkItems, getProjects: _getProjects, DONE_STATUSES, WI_STATUS, reopenWorkItem } = shared;
|
|
@@ -1238,6 +1241,49 @@ async function executeCCActions(actions) {
|
|
|
1238
1241
|
results.push({ type: action.type, id, ok: true });
|
|
1239
1242
|
break;
|
|
1240
1243
|
}
|
|
1244
|
+
case 'build-and-test': {
|
|
1245
|
+
// Resolve PR by number, ID, or URL — same lookup that drives the link-pr / PR-row paths.
|
|
1246
|
+
const allPrs = getPullRequests().filter(p => !p._ghost);
|
|
1247
|
+
const pr = shared.findPrRecord(allPrs, action.pr) || null;
|
|
1248
|
+
if (!pr) {
|
|
1249
|
+
results.push({ type: 'build-and-test', error: `PR not found: ${action.pr}` });
|
|
1250
|
+
break;
|
|
1251
|
+
}
|
|
1252
|
+
// Resolve project: explicit param wins, else PR's _project, else first configured project as last resort.
|
|
1253
|
+
const projectName = action.project || pr._project || null;
|
|
1254
|
+
const project = projectName
|
|
1255
|
+
? PROJECTS.find(p => p.name?.toLowerCase() === String(projectName).toLowerCase())
|
|
1256
|
+
: null;
|
|
1257
|
+
if (!project) {
|
|
1258
|
+
results.push({ type: 'build-and-test', error: `Project not found for PR ${pr.id}: ${projectName || '(none)'}` });
|
|
1259
|
+
break;
|
|
1260
|
+
}
|
|
1261
|
+
// Pick agent: explicit param wins; else routing for 'test' work type.
|
|
1262
|
+
let agentId = action.agent && CONFIG.agents?.[action.agent] ? action.agent : null;
|
|
1263
|
+
if (!agentId) {
|
|
1264
|
+
agentId = routing.resolveAgent('test', CONFIG, { authorAgent: pr.agent });
|
|
1265
|
+
}
|
|
1266
|
+
if (!agentId) {
|
|
1267
|
+
results.push({ type: 'build-and-test', error: 'No available agent for test routing' });
|
|
1268
|
+
break;
|
|
1269
|
+
}
|
|
1270
|
+
const prNumber = shared.getPrNumber(pr);
|
|
1271
|
+
const dispatchKey = `cc-bt-${project.name}-${pr.id}`;
|
|
1272
|
+
const item = playbook.buildPrDispatch(agentId, CONFIG, project, pr, 'test', {
|
|
1273
|
+
pr_id: pr.id, pr_number: prNumber, pr_title: pr.title || '', pr_branch: pr.branch || '',
|
|
1274
|
+
pr_author: pr.agent || '', pr_url: pr.url || '',
|
|
1275
|
+
project_path: project.localPath || '',
|
|
1276
|
+
task: `Build & test ${pr.id}: ${pr.title || ''}`,
|
|
1277
|
+
}, `Build & test ${pr.id}: ${pr.title || ''}`,
|
|
1278
|
+
{ dispatchKey, source: 'cc-build-and-test', pr, branch: pr.branch, project: { name: project.name, localPath: project.localPath } });
|
|
1279
|
+
if (!item) {
|
|
1280
|
+
results.push({ type: 'build-and-test', error: 'Failed to render build-and-test playbook' });
|
|
1281
|
+
break;
|
|
1282
|
+
}
|
|
1283
|
+
const id = dispatchMod.addToDispatch(item);
|
|
1284
|
+
results.push({ type: 'build-and-test', id, agent: agentId, pr: pr.id, ok: true });
|
|
1285
|
+
break;
|
|
1286
|
+
}
|
|
1241
1287
|
case 'note': {
|
|
1242
1288
|
shared.writeToInbox('command-center', shared.slugify(action.title || 'note'), `# ${action.title || 'Note'}\n\n${action.content || action.description || ''}`);
|
|
1243
1289
|
results.push({ type: 'note', ok: true });
|
package/engine/dispatch.js
CHANGED
|
@@ -184,6 +184,22 @@ function isRetryableFailureReason(reason = '', failureClass = '') {
|
|
|
184
184
|
return !nonRetryable.some(s => r.includes(s));
|
|
185
185
|
}
|
|
186
186
|
|
|
187
|
+
function isCompletedWorkItemForFailure(item) {
|
|
188
|
+
return !!item && (
|
|
189
|
+
item.status === WI_STATUS.DONE ||
|
|
190
|
+
(!!item.completedAt && (!!item._pr || !!item._prUrl))
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function readLiveWorkItem(meta) {
|
|
195
|
+
const itemId = meta?.item?.id;
|
|
196
|
+
if (!itemId) return null;
|
|
197
|
+
const wiPath = lifecycle().resolveWorkItemPath(meta);
|
|
198
|
+
if (!wiPath) return null;
|
|
199
|
+
const items = safeJson(wiPath) || [];
|
|
200
|
+
return Array.isArray(items) ? items.find(i => i.id === itemId) || null : null;
|
|
201
|
+
}
|
|
202
|
+
|
|
187
203
|
// ─── Complete Dispatch ───────────────────────────────────────────────────────
|
|
188
204
|
|
|
189
205
|
function completeDispatch(id, result = DISPATCH_RESULT.SUCCESS, reason = '', resultSummary = '', opts = {}) {
|
|
@@ -225,83 +241,96 @@ function completeDispatch(id, result = DISPATCH_RESULT.SUCCESS, reason = '', res
|
|
|
225
241
|
|
|
226
242
|
// Update source work item status on failure + auto-retry with backoff
|
|
227
243
|
const retryableFailure = isRetryableFailureReason(reason, failureClass);
|
|
228
|
-
|
|
229
|
-
|
|
244
|
+
let completedWorkItemFailure = false;
|
|
230
245
|
if (processWorkItemFailure && result === DISPATCH_RESULT.ERROR && item.meta?.item?.id) {
|
|
231
|
-
|
|
246
|
+
// If the live item cannot be resolved, keep the existing retry path.
|
|
232
247
|
try {
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
if (item.meta?.dispatchKey) {
|
|
244
|
-
try {
|
|
245
|
-
mutateDispatch((dp) => {
|
|
246
|
-
dp.completed = Array.isArray(dp.completed) ? dp.completed.filter(d => d.meta?.dispatchKey !== item.meta.dispatchKey) : [];
|
|
247
|
-
return dp;
|
|
248
|
-
});
|
|
249
|
-
} catch (e) { log('warn', 'clear dispatch for retry: ' + e.message); }
|
|
250
|
-
}
|
|
251
|
-
// Increment retry counter on the source work item
|
|
252
|
-
try {
|
|
253
|
-
const wiPath = lifecycle().resolveWorkItemPath(item.meta);
|
|
254
|
-
if (wiPath) {
|
|
255
|
-
mutateWorkItems(wiPath, items => {
|
|
256
|
-
const wi = items.find(i => i.id === item.meta.item.id);
|
|
257
|
-
if (wi && wi.status !== WI_STATUS.PAUSED && wi.status !== WI_STATUS.DONE && !wi.completedAt) {
|
|
258
|
-
wi._retryCount = retries + 1;
|
|
259
|
-
wi.status = WI_STATUS.PENDING;
|
|
260
|
-
wi._lastRetryReason = reason || '';
|
|
261
|
-
wi._lastRetryAt = ts();
|
|
262
|
-
delete wi.failReason;
|
|
263
|
-
delete wi.failedAt;
|
|
264
|
-
delete wi.dispatched_at;
|
|
265
|
-
delete wi.dispatched_to;
|
|
266
|
-
delete wi._pendingReason;
|
|
267
|
-
}
|
|
268
|
-
});
|
|
269
|
-
}
|
|
270
|
-
} catch (e) { log('warn', 'increment retry counter: ' + e.message); }
|
|
248
|
+
completedWorkItemFailure = isCompletedWorkItemForFailure(readLiveWorkItem(item.meta));
|
|
249
|
+
} catch (e) { log('warn', 'read live work item before retry: ' + e.message); }
|
|
250
|
+
}
|
|
251
|
+
if (result === DISPATCH_RESULT.ERROR && item.meta?.dispatchKey && retryableFailure && !completedWorkItemFailure) {
|
|
252
|
+
setCooldownFailure(item.meta.dispatchKey);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
if (processWorkItemFailure && result === DISPATCH_RESULT.ERROR && item.meta?.item?.id) {
|
|
256
|
+
if (completedWorkItemFailure) {
|
|
257
|
+
log('info', `Dispatch error for ${item.meta.item.id} ignored — work item is already completed`);
|
|
271
258
|
} else {
|
|
272
|
-
|
|
273
|
-
const CLASS_LABELS = {
|
|
274
|
-
[FAILURE_CLASS.EMPTY_OUTPUT]: 'agent produced no output \u2014 likely crashed on startup',
|
|
275
|
-
[FAILURE_CLASS.BUILD_FAILURE]: 'build/test/lint failure in output',
|
|
276
|
-
[FAILURE_CLASS.MERGE_CONFLICT]: 'merge conflict',
|
|
277
|
-
[FAILURE_CLASS.MAX_TURNS]: 'reached max turn limit',
|
|
278
|
-
[FAILURE_CLASS.TIMEOUT]: 'timed out waiting for agent',
|
|
279
|
-
[FAILURE_CLASS.SPAWN_ERROR]: 'agent process failed to start',
|
|
280
|
-
[FAILURE_CLASS.NETWORK_ERROR]: 'network or API error',
|
|
281
|
-
[FAILURE_CLASS.OUT_OF_CONTEXT]: 'context window exhausted',
|
|
282
|
-
[FAILURE_CLASS.CONFIG_ERROR]: 'configuration error',
|
|
283
|
-
[FAILURE_CLASS.PERMISSION_BLOCKED]: 'permission or auth failure',
|
|
284
|
-
[FAILURE_CLASS.UNKNOWN]: 'unknown error',
|
|
285
|
-
};
|
|
286
|
-
const classLabel = failureClass ? (CLASS_LABELS[failureClass] || failureClass) : '';
|
|
287
|
-
const effectiveReason = reason || classLabel || 'Unknown error';
|
|
288
|
-
const classSuffix = failureClass ? ` [${failureClass.toUpperCase().replace(/-/g, '_')}]` : '';
|
|
289
|
-
const finalReason = !retryableFailure
|
|
290
|
-
? `Non-retryable failure: ${effectiveReason}${classSuffix}`
|
|
291
|
-
: (reason || `Failed after ${maxRetries} retries${classSuffix}`);
|
|
292
|
-
lifecycle().updateWorkItemStatus(item.meta, WI_STATUS.FAILED, finalReason);
|
|
293
|
-
// Surface blocked dependents in logs without creating failure inbox noise.
|
|
259
|
+
let retries = (item.meta.item._retryCount || 0);
|
|
294
260
|
try {
|
|
295
|
-
const
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
log('
|
|
303
|
-
|
|
304
|
-
|
|
261
|
+
const wi = queries.getWorkItems().find(i => i.id === item.meta.item.id);
|
|
262
|
+
if (wi) retries = wi._retryCount || 0;
|
|
263
|
+
} catch (e) { log('warn', 'read retry count: ' + e.message); }
|
|
264
|
+
const maxRetries = ENGINE_DEFAULTS.maxRetries;
|
|
265
|
+
// Use per-class retry limits from recovery.js when failureClass is available
|
|
266
|
+
const classAllowsRetry = failureClass ? recovery().shouldRetry(failureClass, retries) : (retries < maxRetries);
|
|
267
|
+
if (retryableFailure && classAllowsRetry) {
|
|
268
|
+
log('info', `Dispatch error for ${item.meta.item.id} — auto-retry ${retries + 1}/${maxRetries}${failureClass ? ' [' + failureClass + ']' : ''}`);
|
|
269
|
+
lifecycle().updateWorkItemStatus(item.meta, WI_STATUS.PENDING, '');
|
|
270
|
+
// Remove this dispatch key from completed so dedupe doesn't block immediate redispatch.
|
|
271
|
+
if (item.meta?.dispatchKey) {
|
|
272
|
+
try {
|
|
273
|
+
mutateDispatch((dp) => {
|
|
274
|
+
dp.completed = Array.isArray(dp.completed) ? dp.completed.filter(d => d.meta?.dispatchKey !== item.meta.dispatchKey) : [];
|
|
275
|
+
return dp;
|
|
276
|
+
});
|
|
277
|
+
} catch (e) { log('warn', 'clear dispatch for retry: ' + e.message); }
|
|
278
|
+
}
|
|
279
|
+
// Increment retry counter on the source work item
|
|
280
|
+
try {
|
|
281
|
+
const wiPath = lifecycle().resolveWorkItemPath(item.meta);
|
|
282
|
+
if (wiPath) {
|
|
283
|
+
mutateWorkItems(wiPath, items => {
|
|
284
|
+
const wi = items.find(i => i.id === item.meta.item.id);
|
|
285
|
+
if (wi && wi.status !== WI_STATUS.PAUSED && wi.status !== WI_STATUS.DONE && !wi.completedAt) {
|
|
286
|
+
wi._retryCount = retries + 1;
|
|
287
|
+
wi.status = WI_STATUS.PENDING;
|
|
288
|
+
wi._lastRetryReason = reason || '';
|
|
289
|
+
wi._lastRetryAt = ts();
|
|
290
|
+
delete wi.failReason;
|
|
291
|
+
delete wi.failedAt;
|
|
292
|
+
delete wi.dispatched_at;
|
|
293
|
+
delete wi.dispatched_to;
|
|
294
|
+
delete wi._pendingReason;
|
|
295
|
+
}
|
|
296
|
+
});
|
|
297
|
+
}
|
|
298
|
+
} catch (e) { log('warn', 'increment retry counter: ' + e.message); }
|
|
299
|
+
} else {
|
|
300
|
+
// Human-readable labels for each failure class — used as fallback when reason is empty
|
|
301
|
+
const CLASS_LABELS = {
|
|
302
|
+
[FAILURE_CLASS.EMPTY_OUTPUT]: 'agent produced no output \u2014 likely crashed on startup',
|
|
303
|
+
[FAILURE_CLASS.BUILD_FAILURE]: 'build/test/lint failure in output',
|
|
304
|
+
[FAILURE_CLASS.MERGE_CONFLICT]: 'merge conflict',
|
|
305
|
+
[FAILURE_CLASS.MAX_TURNS]: 'reached max turn limit',
|
|
306
|
+
[FAILURE_CLASS.TIMEOUT]: 'timed out waiting for agent',
|
|
307
|
+
[FAILURE_CLASS.SPAWN_ERROR]: 'agent process failed to start',
|
|
308
|
+
[FAILURE_CLASS.NETWORK_ERROR]: 'network or API error',
|
|
309
|
+
[FAILURE_CLASS.OUT_OF_CONTEXT]: 'context window exhausted',
|
|
310
|
+
[FAILURE_CLASS.CONFIG_ERROR]: 'configuration error',
|
|
311
|
+
[FAILURE_CLASS.PERMISSION_BLOCKED]: 'permission or auth failure',
|
|
312
|
+
[FAILURE_CLASS.UNKNOWN]: 'unknown error',
|
|
313
|
+
};
|
|
314
|
+
const classLabel = failureClass ? (CLASS_LABELS[failureClass] || failureClass) : '';
|
|
315
|
+
const effectiveReason = reason || classLabel || 'Unknown error';
|
|
316
|
+
const classSuffix = failureClass ? ` [${failureClass.toUpperCase().replace(/-/g, '_')}]` : '';
|
|
317
|
+
const finalReason = !retryableFailure
|
|
318
|
+
? `Non-retryable failure: ${effectiveReason}${classSuffix}`
|
|
319
|
+
: (reason || `Failed after ${maxRetries} retries${classSuffix}`);
|
|
320
|
+
lifecycle().updateWorkItemStatus(item.meta, WI_STATUS.FAILED, finalReason);
|
|
321
|
+
// Surface blocked dependents in logs without creating failure inbox noise.
|
|
322
|
+
try {
|
|
323
|
+
const config = getConfig();
|
|
324
|
+
const failedId = item.meta.item.id;
|
|
325
|
+
const blockedItems = [];
|
|
326
|
+
const allItems = queries.getWorkItems(config);
|
|
327
|
+
allItems.filter(w => w.status === WI_STATUS.PENDING && (w.depends_on || []).includes(failedId))
|
|
328
|
+
.forEach(w => blockedItems.push(`- \`${w.id}\` — ${w.title}`));
|
|
329
|
+
|
|
330
|
+
log('warn', `Work item ${failedId} failed: ${finalReason}` +
|
|
331
|
+
(blockedItems.length > 0 ? `; blocked dependents: ${blockedItems.map(line => line.replace(/^- `([^`]+)`.*/, '$1')).join(', ')}` : '; no downstream items blocked'));
|
|
332
|
+
} catch (e) { log('warn', 'summarize failure dependents: ' + e.message); }
|
|
333
|
+
}
|
|
305
334
|
}
|
|
306
335
|
}
|
|
307
336
|
|
package/engine/lifecycle.js
CHANGED
|
@@ -560,10 +560,18 @@ function updateWorkItemStatus(meta, status, reason) {
|
|
|
560
560
|
const wiPath = resolveWorkItemPath(meta);
|
|
561
561
|
if (!wiPath) return;
|
|
562
562
|
|
|
563
|
+
let completionGuarded = false;
|
|
563
564
|
mutateJsonFileLocked(wiPath, (items) => {
|
|
564
565
|
if (!items || !Array.isArray(items)) return items;
|
|
565
566
|
const target = items.find(i => i.id === itemId);
|
|
566
567
|
if (!target) return items;
|
|
568
|
+
if (status !== WI_STATUS.DONE && (
|
|
569
|
+
target.status === WI_STATUS.DONE ||
|
|
570
|
+
(!!target.completedAt && (!!target._pr || !!target._prUrl))
|
|
571
|
+
)) {
|
|
572
|
+
completionGuarded = true;
|
|
573
|
+
return items;
|
|
574
|
+
}
|
|
567
575
|
|
|
568
576
|
if (meta.source === 'central-work-item-fanout') {
|
|
569
577
|
if (!target.agentResults) target.agentResults = {};
|
|
@@ -609,6 +617,10 @@ function updateWorkItemStatus(meta, status, reason) {
|
|
|
609
617
|
return items;
|
|
610
618
|
}, { defaultValue: [], skipWriteIfUnchanged: true });
|
|
611
619
|
|
|
620
|
+
if (completionGuarded) {
|
|
621
|
+
log('info', `Work item ${itemId} already completed — ignoring ${status} status update`);
|
|
622
|
+
return;
|
|
623
|
+
}
|
|
612
624
|
log('info', `Work item ${itemId} → ${status}${reason ? ': ' + reason : ''}`);
|
|
613
625
|
syncPrdItemStatus(itemId, status, meta.item?.sourcePlan);
|
|
614
626
|
}
|
package/engine/playbook.js
CHANGED
|
@@ -278,6 +278,7 @@ const PLAYBOOK_REQUIRED_VARS = {
|
|
|
278
278
|
'decompose': ['item_id', 'item_description', 'project_path'],
|
|
279
279
|
'verify': ['task_description'],
|
|
280
280
|
'test': ['item_name'],
|
|
281
|
+
'docs': ['item_id', 'item_name'],
|
|
281
282
|
'work-item': ['item_id', 'item_name'],
|
|
282
283
|
'meeting-investigate': ['meeting_title', 'agenda'],
|
|
283
284
|
'meeting-debate': ['meeting_title', 'agenda'],
|
|
@@ -630,7 +631,7 @@ function selectPlaybook(workType, item) {
|
|
|
630
631
|
if (workType === WORK_TYPE.REVIEW && !item?._pr && !item?.pr_id) {
|
|
631
632
|
return 'work-item';
|
|
632
633
|
}
|
|
633
|
-
const typeSpecificPlaybooks = ['explore', 'review', 'test', 'plan-to-prd', 'plan', 'ask', 'verify', 'decompose', 'meeting-investigate', 'meeting-debate', 'meeting-conclude'];
|
|
634
|
+
const typeSpecificPlaybooks = ['explore', 'review', 'test', 'plan-to-prd', 'plan', 'ask', 'verify', 'decompose', 'docs', 'meeting-investigate', 'meeting-debate', 'meeting-conclude'];
|
|
634
635
|
return typeSpecificPlaybooks.includes(workType) ? workType : 'work-item';
|
|
635
636
|
}
|
|
636
637
|
|
package/engine.js
CHANGED
|
@@ -2411,6 +2411,7 @@ function discoverFromWorkItems(config, project) {
|
|
|
2411
2411
|
|
|
2412
2412
|
for (const item of items) {
|
|
2413
2413
|
try {
|
|
2414
|
+
if (isItemCompleted(item)) continue;
|
|
2414
2415
|
// Re-evaluate failed items: if deps have recovered, reset to pending
|
|
2415
2416
|
if (item.status === WI_STATUS.FAILED && !isItemCompleted(item) && item.failReason === 'Dependency failed — cannot proceed') {
|
|
2416
2417
|
const depStatus = areDependenciesMet(item, config);
|
|
@@ -2908,6 +2909,7 @@ function discoverCentralWorkItems(config) {
|
|
|
2908
2909
|
|
|
2909
2910
|
for (const item of items) {
|
|
2910
2911
|
try {
|
|
2912
|
+
if (isItemCompleted(item)) continue;
|
|
2911
2913
|
if (item.status !== WI_STATUS.QUEUED && item.status !== WI_STATUS.PENDING) continue;
|
|
2912
2914
|
|
|
2913
2915
|
const key = `central-work-${item.id}`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1634",
|
|
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"
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
# Docs Playbook
|
|
2
|
+
|
|
3
|
+
> Agent: {{agent_name}} ({{agent_role}}) | Task: {{item_name}} | ID: {{item_id}}
|
|
4
|
+
|
|
5
|
+
## Context
|
|
6
|
+
|
|
7
|
+
Repo: {{repo_name}} | Org: {{ado_org}} | Project: {{ado_project}}
|
|
8
|
+
Team root: {{team_root}}
|
|
9
|
+
Project path: {{project_path}}
|
|
10
|
+
|
|
11
|
+
## Mission
|
|
12
|
+
|
|
13
|
+
Update, expand, or rewrite project documentation. Targets include READMEs, CLAUDE.md,
|
|
14
|
+
files under `docs/`, JSDoc/TSDoc on exported APIs, and inline comments where they add
|
|
15
|
+
real WHY value (not WHAT — the code already says what). Keep voice consistent with the
|
|
16
|
+
project's existing docs.
|
|
17
|
+
|
|
18
|
+
## Task
|
|
19
|
+
|
|
20
|
+
**{{item_name}}**
|
|
21
|
+
|
|
22
|
+
{{item_description}}
|
|
23
|
+
|
|
24
|
+
{{additional_context}}
|
|
25
|
+
|
|
26
|
+
{{references}}
|
|
27
|
+
|
|
28
|
+
{{acceptance_criteria}}
|
|
29
|
+
|
|
30
|
+
## Steps
|
|
31
|
+
|
|
32
|
+
### 1. Read the doc(s) and the code they describe
|
|
33
|
+
|
|
34
|
+
- Open the doc(s) being changed end-to-end before writing.
|
|
35
|
+
- Read the source they describe — function signatures, exported symbols, config keys,
|
|
36
|
+
CLI flags, file paths. Don't trust the existing doc; trust the code.
|
|
37
|
+
- For project-level docs (README, CLAUDE.md, /docs/*.md), skim adjacent docs so your
|
|
38
|
+
voice and structure match.
|
|
39
|
+
|
|
40
|
+
### 2. Confirm doc reflects current code
|
|
41
|
+
|
|
42
|
+
For every claim in the doc you're touching, verify it against current code:
|
|
43
|
+
|
|
44
|
+
- Does the function still exist with that signature?
|
|
45
|
+
- Are the file paths correct?
|
|
46
|
+
- Are the listed flags / config keys still accepted?
|
|
47
|
+
- Are removed features still being documented?
|
|
48
|
+
- Are new features (visible in code) missing from the doc?
|
|
49
|
+
|
|
50
|
+
If the doc describes vapor, delete the section. If real features are missing, add them.
|
|
51
|
+
|
|
52
|
+
### 3. Write or update concisely
|
|
53
|
+
|
|
54
|
+
- Match the project's existing voice — read 2-3 nearby docs to calibrate tone.
|
|
55
|
+
- Prefer concrete examples over abstract description.
|
|
56
|
+
- For code comments: follow the project's "Default to writing no comments" rule
|
|
57
|
+
(CLAUDE.md). Add comments only where they explain WHY a non-obvious choice was made,
|
|
58
|
+
never to restate WHAT the code does.
|
|
59
|
+
- For project-level docs: the bar is "would a new contributor understand this?"
|
|
60
|
+
- Keep tables, lists, and code blocks formatted consistently with surrounding docs.
|
|
61
|
+
|
|
62
|
+
### 4. Verify
|
|
63
|
+
|
|
64
|
+
- Re-read the changed doc end-to-end after editing — does it still flow?
|
|
65
|
+
- If the project has doc-validation tests (lint, link-check, snippet-execution), run
|
|
66
|
+
them. Otherwise run `npm test` (or the project's documented test command) to make
|
|
67
|
+
sure nothing else broke.
|
|
68
|
+
- For docs with embedded code samples, mentally execute each sample against current
|
|
69
|
+
code — stale samples are worse than missing ones.
|
|
70
|
+
|
|
71
|
+
## Acceptance
|
|
72
|
+
|
|
73
|
+
- Doc accurately reflects current code (no vapor, no missing features).
|
|
74
|
+
- Voice and structure match the rest of the project's docs.
|
|
75
|
+
- For inline code comments: follow project conventions; add comments only where they
|
|
76
|
+
explain WHY, never WHAT.
|
|
77
|
+
- For project-level docs: a new contributor could read it and understand the topic.
|
|
78
|
+
- Existing tests still pass; any doc-validation tests pass.
|
|
79
|
+
|
|
80
|
+
## Git Workflow
|
|
81
|
+
|
|
82
|
+
You are already running in a git worktree on branch `{{branch_name}}`. Do NOT create
|
|
83
|
+
additional worktrees — the engine pre-created one for you. Do NOT remove the worktree —
|
|
84
|
+
the engine handles cleanup automatically.
|
|
85
|
+
|
|
86
|
+
Commit only the doc files (and any helper assets they reference). Do not bundle
|
|
87
|
+
unrelated code changes into a docs PR.
|
|
88
|
+
|
|
89
|
+
```bash
|
|
90
|
+
git add <doc files>
|
|
91
|
+
git commit -m "{{commit_message}}"
|
|
92
|
+
git push -u origin {{branch_name}}
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
PR creation is MANDATORY for docs tasks — docs go through the same review flow as code.
|
|
96
|
+
Use the appropriate repo-host tooling for PR creation. For Azure DevOps, prefer the
|
|
97
|
+
`az` CLI first and use the ADO MCP only as a fallback.
|
|
98
|
+
|
|
99
|
+
## Rules
|
|
100
|
+
|
|
101
|
+
- Do NOT modify product code unless the task explicitly asks for it.
|
|
102
|
+
- Do NOT add comments that restate what the code does.
|
|
103
|
+
- Do NOT invent features that don't exist; verify against current code.
|
|
104
|
+
- Read `notes.md` for all team rules before starting.
|
|
105
|
+
|
|
106
|
+
## When to Stop
|
|
107
|
+
|
|
108
|
+
Your task is complete once the doc accurately reflects current code, the PR is created
|
|
109
|
+
with the changed doc files, and any doc-validation tests pass. Do not continue editing
|
|
110
|
+
adjacent docs that weren't part of the task.
|
|
111
|
+
|
|
112
|
+
## Team Decisions
|
|
113
|
+
{{notes_content}}
|
package/playbooks/fix.md
CHANGED
|
@@ -25,33 +25,31 @@ Before starting work, run `git status` and verify the worktree is clean and on t
|
|
|
25
25
|
|
|
26
26
|
Use subagents only for genuinely parallel, independent tasks. For sequential work, single-file edits, searches, and file reads, work directly — do not spawn subagents.
|
|
27
27
|
|
|
28
|
-
##
|
|
28
|
+
## Delivery Contract
|
|
29
29
|
|
|
30
|
-
|
|
30
|
+
Handle this like the PR author responding directly from a CLI:
|
|
31
31
|
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
32
|
+
- You are already in the correct worktree on branch `{{pr_branch}}`. Do NOT create additional worktrees.
|
|
33
|
+
- For each review finding, use engineering judgment:
|
|
34
|
+
- Fix it if the feedback is valid and improves correctness, safety, maintainability, or test coverage.
|
|
35
|
+
- If the current approach is intentionally correct, reply with specific rationale instead of silently changing code or ignoring the thread.
|
|
36
|
+
- Handle merge conflicts when needed, preserving the PR's intended changes while keeping the branch reviewable.
|
|
37
|
+
- Do not add unrelated cleanups or broaden the PR beyond the review feedback unless that is necessary to make the fix correct.
|
|
35
38
|
|
|
36
|
-
|
|
37
|
-
- If `git pull` or the PR shows conflicts, resolve them in the worktree
|
|
38
|
-
- Prefer the PR branch changes, commit the resolution
|
|
39
|
+
## Validation
|
|
39
40
|
|
|
40
|
-
|
|
41
|
+
Before pushing, prove the review fix did not break the branch:
|
|
41
42
|
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
3. If any tests fail due to your changes, fix them before pushing.
|
|
47
|
-
4. If the build fails 3 times, report the errors in your PR comment and stop.
|
|
48
|
-
5. Do NOT push code that breaks existing tests or the build.
|
|
43
|
+
- Use the project's source of truth for commands: `CLAUDE.md`, README, package scripts, Makefile, or equivalent build config.
|
|
44
|
+
- Run checks that are relevant to the addressed findings. Prefer the full suite when practical.
|
|
45
|
+
- Fix regressions you introduced. If failures are pre-existing or unrelated, capture the evidence and include it in the PR comment.
|
|
46
|
+
- Do not push code that breaks existing tests or the build because of your changes.
|
|
49
47
|
|
|
50
48
|
> ⚠️ **Long builds (Gradle, MSBuild, dotnet, fresh `npm install`)**: any command that may stay silent for more than ~4 minutes will be killed by the heartbeat monitor. Run it via `Bash(run_in_background: true)` then `Monitor` to stream stdout, OR pass an explicit `timeout` (max 600000 ms). See **Long-Running Build / Test Commands** below for the full pattern.
|
|
51
49
|
|
|
52
|
-
##
|
|
50
|
+
## Publish & Comment on PR
|
|
53
51
|
|
|
54
|
-
|
|
52
|
+
After the fix is validated or any unavoidable limitation is clearly documented, commit only relevant files and push:
|
|
55
53
|
|
|
56
54
|
```bash
|
|
57
55
|
git add <specific files>
|
|
@@ -76,7 +74,7 @@ After pushing, respond to each review comment/thread:
|
|
|
76
74
|
|
|
77
75
|
## When to Stop
|
|
78
76
|
|
|
79
|
-
Your task is complete
|
|
77
|
+
Your task is complete when each review finding has either been fixed or answered with rationale, the validation story is truthful and sufficient for review, the fix is pushed if code changed, the PR is commented, and addressed threads are resolved. Do NOT continue into unrelated improvements.
|
|
80
78
|
|
|
81
79
|
**NEVER run `gh pr merge` or any merge command on this PR.** The engine handles merging after review approval. Self-merging bypasses the review cycle and is prohibited.
|
|
82
80
|
|
|
@@ -47,29 +47,30 @@ Before starting work, run `git status` and verify the worktree is clean and on t
|
|
|
47
47
|
|
|
48
48
|
Use subagents only for genuinely parallel, independent tasks. For sequential work, single-file edits, searches, and file reads, work directly — do not spawn subagents.
|
|
49
49
|
|
|
50
|
-
##
|
|
50
|
+
## Delivery Contract
|
|
51
51
|
|
|
52
|
-
|
|
53
|
-
2. Check what prior plan items already committed on this branch (`git log {{main_branch}}..HEAD`)
|
|
54
|
-
3. Follow existing patterns exactly — check `CLAUDE.md` for conventions
|
|
55
|
-
4. Build on existing work — don't duplicate or conflict with prior commits
|
|
52
|
+
Deliver this as if the user asked you directly in a CLI, with the added constraint that this branch may already contain related work:
|
|
56
53
|
|
|
57
|
-
|
|
54
|
+
- Understand the requested behavior and how prior commits on `{{branch_name}}` affect it.
|
|
55
|
+
- Read the smallest useful set of source, tests, docs, and comparable implementations needed to make the change correctly.
|
|
56
|
+
- Follow existing project conventions from `CLAUDE.md` and nearby code.
|
|
57
|
+
- Build on previous plan-item work instead of duplicating or conflicting with it.
|
|
58
|
+
- Make the complete change required by this item; do not add unrelated cleanups or speculative improvements.
|
|
58
59
|
|
|
59
|
-
|
|
60
|
+
## Validation
|
|
60
61
|
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
62
|
+
Before publishing, prove the shared branch still works with your change included:
|
|
63
|
+
|
|
64
|
+
- Use the project's source of truth for commands: `CLAUDE.md`, README, package scripts, Makefile, or equivalent build config.
|
|
65
|
+
- Run checks that are relevant to this item and to the integrated branch state. Prefer the full suite when practical.
|
|
66
|
+
- Fix regressions you introduced. If failures are pre-existing or caused by earlier branch work, capture the evidence and say so clearly.
|
|
67
|
+
- Do not push code with a broken build or failing tests that you introduced.
|
|
67
68
|
|
|
68
69
|
> ⚠️ **Long builds (Gradle, MSBuild, dotnet, fresh `npm install`)**: any command that may stay silent for more than ~4 minutes will be killed by the heartbeat monitor. Run it via `Bash(run_in_background: true)` then `Monitor` to stream stdout, OR pass an explicit `timeout` (max 600000 ms). See **Long-Running Build / Test Commands** below for the full pattern.
|
|
69
70
|
|
|
70
|
-
##
|
|
71
|
+
## Publish
|
|
71
72
|
|
|
72
|
-
|
|
73
|
+
After the change is validated or any unavoidable limitation is clearly documented, commit only the relevant files and push to the shared branch:
|
|
73
74
|
|
|
74
75
|
```bash
|
|
75
76
|
git add <specific files>
|
|
@@ -79,7 +80,7 @@ git push origin {{branch_name}}
|
|
|
79
80
|
|
|
80
81
|
## When to Stop
|
|
81
82
|
|
|
82
|
-
Your task is complete
|
|
83
|
+
Your task is complete when the requested implementation is delivered, the validation story is truthful and sufficient for review, and your commit is pushed to the shared branch. Do NOT create a PR — the engine creates one when all plan items are done.
|
|
83
84
|
|
|
84
85
|
## Completion
|
|
85
86
|
|
package/playbooks/implement.md
CHANGED
|
@@ -38,32 +38,35 @@ Before starting work, run `git status` and verify the worktree is clean and on t
|
|
|
38
38
|
|
|
39
39
|
Use subagents only for genuinely parallel, independent tasks (e.g., editing files in unrelated modules simultaneously). For sequential work, single-file edits, searches, and file reads, work directly — do not spawn subagents.
|
|
40
40
|
|
|
41
|
-
##
|
|
41
|
+
## Delivery Contract
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
43
|
+
Deliver this as if the user asked you directly in a CLI:
|
|
44
|
+
|
|
45
|
+
- Understand the requested behavior and relevant acceptance criteria before editing.
|
|
46
|
+
- Read the smallest useful set of source, tests, docs, and comparable implementations needed to make the change correctly.
|
|
47
|
+
- Follow existing project conventions, including logging, typing, error handling, and test structure.
|
|
48
|
+
- Make the complete change required by the task; do not add unrelated cleanups or speculative improvements.
|
|
49
|
+
- Keep working through failures you introduced until the implementation is either correct or honestly blocked with concrete evidence.
|
|
46
50
|
|
|
47
51
|
## Git Workflow
|
|
48
52
|
|
|
49
53
|
You are already running in a git worktree on branch `{{branch_name}}`. Do NOT create additional worktrees — the engine pre-created one for you.
|
|
50
54
|
Do NOT remove the worktree — the engine handles cleanup automatically.
|
|
51
55
|
|
|
52
|
-
##
|
|
56
|
+
## Validation
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
Before publishing, prove the change with the repo's own documented checks:
|
|
55
59
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
5. Do NOT push code with a broken build or failing tests that you introduced.
|
|
60
|
+
- Use the project's source of truth for commands: `CLAUDE.md`, README, package scripts, Makefile, or equivalent build config.
|
|
61
|
+
- Run the checks that are relevant to this task, including tests that cover the changed behavior. Prefer the full suite when practical.
|
|
62
|
+
- Fix regressions you introduced. If failures are pre-existing or outside the task, capture the evidence and make that explicit in the PR.
|
|
63
|
+
- Do not publish changes with a broken build or failing tests that you introduced.
|
|
61
64
|
|
|
62
65
|
> ⚠️ **Long builds (Gradle, MSBuild, dotnet, fresh `npm install`)**: any command that may stay silent for more than ~4 minutes will be killed by the heartbeat monitor. Run it via `Bash(run_in_background: true)` then `Monitor` to stream stdout, OR pass an explicit `timeout` (max 600000 ms). See **Long-Running Build / Test Commands** below for the full pattern.
|
|
63
66
|
|
|
64
|
-
##
|
|
67
|
+
## Publish
|
|
65
68
|
|
|
66
|
-
|
|
69
|
+
After the change is validated or any unavoidable limitation is clearly documented, commit only the relevant files and push this branch:
|
|
67
70
|
|
|
68
71
|
```bash
|
|
69
72
|
git add <specific files>
|
|
@@ -73,10 +76,12 @@ git push -u origin {{branch_name}}
|
|
|
73
76
|
|
|
74
77
|
{{pr_section}}
|
|
75
78
|
|
|
79
|
+
PR creation is MANDATORY for implement tasks because the engine tracks review and completion from the PR.
|
|
80
|
+
|
|
76
81
|
Include build/test status and run instructions in the PR description. If the project has a runnable app, include the localhost URL.
|
|
77
82
|
|
|
78
83
|
## When to Stop
|
|
79
84
|
|
|
80
|
-
Your task is complete
|
|
85
|
+
Your task is complete when the requested implementation is delivered, the validation story is truthful and sufficient for review, the branch is pushed, and the PR exists. Your final message MUST include the PR URL so the engine can track it.
|
|
81
86
|
|
|
82
87
|
Do NOT run `gh pr merge` or any other merge command on your own PR. The engine reviews and merges PRs through a separate review cycle. Self-merging is prohibited.
|
|
@@ -17,6 +17,17 @@ Codex will review your changes — make sure your implementation is thorough and
|
|
|
17
17
|
|
|
18
18
|
Your context window may be compacted or summarized mid-task by Claude's automatic context management. This is normal and expected for long-running tasks. Do NOT interpret compacted or truncated context as a signal to stop early, wrap up prematurely, or skip remaining work. Continue working toward your stated objective regardless of context window state — re-read key files if needed to recover context.
|
|
19
19
|
|
|
20
|
+
## Delegated Task Contract
|
|
21
|
+
|
|
22
|
+
Treat a Minions assignment like the user typed the same task directly into a capable CLI agent. Preserve the user's actual task contract first; the playbook adds orchestration guardrails, not a rigid script for thinking or implementation.
|
|
23
|
+
|
|
24
|
+
- Optimize for the requested outcome, not for mechanically completing checklist steps.
|
|
25
|
+
- Use judgment to choose the smallest reliable workflow that fully satisfies the task.
|
|
26
|
+
- Read only the context needed to make correct decisions; do not perform broad archaeology unless the task requires it.
|
|
27
|
+
- Validate with the repo's own documented commands and acceptance criteria. If full validation is impossible or pre-existing failures block it, explain that precisely instead of inventing a green result.
|
|
28
|
+
- Prefer direct work over ceremony. Branches, PRs, inbox notes, completion blocks, and status comments exist for traceability; they should not change what "done" means for the user.
|
|
29
|
+
- Safety and observability rules still win: stay in the engine-created worktree, do not self-merge, do not edit engine-managed status files, do not hide failures, and leave enough evidence for the human and engine to track the result.
|
|
30
|
+
|
|
20
31
|
## Engine Rules (apply to all tasks)
|
|
21
32
|
|
|
22
33
|
**Context compaction:** Your context window may be compacted mid-task by Claude's infrastructure. If you notice your earlier conversation history appears truncated or summarized, this is normal and expected. Do not interpret compaction as a signal to stop early or wrap up. Continue working toward your task objective — all relevant instructions and state remain available.
|
package/playbooks/work-item.md
CHANGED
|
@@ -20,28 +20,31 @@ Team root: {{team_root}}
|
|
|
20
20
|
Branch format: `feat/{{item_id}}-<short-description>`
|
|
21
21
|
Keep branch names lowercase, use hyphens, max 60 chars.
|
|
22
22
|
|
|
23
|
-
##
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
23
|
+
## Delivery Contract
|
|
24
|
+
|
|
25
|
+
Treat this like the user typed the task directly into a CLI agent:
|
|
26
|
+
|
|
27
|
+
- Work in the correct project directory: `{{project_path}}`.
|
|
28
|
+
- You are already in a worktree on branch `{{branch_name}}`. Do NOT create additional worktrees.
|
|
29
|
+
- Understand the requested outcome, inspect the relevant source/tests/docs, and make the complete change needed.
|
|
30
|
+
- Follow existing repo conventions and avoid unrelated cleanups.
|
|
31
|
+
- Validate with the repo's documented build/test/check commands. Fix regressions you introduced; if failures are pre-existing or outside the task, document the evidence.
|
|
32
|
+
- Do NOT publish code with a broken build or failing tests that you introduced.
|
|
33
|
+
|
|
34
|
+
After the change is ready for review, commit only relevant files, push `{{branch_name}}`, create the PR, and post implementation notes with the validation result:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
git add <specific files>
|
|
38
|
+
git commit -m "feat({{item_id}}): <description>"
|
|
39
|
+
git push -u origin {{branch_name}}
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
{{pr_create_instructions}}
|
|
43
|
+
- sourceRefName: `refs/heads/feat/{{item_id}}-<short-desc>`
|
|
44
|
+
- targetRefName: `refs/heads/{{main_branch}}`
|
|
45
|
+
- title: `feat({{item_id}}): <description>`
|
|
46
|
+
|
|
47
|
+
{{pr_comment_instructions}}
|
|
45
48
|
|
|
46
49
|
Do NOT remove the worktree — the engine handles cleanup automatically.
|
|
47
50
|
|
|
@@ -59,6 +62,6 @@ If you encounter merge conflicts during push or PR creation:
|
|
|
59
62
|
|
|
60
63
|
## When to Stop
|
|
61
64
|
|
|
62
|
-
Your task is complete
|
|
65
|
+
Your task is complete when the requested work item is delivered, the validation story is truthful and sufficient for review, the branch is pushed, and the PR exists. Do NOT continue into unrelated improvements.
|
|
63
66
|
|
|
64
67
|
Do NOT run `gh pr merge` or any other merge command on your own PR. The engine reviews and merges PRs through a separate review cycle. Self-merging is prohibited.
|
package/prompts/cc-system.md
CHANGED
|
@@ -77,6 +77,8 @@ Core action types:
|
|
|
77
77
|
workTypes: `explore` (research/report only, NO PR), `ask` (answer/report, NO PR), `implement` (new code, PR REQUIRED), `fix` (bug fix, PR REQUIRED), `review` (code review, NO PR), `test` (tests, PR if new), `verify` (merge/build/maintenance, NO PR)
|
|
78
78
|
If the user wants a design/architecture artifact committed through a PR, dispatch `implement` or `docs` rather than `explore`.
|
|
79
79
|
When the user names a specific agent ("assign this to lambert"), put exactly that one name in `agents` (e.g. `"agents": ["lambert"]`). A single-agent assignment is hard-pinned by the server — it will queue for that agent only and skip the routing table. Use multi-agent arrays only when the user names multiple agents or asks for fan-out.
|
|
80
|
+
- **build-and-test**: pr, project (optional), agent (optional) — Run the build-and-test playbook against a PR. The agent will checkout the PR branch, run the project's build/test commands, and report results. Use when the user asks to "run tests on PR X" or "build PR X" or after a fix to verify nothing regressed.
|
|
81
|
+
Example: user says "run build and test on PR 1834" → `{"type":"build-and-test","pr":"1834"}`
|
|
80
82
|
- **note**: title, content — save to inbox
|
|
81
83
|
- **knowledge**: title, content, category (architecture/conventions/project-notes/build-reports/reviews) — create new KB entry or copy existing doc to KB
|
|
82
84
|
- **pin-to-pinned**: title, content, level (critical/warning) — write to pinned.md, force-injected into ALL agent prompts (rarely needed)
|
package/routing.md
CHANGED
|
@@ -25,6 +25,7 @@ Notes:
|
|
|
25
25
|
- `_any_` means route to any available idle agent (lowest error rate first)
|
|
26
26
|
- `implement:large` is for items with `estimated_complexity: "large"`
|
|
27
27
|
- Engine falls back to any idle agent if both preferred and fallback are busy
|
|
28
|
+
- Routing selects an owner; it should not narrow the user's task contract. The assigned agent should behave like the user typed the same task directly into a CLI, with Minions adding only safety, status, and review guardrails.
|
|
28
29
|
|
|
29
30
|
## Rules
|
|
30
31
|
|