@yemi33/minions 0.1.1608 → 0.1.1610
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/command-center.js +7 -1
- package/dashboard.js +12 -3
- package/minions.js +40 -0
- package/package.json +1 -1
- package/prompts/cc-system.md +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
-
## 0.1.
|
|
3
|
+
## 0.1.1610 (2026-04-28)
|
|
4
4
|
|
|
5
5
|
### Features
|
|
6
|
+
- hard-pin agent assignment when CC names a specific agent
|
|
7
|
+
- auto-detect available CLI runtimes and pin engine.defaultCli
|
|
6
8
|
- match runtime tags to actual logos (pixel-crab Claude, mascot Copilot)
|
|
7
9
|
- replace runtime text tag with inline SVG logos
|
|
8
10
|
|
|
@@ -807,10 +807,16 @@ async function ccExecuteAction(action, targetTabId) {
|
|
|
807
807
|
case 'review':
|
|
808
808
|
case 'test': {
|
|
809
809
|
var workType = action.workType || (action.type !== 'dispatch' ? action.type : 'implement');
|
|
810
|
+
// Forward both singular (`agent`) and plural (`agents`) hint shapes —
|
|
811
|
+
// the LLM emits either depending on phrasing ("assign to lambert" vs
|
|
812
|
+
// "dispatch to dallas, ralph"). The server-side handler promotes a
|
|
813
|
+
// single explicit agent to a hard pin so routing doesn't reassign it.
|
|
810
814
|
var res = await _ccFetch('/api/work-items', {
|
|
811
815
|
title: action.title, type: workType,
|
|
812
816
|
priority: action.priority || 'medium', description: action.description || '',
|
|
813
|
-
project: action.project || '',
|
|
817
|
+
project: action.project || '',
|
|
818
|
+
agent: action.agent || '',
|
|
819
|
+
agents: action.agents || [],
|
|
814
820
|
});
|
|
815
821
|
var d = await res.json();
|
|
816
822
|
status.innerHTML = '✓ Dispatched: <strong>' + escHtml(d.id || action.title) + '</strong>';
|
package/dashboard.js
CHANGED
|
@@ -1004,7 +1004,7 @@ async function executeCCActions(actions) {
|
|
|
1004
1004
|
priority: action.priority || 'medium', description: action.description || '',
|
|
1005
1005
|
status: WI_STATUS.PENDING, created: new Date().toISOString(),
|
|
1006
1006
|
createdBy: 'command-center', project,
|
|
1007
|
-
...(action.agents?.length ? { preferred_agent: action.agents[0] } : {}),
|
|
1007
|
+
...(action.agents?.length ? { preferred_agent: action.agents[0], agents: action.agents } : {}),
|
|
1008
1008
|
...(isOneShot ? { oneShot: true } : {}),
|
|
1009
1009
|
});
|
|
1010
1010
|
return items;
|
|
@@ -2207,8 +2207,17 @@ const server = http.createServer(async (req, res) => {
|
|
|
2207
2207
|
status: WI_STATUS.PENDING, created: new Date().toISOString(), createdBy: 'dashboard',
|
|
2208
2208
|
};
|
|
2209
2209
|
if (body.scope) item.scope = body.scope;
|
|
2210
|
-
|
|
2211
|
-
|
|
2210
|
+
// Agent assignment normalization: when the caller (CC, dashboard form,
|
|
2211
|
+
// direct API) supplies a single explicit agent — either via `agent`
|
|
2212
|
+
// (singular) or a one-element `agents` array — treat it as a HARD pin
|
|
2213
|
+
// by setting `item.agent`. The engine reads `item.agent || resolveAgent(…)`,
|
|
2214
|
+
// so a hard-pinned item bypasses routing entirely and queues until that
|
|
2215
|
+
// exact agent is free. Multi-agent arrays remain `item.agents` (hints
|
|
2216
|
+
// for resolveAgent or fan-out scope).
|
|
2217
|
+
const _agentsArr = Array.isArray(body.agents) ? body.agents.filter(Boolean) : (typeof body.agents === 'string' && body.agents ? [body.agents] : []);
|
|
2218
|
+
if (body.agent) item.agent = String(body.agent);
|
|
2219
|
+
else if (_agentsArr.length === 1 && body.scope !== 'fan-out') item.agent = String(_agentsArr[0]);
|
|
2220
|
+
if (_agentsArr.length > 0) item.agents = _agentsArr;
|
|
2212
2221
|
if (body.references) item.references = body.references;
|
|
2213
2222
|
if (body.acceptanceCriteria) item.acceptanceCriteria = body.acceptanceCriteria;
|
|
2214
2223
|
if (body.skipPr) item.skipPr = true;
|
package/minions.js
CHANGED
|
@@ -125,6 +125,30 @@ function autoDiscover(targetDir) {
|
|
|
125
125
|
|
|
126
126
|
// ─── Shared Helpers (used by both addProject and scanAndAdd) ─────────────────
|
|
127
127
|
|
|
128
|
+
/**
|
|
129
|
+
* Probe each registered runtime adapter and return the names whose
|
|
130
|
+
* resolveBinary() returns a non-null result. Used by initMinions to set
|
|
131
|
+
* engine.defaultCli automatically. Adapter `resolveBinary()` returns `null`
|
|
132
|
+
* when the CLI binary isn't on PATH and otherwise returns `{ bin, ... }`.
|
|
133
|
+
* Errors (unregistered runtime, exec failures) are swallowed — the helper
|
|
134
|
+
* is best-effort and a missing CLI just means we don't pin defaultCli.
|
|
135
|
+
*/
|
|
136
|
+
function _detectAvailableRuntimes() {
|
|
137
|
+
const found = [];
|
|
138
|
+
let registry;
|
|
139
|
+
try { registry = require('./engine/runtimes'); }
|
|
140
|
+
catch { return found; }
|
|
141
|
+
for (const name of registry.listRuntimes()) {
|
|
142
|
+
try {
|
|
143
|
+
const adapter = registry.resolveRuntime(name);
|
|
144
|
+
if (typeof adapter.resolveBinary !== 'function') continue;
|
|
145
|
+
const result = adapter.resolveBinary({ env: process.env });
|
|
146
|
+
if (result && result.bin) found.push(name);
|
|
147
|
+
} catch { /* probe failed → treat as unavailable */ }
|
|
148
|
+
}
|
|
149
|
+
return found;
|
|
150
|
+
}
|
|
151
|
+
|
|
128
152
|
function buildPrUrlBase({ repoHost, org, project, repoName }) {
|
|
129
153
|
if (repoHost === 'github') {
|
|
130
154
|
return org && repoName ? `https://github.com/${org}/${repoName}/pull/` : '';
|
|
@@ -450,6 +474,22 @@ async function initMinions({ skipScan = false, scanRoot, scanDepth } = {}) {
|
|
|
450
474
|
if (!config.agents || Object.keys(config.agents).length === 0) {
|
|
451
475
|
config.agents = { ...DEFAULT_AGENTS };
|
|
452
476
|
}
|
|
477
|
+
|
|
478
|
+
// Auto-detect available runtime CLIs and pin engine.defaultCli to whichever
|
|
479
|
+
// is installed. Only set if the user hasn't already configured one — never
|
|
480
|
+
// overwrite an explicit choice on `init --force` upgrades.
|
|
481
|
+
if (!config.engine.defaultCli) {
|
|
482
|
+
const detected = _detectAvailableRuntimes();
|
|
483
|
+
if (detected.length === 1) {
|
|
484
|
+
config.engine.defaultCli = detected[0];
|
|
485
|
+
console.log(`\n ✓ Detected ${detected[0]} CLI — set as fleet default runtime`);
|
|
486
|
+
} else if (detected.length > 1) {
|
|
487
|
+
// Both available — prefer claude (the historical default and broader skill coverage)
|
|
488
|
+
config.engine.defaultCli = detected.includes('claude') ? 'claude' : detected[0];
|
|
489
|
+
console.log(`\n ✓ Detected ${detected.join(' + ')} — fleet default set to ${config.engine.defaultCli}`);
|
|
490
|
+
}
|
|
491
|
+
// If nothing detected, leave defaultCli unset (engine falls back to 'claude')
|
|
492
|
+
}
|
|
453
493
|
saveConfig(config);
|
|
454
494
|
console.log(`\n Minions initialized at ${MINIONS_HOME}`);
|
|
455
495
|
console.log(` Config, agents, and engine defaults created.\n`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yemi33/minions",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.1610",
|
|
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"
|
package/prompts/cc-system.md
CHANGED
|
@@ -63,6 +63,7 @@ I'll dispatch dallas to fix that bug.
|
|
|
63
63
|
Core action types:
|
|
64
64
|
- **dispatch**: title, workType, priority (low/medium/high), agents[] (optional), project, description
|
|
65
65
|
workTypes: `explore` (research, 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)
|
|
66
|
+
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.
|
|
66
67
|
- **note**: title, content — save to inbox
|
|
67
68
|
- **knowledge**: title, content, category (architecture/conventions/project-notes/build-reports/reviews) — create new KB entry or copy existing doc to KB
|
|
68
69
|
- **pin-to-pinned**: title, content, level (critical/warning) — write to pinned.md, force-injected into ALL agent prompts (rarely needed)
|