monomind 1.17.0 → 1.17.1
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/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/.claude/commands/mastermind/_repeat.md +4 -0
- package/.claude/commands/mastermind/master.md +52 -1
- package/.claude/scheduled_tasks.lock +1 -1
- package/.claude/skills/mastermind/_repeat.md +2 -0
- package/package.json +1 -1
- package/packages/@monomind/cli/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +4 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/master.md +52 -1
- package/packages/@monomind/cli/.claude/skills/mastermind/_repeat.md +2 -0
- package/packages/@monomind/cli/dist/src/__tests__/browse-analyzer.test.js +42 -59
- package/packages/@monomind/cli/dist/src/browser/dashboard/server.js +18 -0
- package/packages/@monomind/cli/dist/src/browser/dashboard/ui.html +37 -125
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.d.ts +17 -0
- package/packages/@monomind/cli/dist/src/commands/agent-lifecycle.js +320 -0
- package/packages/@monomind/cli/dist/src/commands/agent-ops.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/agent-ops.js +329 -0
- package/packages/@monomind/cli/dist/src/commands/agent.js +5 -907
- package/packages/@monomind/cli/dist/src/commands/analyze-ast.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-ast.js +284 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-boundaries.js +295 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-diff.js +395 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-graph.js +304 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-imports.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-imports.js +287 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-symbols.d.ts +14 -0
- package/packages/@monomind/cli/dist/src/commands/analyze-symbols.js +302 -0
- package/packages/@monomind/cli/dist/src/commands/analyze.d.ts +38 -0
- package/packages/@monomind/cli/dist/src/commands/analyze.js +12 -1827
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.d.ts +26 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-env-checks.js +189 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.d.ts +19 -0
- package/packages/@monomind/cli/dist/src/commands/doctor-project-checks.js +388 -0
- package/packages/@monomind/cli/dist/src/commands/doctor.js +51 -942
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.d.ts +11 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-comms.js +242 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.d.ts +35 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-helpers.js +203 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-ops.js +233 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.d.ts +12 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind-spawn.js +274 -0
- package/packages/@monomind/cli/dist/src/commands/hive-mind.js +10 -1129
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.d.ts +4 -4
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-commands.js +19 -819
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-gaps.js +334 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/hooks-coverage-routing.js +399 -0
- package/packages/@monomind/cli/dist/src/commands/init-subcommands.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/init-subcommands.js +156 -0
- package/packages/@monomind/cli/dist/src/commands/init-upgrade.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/init-upgrade.js +203 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/init-wizard.js +246 -0
- package/packages/@monomind/cli/dist/src/commands/init.js +6 -623
- package/packages/@monomind/cli/dist/src/commands/memory-admin.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/memory-admin.js +433 -0
- package/packages/@monomind/cli/dist/src/commands/memory-crud.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/memory-crud.js +342 -0
- package/packages/@monomind/cli/dist/src/commands/memory-list.d.ts +10 -0
- package/packages/@monomind/cli/dist/src/commands/memory-list.js +321 -0
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/memory-transfer.js +372 -0
- package/packages/@monomind/cli/dist/src/commands/memory.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/memory.js +10 -1441
- package/packages/@monomind/cli/dist/src/commands/neural-core.d.ts +8 -0
- package/packages/@monomind/cli/dist/src/commands/neural-core.js +274 -0
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/neural-optimize.js +332 -0
- package/packages/@monomind/cli/dist/src/commands/neural-registry.d.ts +7 -0
- package/packages/@monomind/cli/dist/src/commands/neural-registry.js +290 -0
- package/packages/@monomind/cli/dist/src/commands/neural.js +3 -974
- package/packages/@monomind/cli/dist/src/commands/platforms.js +327 -7
- package/packages/@monomind/cli/dist/src/commands/security-cve.d.ts +6 -0
- package/packages/@monomind/cli/dist/src/commands/security-cve.js +310 -0
- package/packages/@monomind/cli/dist/src/commands/security-misc.d.ts +9 -0
- package/packages/@monomind/cli/dist/src/commands/security-misc.js +293 -0
- package/packages/@monomind/cli/dist/src/commands/security-scan.d.ts +18 -0
- package/packages/@monomind/cli/dist/src/commands/security-scan.js +328 -0
- package/packages/@monomind/cli/dist/src/commands/security.js +3 -958
- package/packages/@monomind/cli/dist/src/commands/session.js +1 -1
- package/packages/@monomind/cli/dist/src/commands/swarm.js +23 -17
- package/packages/@monomind/cli/dist/src/mcp-tools/swarm-tools.js +77 -0
- package/packages/@monomind/cli/dist/src/parser.js +11 -6
- package/packages/@monomind/cli/dist/src/routing/llm-caller.js +1 -2
- package/packages/@monomind/cli/package.json +2 -3
- package/packages/@monomind/cli/scripts/understand-analyze.mjs +1 -1
|
@@ -420,8 +420,9 @@ body { background: #0b0b14; color: #ccc; font-family: system-ui,-apple-system,sa
|
|
|
420
420
|
<!-- ── top bar ─────────────────────────────────────── -->
|
|
421
421
|
<div id="topbar">
|
|
422
422
|
<span class="logo">monomind <span>dashboard</span></span>
|
|
423
|
-
<span class="pill pill-run" id="p-
|
|
424
|
-
<span class="pill pill-done" id="p-
|
|
423
|
+
<span class="pill pill-run" id="p-run">● 0</span>
|
|
424
|
+
<span class="pill pill-done" id="p-done">✓ 0</span>
|
|
425
|
+
<span class="pill pill-fail" id="p-fail">✗ 0</span>
|
|
425
426
|
<span id="conn">
|
|
426
427
|
<span id="conn-dot"></span>
|
|
427
428
|
<span id="conn-label">connecting…</span>
|
|
@@ -434,9 +435,12 @@ body { background: #0b0b14; color: #ccc; font-family: system-ui,-apple-system,sa
|
|
|
434
435
|
<!-- sidebar -->
|
|
435
436
|
<nav id="sidebar">
|
|
436
437
|
<div class="nav-section-label">Project</div>
|
|
437
|
-
<div class="nav-item active" data-panel="
|
|
438
|
-
<span class="nav-icon"
|
|
439
|
-
<span class="nav-badge
|
|
438
|
+
<div class="nav-item active" data-panel="playbooks">
|
|
439
|
+
<span class="nav-icon">⚡</span> Runs
|
|
440
|
+
<span class="nav-badge" id="nb-run">0</span>
|
|
441
|
+
</div>
|
|
442
|
+
<div class="nav-item" data-panel="builder">
|
|
443
|
+
<span class="nav-icon">🔧</span> Builder
|
|
440
444
|
</div>
|
|
441
445
|
|
|
442
446
|
<div class="nav-section-label" style="margin-top:8px">System</div>
|
|
@@ -454,38 +458,21 @@ body { background: #0b0b14; color: #ccc; font-family: system-ui,-apple-system,sa
|
|
|
454
458
|
<!-- main -->
|
|
455
459
|
<div id="main">
|
|
456
460
|
|
|
457
|
-
<!--
|
|
458
|
-
<div class="panel active" id="
|
|
461
|
+
<!-- Playbook Runs panel -->
|
|
462
|
+
<div class="panel active" id="pb-panel">
|
|
459
463
|
<div class="panel-header">
|
|
460
|
-
<span class="panel-title">
|
|
461
|
-
<span class="panel-subtitle" id="
|
|
462
|
-
<button onclick="loadMonoagentData()" style="margin-left:auto;background:#1a1a2e;border:1px solid #2a2a4a;color:#a78bfa;padding:3px 10px;border-radius:6px;cursor:pointer;font-size:11px">↻ Refresh</button>
|
|
464
|
+
<span class="panel-title">Playbook Runs</span>
|
|
465
|
+
<span class="panel-subtitle" id="pb-subtitle">0 runs</span>
|
|
463
466
|
</div>
|
|
464
|
-
<div style="
|
|
465
|
-
|
|
466
|
-
<
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
<div class="empty" id="ma-wf-empty" style="display:none">
|
|
470
|
-
<span class="empty-icon">🤖</span>
|
|
471
|
-
<span class="empty-title">No workflows found</span>
|
|
472
|
-
<span class="empty-sub">Create one with: <code style="color:#7c3aed">monoagent workflow create</code></span>
|
|
473
|
-
</div>
|
|
474
|
-
</div>
|
|
475
|
-
<!-- Action run history -->
|
|
476
|
-
<div>
|
|
477
|
-
<div style="font-size:10px;font-weight:700;text-transform:uppercase;letter-spacing:1px;color:#3a3a5a;margin-bottom:8px">Action History</div>
|
|
478
|
-
<div id="ma-history" style="display:grid;gap:6px;align-content:start"></div>
|
|
479
|
-
<div class="empty" id="ma-hist-empty" style="display:none">
|
|
480
|
-
<span class="empty-icon">📋</span>
|
|
481
|
-
<span class="empty-title">No action history</span>
|
|
482
|
-
<span class="empty-sub">Run an action with: <code style="color:#7c3aed">monoagent run <ACTION_ID></code></span>
|
|
483
|
-
</div>
|
|
484
|
-
</div>
|
|
467
|
+
<div id="pb-cards" style="overflow-y:auto;flex:1;padding:12px;display:grid;gap:10px;align-content:start"></div>
|
|
468
|
+
<div class="empty" id="pb-empty">
|
|
469
|
+
<span class="empty-icon">⚡</span>
|
|
470
|
+
<span class="empty-title">No playbook runs yet</span>
|
|
471
|
+
<span class="empty-sub">Use the Builder tab to create and run playbooks,<br>or run via CLI: <code style="color:#7c3aed">npx monomind browse playbook run <name></code></span>
|
|
485
472
|
</div>
|
|
486
473
|
</div>
|
|
487
474
|
|
|
488
|
-
<!-- Builder panel
|
|
475
|
+
<!-- Builder panel -->
|
|
489
476
|
<div class="panel" id="builder-panel">
|
|
490
477
|
<!-- Toolbar -->
|
|
491
478
|
<div id="builder-toolbar">
|
|
@@ -586,11 +573,12 @@ function navigateToPanel(target) {
|
|
|
586
573
|
var navItem = document.querySelector('[data-panel="' + target + '"]');
|
|
587
574
|
if (navItem) navItem.classList.add('active');
|
|
588
575
|
document.querySelectorAll('.panel').forEach(function(p) { p.classList.remove('active'); });
|
|
589
|
-
var panelId = target
|
|
576
|
+
var panelId = target === 'playbooks' ? 'pb-panel'
|
|
577
|
+
: target === 'builder' ? 'builder-panel'
|
|
578
|
+
: target + '-panel';
|
|
590
579
|
var panel = document.getElementById(panelId);
|
|
591
580
|
if (panel) panel.classList.add('active');
|
|
592
581
|
if (target === 'builder') renderEdges();
|
|
593
|
-
if (target === 'monoagent') loadMonoagentData();
|
|
594
582
|
location.hash = target;
|
|
595
583
|
}
|
|
596
584
|
|
|
@@ -604,7 +592,7 @@ document.querySelectorAll('.nav-item').forEach(function(item) {
|
|
|
604
592
|
// Hash-based routing on load
|
|
605
593
|
(function() {
|
|
606
594
|
var hash = location.hash.replace('#', '');
|
|
607
|
-
var validPanels = ['
|
|
595
|
+
var validPanels = ['playbooks', 'builder', 'agents', 'memory', 'sessions'];
|
|
608
596
|
if (hash && validPanels.indexOf(hash) !== -1) {
|
|
609
597
|
// defer until after renderEdges is defined
|
|
610
598
|
window.addEventListener('load', function() { navigateToPanel(hash); });
|
|
@@ -625,7 +613,20 @@ function esc(s) {
|
|
|
625
613
|
}
|
|
626
614
|
|
|
627
615
|
function updateHeader() {
|
|
628
|
-
|
|
616
|
+
var running = 0, done = 0, fail = 0;
|
|
617
|
+
for (var id in runs) {
|
|
618
|
+
var s = runs[id].status;
|
|
619
|
+
if (s === 'running') running++;
|
|
620
|
+
else if (s === 'completed') done++;
|
|
621
|
+
else if (s === 'failed') fail++;
|
|
622
|
+
}
|
|
623
|
+
document.getElementById('p-run').textContent = '● ' + running;
|
|
624
|
+
document.getElementById('p-done').textContent = '✓ ' + done;
|
|
625
|
+
document.getElementById('p-fail').textContent = '✗ ' + fail;
|
|
626
|
+
document.getElementById('nb-run').textContent = String(running || Object.keys(runs).length);
|
|
627
|
+
document.getElementById('nb-run').className = 'nav-badge' + (running ? '' : ' green');
|
|
628
|
+
var total = Object.keys(runs).length;
|
|
629
|
+
document.getElementById('pb-subtitle').textContent = total + (total === 1 ? ' run' : ' runs');
|
|
629
630
|
}
|
|
630
631
|
|
|
631
632
|
function progressPct(r) {
|
|
@@ -647,7 +648,6 @@ function elapsed(r) {
|
|
|
647
648
|
function renderCards() {
|
|
648
649
|
var cards = document.getElementById('pb-cards');
|
|
649
650
|
var empty = document.getElementById('pb-empty');
|
|
650
|
-
if (!cards) return; // panel removed from DOM
|
|
651
651
|
var sorted = Object.values(runs).sort(function(a, b) { return b.startedAt - a.startedAt; });
|
|
652
652
|
if (!sorted.length) { cards.innerHTML = ''; empty.style.display = 'flex'; return; }
|
|
653
653
|
empty.style.display = 'none';
|
|
@@ -1737,94 +1737,6 @@ function handleEvent(evt) {
|
|
|
1737
1737
|
renderCards();
|
|
1738
1738
|
}
|
|
1739
1739
|
|
|
1740
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
1741
|
-
// MONOAGENT DATA
|
|
1742
|
-
// ═══════════════════════════════════════════════════════════════════
|
|
1743
|
-
var MA_STATE_COLORS = { COMPLETED: '#22c55e', FAILED: '#ef4444', PENDING: '#f59e0b', RUNNING: '#a78bfa' };
|
|
1744
|
-
|
|
1745
|
-
function maStateLabel(state) {
|
|
1746
|
-
var s = (state || '').toUpperCase();
|
|
1747
|
-
return { color: MA_STATE_COLORS[s] || '#555', text: s || 'UNKNOWN' };
|
|
1748
|
-
}
|
|
1749
|
-
|
|
1750
|
-
function renderWorkflows(workflows) {
|
|
1751
|
-
var el = document.getElementById('ma-workflows');
|
|
1752
|
-
var empty = document.getElementById('ma-wf-empty');
|
|
1753
|
-
if (!workflows || !workflows.length) {
|
|
1754
|
-
el.innerHTML = '';
|
|
1755
|
-
empty.style.display = 'flex';
|
|
1756
|
-
return;
|
|
1757
|
-
}
|
|
1758
|
-
empty.style.display = 'none';
|
|
1759
|
-
el.innerHTML = workflows.map(function(wf) {
|
|
1760
|
-
var active = wf.is_active;
|
|
1761
|
-
var updated = wf.updated_at && wf.updated_at !== '0001-01-01T00:00:00Z'
|
|
1762
|
-
? new Date(wf.updated_at).toLocaleDateString()
|
|
1763
|
-
: '—';
|
|
1764
|
-
return '<div style="background:#0f0f1e;border:1px solid #1a1a2e;border-radius:8px;padding:10px 14px;display:flex;align-items:center;gap:10px">' +
|
|
1765
|
-
'<span style="font-size:16px">' + (active ? '▶' : '⏸') + '</span>' +
|
|
1766
|
-
'<div style="flex:1;min-width:0">' +
|
|
1767
|
-
'<div style="font-weight:600;font-size:12px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis">' + esc(wf.name || wf.id) + '</div>' +
|
|
1768
|
-
'<div style="font-size:10px;color:#3a3a5a;margin-top:2px">' + esc(wf.id) + ' · v' + (wf.version || 1) + ' · updated ' + esc(updated) + '</div>' +
|
|
1769
|
-
(wf.description ? '<div style="font-size:10px;color:#555;margin-top:2px">' + esc(wf.description) + '</div>' : '') +
|
|
1770
|
-
'</div>' +
|
|
1771
|
-
'<span style="font-size:10px;padding:2px 7px;border-radius:10px;border:1px solid;' +
|
|
1772
|
-
(active ? 'background:#22c55e15;border-color:#22c55e44;color:#22c55e' : 'background:#33333315;border-color:#33333344;color:#555') + '">' +
|
|
1773
|
-
(active ? 'active' : 'inactive') +
|
|
1774
|
-
'</span>' +
|
|
1775
|
-
'</div>';
|
|
1776
|
-
}).join('');
|
|
1777
|
-
document.getElementById('nb-ma').textContent = String(workflows.length);
|
|
1778
|
-
}
|
|
1779
|
-
|
|
1780
|
-
function renderHistory(actions) {
|
|
1781
|
-
var el = document.getElementById('ma-history');
|
|
1782
|
-
var empty = document.getElementById('ma-hist-empty');
|
|
1783
|
-
if (!actions || !actions.length) {
|
|
1784
|
-
el.innerHTML = '';
|
|
1785
|
-
empty.style.display = 'flex';
|
|
1786
|
-
return;
|
|
1787
|
-
}
|
|
1788
|
-
empty.style.display = 'none';
|
|
1789
|
-
el.innerHTML = actions.map(function(a) {
|
|
1790
|
-
var sl = maStateLabel(a.state);
|
|
1791
|
-
var dt = a.created_at
|
|
1792
|
-
? new Date(typeof a.created_at === 'number' ? a.created_at * 1000 : a.created_at).toLocaleString()
|
|
1793
|
-
: '—';
|
|
1794
|
-
return '<div style="background:#0f0f1e;border:1px solid #1a1a2e;border-radius:6px;padding:8px 12px;display:flex;align-items:center;gap:10px">' +
|
|
1795
|
-
'<div style="flex:1;min-width:0">' +
|
|
1796
|
-
'<div style="font-weight:600;font-size:11px">' + esc(a.type || '(unnamed)') + '</div>' +
|
|
1797
|
-
'<div style="font-size:10px;color:#3a3a5a;margin-top:2px">' +
|
|
1798
|
-
esc(a.id.slice(0, 8)) + '… · ' + esc(a.platform || '') + ' · ' + esc(dt) +
|
|
1799
|
-
'</div>' +
|
|
1800
|
-
'</div>' +
|
|
1801
|
-
'<span style="font-size:10px;font-weight:600;color:' + sl.color + '">' + sl.text + '</span>' +
|
|
1802
|
-
'</div>';
|
|
1803
|
-
}).join('');
|
|
1804
|
-
}
|
|
1805
|
-
|
|
1806
|
-
function loadMonoagentData() {
|
|
1807
|
-
document.getElementById('ma-subtitle').textContent = 'loading…';
|
|
1808
|
-
fetch('/monoagent/data')
|
|
1809
|
-
.then(function(r) { return r.json(); })
|
|
1810
|
-
.then(function(d) {
|
|
1811
|
-
renderWorkflows(d.workflows || []);
|
|
1812
|
-
renderHistory(d.actions || []);
|
|
1813
|
-
var wc = (d.workflows || []).length;
|
|
1814
|
-
var ac = (d.actions || []).length;
|
|
1815
|
-
document.getElementById('ma-subtitle').textContent = wc + ' workflow' + (wc !== 1 ? 's' : '') + ' · ' + ac + ' action' + (ac !== 1 ? 's' : '');
|
|
1816
|
-
document.getElementById('p-workflows').textContent = '⚡ ' + wc;
|
|
1817
|
-
document.getElementById('p-actions').textContent = '✓ ' + ac;
|
|
1818
|
-
})
|
|
1819
|
-
.catch(function(e) {
|
|
1820
|
-
document.getElementById('ma-subtitle').textContent = 'error loading data';
|
|
1821
|
-
console.error('monoagent data fetch failed', e);
|
|
1822
|
-
});
|
|
1823
|
-
}
|
|
1824
|
-
|
|
1825
|
-
// Load monoagent data on startup (it's the default panel)
|
|
1826
|
-
loadMonoagentData();
|
|
1827
|
-
|
|
1828
1740
|
// ═══════════════════════════════════════════════════════════════════
|
|
1829
1741
|
// CONNECTION
|
|
1830
1742
|
// ═══════════════════════════════════════════════════════════════════
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent lifecycle commands — spawn, list, status, stop
|
|
3
|
+
*/
|
|
4
|
+
import type { Command } from '../types.js';
|
|
5
|
+
export declare function updateSwarmActivityMetrics(agentCountDelta: number): void;
|
|
6
|
+
export declare const AGENT_TYPES: {
|
|
7
|
+
value: string;
|
|
8
|
+
label: string;
|
|
9
|
+
hint: string;
|
|
10
|
+
}[];
|
|
11
|
+
export declare function getAgentCapabilities(type: string): string[];
|
|
12
|
+
export declare function formatStatus(status: unknown): string;
|
|
13
|
+
export declare const spawnCommand: Command;
|
|
14
|
+
export declare const listCommand: Command;
|
|
15
|
+
export declare const statusCommand: Command;
|
|
16
|
+
export declare const stopCommand: Command;
|
|
17
|
+
//# sourceMappingURL=agent-lifecycle.d.ts.map
|
|
@@ -0,0 +1,320 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent lifecycle commands — spawn, list, status, stop
|
|
3
|
+
*/
|
|
4
|
+
import { output } from '../output.js';
|
|
5
|
+
import { select, confirm, input } from '../prompt.js';
|
|
6
|
+
import { callMCPTool, MCPClientError } from '../mcp-client.js';
|
|
7
|
+
import * as fs from 'fs';
|
|
8
|
+
import * as path from 'path';
|
|
9
|
+
// ─── Shared utilities ────────────────────────────────────────────────────────
|
|
10
|
+
export function updateSwarmActivityMetrics(agentCountDelta) {
|
|
11
|
+
try {
|
|
12
|
+
const metricsDir = path.join(process.cwd(), '.monomind', 'metrics');
|
|
13
|
+
const activityPath = path.join(metricsDir, 'swarm-activity.json');
|
|
14
|
+
let data = {
|
|
15
|
+
timestamp: new Date().toISOString(),
|
|
16
|
+
swarm: { active: false, agent_count: 0, coordination_active: false },
|
|
17
|
+
};
|
|
18
|
+
if (fs.existsSync(activityPath) && fs.statSync(activityPath).size <= 10 * 1024 * 1024) {
|
|
19
|
+
data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
|
|
20
|
+
}
|
|
21
|
+
else {
|
|
22
|
+
fs.mkdirSync(metricsDir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
const swarm = data.swarm ?? {};
|
|
25
|
+
const currentCount = Math.max(0, swarm.agent_count || 0);
|
|
26
|
+
const newCount = Math.max(0, currentCount + agentCountDelta);
|
|
27
|
+
swarm.agent_count = newCount;
|
|
28
|
+
swarm.active = newCount > 0;
|
|
29
|
+
swarm.coordination_active = newCount > 0;
|
|
30
|
+
data.swarm = swarm;
|
|
31
|
+
data.timestamp = new Date().toISOString();
|
|
32
|
+
const tmpPath = activityPath + '.tmp';
|
|
33
|
+
fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
|
|
34
|
+
fs.renameSync(tmpPath, activityPath);
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
// Non-critical — don't fail the command if metrics update fails
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
export const AGENT_TYPES = [
|
|
41
|
+
{ value: 'coder', label: 'Coder', hint: 'Code development with neural patterns' },
|
|
42
|
+
{ value: 'researcher', label: 'Researcher', hint: 'Research with web access and data analysis' },
|
|
43
|
+
{ value: 'tester', label: 'Tester', hint: 'Comprehensive testing with automation' },
|
|
44
|
+
{ value: 'reviewer', label: 'Reviewer', hint: 'Code review with security and quality checks' },
|
|
45
|
+
{ value: 'architect', label: 'Architect', hint: 'System design with enterprise patterns' },
|
|
46
|
+
{ value: 'coordinator', label: 'Coordinator', hint: 'Multi-agent orchestration and workflow' },
|
|
47
|
+
{ value: 'analyst', label: 'Analyst', hint: 'Performance analysis and optimization' },
|
|
48
|
+
{ value: 'optimizer', label: 'Optimizer', hint: 'Performance optimization and bottleneck analysis' },
|
|
49
|
+
{ value: 'security-architect', label: 'Security Architect', hint: 'Security architecture and threat modeling' },
|
|
50
|
+
{ value: 'security-auditor', label: 'Security Auditor', hint: 'CVE remediation and security testing' },
|
|
51
|
+
{ value: 'memory-specialist', label: 'Memory Specialist', hint: 'LanceDB ANN search (150x-12,500x faster)' },
|
|
52
|
+
{ value: 'swarm-specialist', label: 'Swarm Specialist', hint: 'Unified coordination engine' },
|
|
53
|
+
{ value: 'performance-engineer', label: 'Performance Engineer', hint: '2.49x-7.47x optimization targets' },
|
|
54
|
+
{ value: 'core-architect', label: 'Core Architect', hint: 'Domain-driven design restructure' },
|
|
55
|
+
{ value: 'test-architect', label: 'Test Architect', hint: 'TDD London School methodology' },
|
|
56
|
+
];
|
|
57
|
+
export function getAgentCapabilities(type) {
|
|
58
|
+
const capabilities = {
|
|
59
|
+
coder: ['code-generation', 'refactoring', 'debugging', 'testing'],
|
|
60
|
+
researcher: ['web-search', 'data-analysis', 'summarization', 'citation'],
|
|
61
|
+
tester: ['unit-testing', 'integration-testing', 'coverage-analysis', 'automation'],
|
|
62
|
+
reviewer: ['code-review', 'security-audit', 'quality-check', 'documentation'],
|
|
63
|
+
architect: ['system-design', 'pattern-analysis', 'scalability', 'documentation'],
|
|
64
|
+
coordinator: ['task-orchestration', 'agent-management', 'workflow-control'],
|
|
65
|
+
'security-architect': ['threat-modeling', 'security-patterns', 'compliance', 'audit'],
|
|
66
|
+
'memory-specialist': ['vector-search', 'lancedb', 'caching', 'optimization'],
|
|
67
|
+
'performance-engineer': ['benchmarking', 'profiling', 'optimization', 'monitoring'],
|
|
68
|
+
};
|
|
69
|
+
return capabilities[type] || ['general'];
|
|
70
|
+
}
|
|
71
|
+
export function formatStatus(status) {
|
|
72
|
+
const s = String(status);
|
|
73
|
+
switch (s) {
|
|
74
|
+
case 'active': return output.success(s);
|
|
75
|
+
case 'idle': return output.warning(s);
|
|
76
|
+
case 'inactive':
|
|
77
|
+
case 'stopped': return output.dim(s);
|
|
78
|
+
case 'error': return output.error(s);
|
|
79
|
+
default: return s;
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
// ─── spawn subcommand ────────────────────────────────────────────────────────
|
|
83
|
+
export const spawnCommand = {
|
|
84
|
+
name: 'spawn',
|
|
85
|
+
description: 'Spawn a new agent',
|
|
86
|
+
options: [
|
|
87
|
+
{ name: 'type', short: 't', description: 'Agent type to spawn', type: 'string', choices: AGENT_TYPES.map(a => a.value) },
|
|
88
|
+
{ name: 'name', short: 'n', description: 'Agent name/identifier', type: 'string' },
|
|
89
|
+
{ name: 'provider', short: 'p', description: 'Provider to use (anthropic, openrouter, ollama)', type: 'string', default: 'anthropic' },
|
|
90
|
+
{ name: 'model', short: 'm', description: 'Model to use', type: 'string' },
|
|
91
|
+
{ name: 'task', description: 'Initial task for the agent', type: 'string' },
|
|
92
|
+
{ name: 'timeout', description: 'Agent timeout in seconds', type: 'number', default: 300 },
|
|
93
|
+
{ name: 'auto-tools', description: 'Enable automatic tool usage', type: 'boolean', default: true },
|
|
94
|
+
],
|
|
95
|
+
examples: [
|
|
96
|
+
{ command: 'monomind agent spawn --type coder --name bot-1', description: 'Spawn a coder agent' },
|
|
97
|
+
{ command: 'monomind agent spawn -t researcher --task "Research React 19"', description: 'Spawn researcher with task' },
|
|
98
|
+
],
|
|
99
|
+
action: async (ctx) => {
|
|
100
|
+
let agentType = ctx.flags.type?.slice(0, 64) ?? '';
|
|
101
|
+
let agentName = ctx.flags.name?.slice(0, 128) ?? '';
|
|
102
|
+
if (!agentType && ctx.interactive) {
|
|
103
|
+
agentType = await select({ message: 'Select agent type:', options: AGENT_TYPES });
|
|
104
|
+
}
|
|
105
|
+
const taskDescription = ctx.flags.task?.slice(0, 2048);
|
|
106
|
+
if (!agentType && taskDescription) {
|
|
107
|
+
try {
|
|
108
|
+
const { createConfiguredRouteLayer } = await import('../routing/route-layer-factory.js');
|
|
109
|
+
const layer = await createConfiguredRouteLayer();
|
|
110
|
+
const routeResult = await layer.route(taskDescription);
|
|
111
|
+
agentType = routeResult.agentSlug;
|
|
112
|
+
process.stderr.write(`[route] ${routeResult.method}: "${agentType}" (confidence: ${(routeResult.confidence * 100).toFixed(1)}%)\n`);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
// RouteLayer unavailable — fall through to error below
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (!agentType) {
|
|
119
|
+
output.printError('Agent type is required. Use --type or -t flag, or provide --task for auto-routing.');
|
|
120
|
+
return { success: false, exitCode: 1 };
|
|
121
|
+
}
|
|
122
|
+
if (!agentName)
|
|
123
|
+
agentName = `${agentType}-${Date.now().toString(36)}`;
|
|
124
|
+
output.printInfo(`Spawning ${agentType} agent: ${output.highlight(agentName)}`);
|
|
125
|
+
try {
|
|
126
|
+
const result = await callMCPTool('agent_spawn', {
|
|
127
|
+
agentType, id: agentName,
|
|
128
|
+
config: {
|
|
129
|
+
provider: ctx.flags.provider || 'anthropic',
|
|
130
|
+
model: ctx.flags.model,
|
|
131
|
+
task: ctx.flags.task,
|
|
132
|
+
timeout: ctx.flags.timeout,
|
|
133
|
+
autoTools: ctx.flags['auto-tools'],
|
|
134
|
+
},
|
|
135
|
+
priority: 'normal',
|
|
136
|
+
metadata: { name: agentName, capabilities: getAgentCapabilities(agentType) },
|
|
137
|
+
});
|
|
138
|
+
output.writeln();
|
|
139
|
+
output.printTable({
|
|
140
|
+
columns: [
|
|
141
|
+
{ key: 'property', header: 'Property', width: 15 },
|
|
142
|
+
{ key: 'value', header: 'Value', width: 40 },
|
|
143
|
+
],
|
|
144
|
+
data: [
|
|
145
|
+
{ property: 'ID', value: result.agentId },
|
|
146
|
+
{ property: 'Type', value: result.agentType },
|
|
147
|
+
{ property: 'Name', value: agentName },
|
|
148
|
+
{ property: 'Status', value: result.status },
|
|
149
|
+
{ property: 'Created', value: result.createdAt },
|
|
150
|
+
{ property: 'Capabilities', value: getAgentCapabilities(agentType).join(', ') },
|
|
151
|
+
],
|
|
152
|
+
});
|
|
153
|
+
output.writeln();
|
|
154
|
+
output.printSuccess(`Agent ${agentName} spawned successfully`);
|
|
155
|
+
updateSwarmActivityMetrics(1);
|
|
156
|
+
if (ctx.flags.format === 'json')
|
|
157
|
+
output.printJson(result);
|
|
158
|
+
return { success: true, data: result };
|
|
159
|
+
}
|
|
160
|
+
catch (error) {
|
|
161
|
+
output.printError(error instanceof MCPClientError ? `Failed to spawn agent: ${error.message}` : `Unexpected error: ${String(error)}`);
|
|
162
|
+
return { success: false, exitCode: 1 };
|
|
163
|
+
}
|
|
164
|
+
},
|
|
165
|
+
};
|
|
166
|
+
// ─── list subcommand ─────────────────────────────────────────────────────────
|
|
167
|
+
export const listCommand = {
|
|
168
|
+
name: 'list',
|
|
169
|
+
aliases: ['ls'],
|
|
170
|
+
description: 'List all active agents',
|
|
171
|
+
options: [
|
|
172
|
+
{ name: 'all', short: 'a', description: 'Include inactive agents', type: 'boolean', default: false },
|
|
173
|
+
{ name: 'type', short: 't', description: 'Filter by agent type', type: 'string' },
|
|
174
|
+
{ name: 'status', short: 's', description: 'Filter by status', type: 'string' },
|
|
175
|
+
],
|
|
176
|
+
action: async (ctx) => {
|
|
177
|
+
try {
|
|
178
|
+
const result = await callMCPTool('agent_list', {
|
|
179
|
+
status: ctx.flags.all ? 'all' : ctx.flags.status || undefined,
|
|
180
|
+
agentType: ctx.flags.type || undefined,
|
|
181
|
+
limit: 100,
|
|
182
|
+
});
|
|
183
|
+
if (ctx.flags.format === 'json') {
|
|
184
|
+
output.printJson(result);
|
|
185
|
+
return { success: true, data: result };
|
|
186
|
+
}
|
|
187
|
+
output.writeln();
|
|
188
|
+
output.writeln(output.bold('Active Agents'));
|
|
189
|
+
output.writeln();
|
|
190
|
+
if (result.agents.length === 0) {
|
|
191
|
+
output.printInfo('No agents found matching criteria');
|
|
192
|
+
return { success: true, data: result };
|
|
193
|
+
}
|
|
194
|
+
const displayAgents = result.agents.map(agent => ({
|
|
195
|
+
id: agent.id,
|
|
196
|
+
type: agent.agentType,
|
|
197
|
+
status: agent.status,
|
|
198
|
+
created: new Date(agent.createdAt).toLocaleTimeString(),
|
|
199
|
+
lastActivity: agent.lastActivityAt ? new Date(agent.lastActivityAt).toLocaleTimeString() : 'N/A',
|
|
200
|
+
}));
|
|
201
|
+
output.printTable({
|
|
202
|
+
columns: [
|
|
203
|
+
{ key: 'id', header: 'ID', width: 20 },
|
|
204
|
+
{ key: 'type', header: 'Type', width: 15 },
|
|
205
|
+
{ key: 'status', header: 'Status', width: 12, format: formatStatus },
|
|
206
|
+
{ key: 'created', header: 'Created', width: 12 },
|
|
207
|
+
{ key: 'lastActivity', header: 'Last Activity', width: 12 },
|
|
208
|
+
],
|
|
209
|
+
data: displayAgents,
|
|
210
|
+
});
|
|
211
|
+
output.writeln();
|
|
212
|
+
output.printInfo(`Total: ${result.total} agents`);
|
|
213
|
+
return { success: true, data: result };
|
|
214
|
+
}
|
|
215
|
+
catch (error) {
|
|
216
|
+
output.printError(error instanceof MCPClientError ? `Failed to list agents: ${error.message}` : `Unexpected error: ${String(error)}`);
|
|
217
|
+
return { success: false, exitCode: 1 };
|
|
218
|
+
}
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
// ─── status subcommand ───────────────────────────────────────────────────────
|
|
222
|
+
export const statusCommand = {
|
|
223
|
+
name: 'status',
|
|
224
|
+
description: 'Show detailed status of an agent',
|
|
225
|
+
options: [{ name: 'id', description: 'Agent ID', type: 'string' }],
|
|
226
|
+
action: async (ctx) => {
|
|
227
|
+
let agentId = ctx.args[0] || ctx.flags.id;
|
|
228
|
+
if (!agentId && ctx.interactive) {
|
|
229
|
+
agentId = await input({ message: 'Enter agent ID:', validate: (v) => v.length > 0 || 'Agent ID is required' });
|
|
230
|
+
}
|
|
231
|
+
if (!agentId) {
|
|
232
|
+
output.printError('Agent ID is required');
|
|
233
|
+
return { success: false, exitCode: 1 };
|
|
234
|
+
}
|
|
235
|
+
try {
|
|
236
|
+
const status = await callMCPTool('agent_status', { agentId, includeMetrics: true, includeHistory: false });
|
|
237
|
+
if (ctx.flags.format === 'json') {
|
|
238
|
+
output.printJson(status);
|
|
239
|
+
return { success: true, data: status };
|
|
240
|
+
}
|
|
241
|
+
output.writeln();
|
|
242
|
+
output.printBox([
|
|
243
|
+
`Type: ${status.agentType}`,
|
|
244
|
+
`Status: ${formatStatus(status.status)}`,
|
|
245
|
+
`Created: ${new Date(status.createdAt).toLocaleString()}`,
|
|
246
|
+
`Last Activity: ${status.lastActivityAt ? new Date(status.lastActivityAt).toLocaleString() : 'N/A'}`,
|
|
247
|
+
].join('\n'), `Agent: ${status.id}`);
|
|
248
|
+
if (status.metrics) {
|
|
249
|
+
output.writeln();
|
|
250
|
+
output.writeln(output.bold('Metrics'));
|
|
251
|
+
const avgExecTime = status.metrics.averageExecutionTime ?? 0;
|
|
252
|
+
const uptime = status.metrics.uptime ?? 0;
|
|
253
|
+
output.printTable({
|
|
254
|
+
columns: [
|
|
255
|
+
{ key: 'metric', header: 'Metric', width: 25 },
|
|
256
|
+
{ key: 'value', header: 'Value', width: 15, align: 'right' },
|
|
257
|
+
],
|
|
258
|
+
data: [
|
|
259
|
+
{ metric: 'Tasks Completed', value: status.metrics.tasksCompleted ?? 0 },
|
|
260
|
+
{ metric: 'Tasks In Progress', value: status.metrics.tasksInProgress ?? 0 },
|
|
261
|
+
{ metric: 'Tasks Failed', value: status.metrics.tasksFailed ?? 0 },
|
|
262
|
+
{ metric: 'Avg Execution Time', value: `${avgExecTime.toFixed(2)}ms` },
|
|
263
|
+
{ metric: 'Uptime', value: `${(uptime / 1000 / 60).toFixed(1)}m` },
|
|
264
|
+
],
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return { success: true, data: status };
|
|
268
|
+
}
|
|
269
|
+
catch (error) {
|
|
270
|
+
output.printError(error instanceof MCPClientError ? `Failed to get agent status: ${error.message}` : `Unexpected error: ${String(error)}`);
|
|
271
|
+
return { success: false, exitCode: 1 };
|
|
272
|
+
}
|
|
273
|
+
},
|
|
274
|
+
};
|
|
275
|
+
// ─── stop subcommand ─────────────────────────────────────────────────────────
|
|
276
|
+
export const stopCommand = {
|
|
277
|
+
name: 'stop',
|
|
278
|
+
aliases: ['kill'],
|
|
279
|
+
description: 'Stop a running agent',
|
|
280
|
+
options: [
|
|
281
|
+
{ name: 'force', short: 'f', description: 'Force stop without graceful shutdown', type: 'boolean', default: false },
|
|
282
|
+
{ name: 'timeout', description: 'Graceful shutdown timeout in seconds', type: 'number', default: 30 },
|
|
283
|
+
],
|
|
284
|
+
action: async (ctx) => {
|
|
285
|
+
const agentId = ctx.args[0];
|
|
286
|
+
if (!agentId) {
|
|
287
|
+
output.printError('Agent ID is required');
|
|
288
|
+
return { success: false, exitCode: 1 };
|
|
289
|
+
}
|
|
290
|
+
const force = ctx.flags.force;
|
|
291
|
+
if (!force && ctx.interactive) {
|
|
292
|
+
const confirmed = await confirm({ message: `Are you sure you want to stop agent ${agentId}?`, default: false });
|
|
293
|
+
if (!confirmed) {
|
|
294
|
+
output.printInfo('Operation cancelled');
|
|
295
|
+
return { success: true };
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
output.printInfo(`Stopping agent ${agentId}...`);
|
|
299
|
+
try {
|
|
300
|
+
const result = await callMCPTool('agent_terminate', {
|
|
301
|
+
agentId, graceful: !force, reason: 'Stopped by user via CLI',
|
|
302
|
+
});
|
|
303
|
+
if (!force) {
|
|
304
|
+
output.writeln(output.dim(' Completing current task...'));
|
|
305
|
+
output.writeln(output.dim(' Saving state...'));
|
|
306
|
+
output.writeln(output.dim(' Releasing resources...'));
|
|
307
|
+
}
|
|
308
|
+
output.printSuccess(`Agent ${agentId} stopped successfully`);
|
|
309
|
+
updateSwarmActivityMetrics(-1);
|
|
310
|
+
if (ctx.flags.format === 'json')
|
|
311
|
+
output.printJson(result);
|
|
312
|
+
return { success: true, data: result };
|
|
313
|
+
}
|
|
314
|
+
catch (error) {
|
|
315
|
+
output.printError(error instanceof MCPClientError ? `Failed to stop agent: ${error.message}` : `Unexpected error: ${String(error)}`);
|
|
316
|
+
return { success: false, exitCode: 1 };
|
|
317
|
+
}
|
|
318
|
+
},
|
|
319
|
+
};
|
|
320
|
+
//# sourceMappingURL=agent-lifecycle.js.map
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent operational commands — metrics, pool, health, logs
|
|
3
|
+
*/
|
|
4
|
+
import type { Command } from '../types.js';
|
|
5
|
+
export declare const metricsCommand: Command;
|
|
6
|
+
export declare const poolCommand: Command;
|
|
7
|
+
export declare const healthCommand: Command;
|
|
8
|
+
export declare const logsCommand: Command;
|
|
9
|
+
//# sourceMappingURL=agent-ops.d.ts.map
|