monomind 1.16.11 → 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/agents/github/code-review-swarm.md +19 -19
- package/.claude/agents/github/github-modes.md +4 -4
- package/.claude/agents/github/multi-repo-swarm.md +24 -24
- package/.claude/agents/github/project-board-sync.md +28 -28
- package/.claude/agents/github/swarm-issue.md +26 -26
- package/.claude/agents/github/swarm-pr.md +18 -18
- package/.claude/agents/github/workflow-automation.md +27 -27
- package/.claude/agents/reengineer-squad/git-manager.md +2 -2
- package/.claude/commands/mastermind/_repeat.md +4 -0
- package/.claude/commands/mastermind/master.md +61 -4
- package/.claude/commands/mastermind/references/antigravity-tools.md +60 -0
- package/.claude/commands/mastermind/references/claude-code-tools.md +50 -0
- package/.claude/commands/mastermind/references/codex-tools.md +64 -0
- package/.claude/commands/mastermind/references/copilot-tools.md +49 -0
- package/.claude/commands/mastermind/references/gemini-tools.md +63 -0
- package/.claude/commands/mastermind/references/pi-tools.md +28 -0
- package/.claude/helpers/mastermind-activate.cjs +53 -0
- package/.claude/scheduled_tasks.lock +1 -1
- package/.claude/settings.json +4 -0
- package/.claude/skills/mastermind/_repeat.md +2 -0
- package/.claude/skills/mastermind/runorg.md +14 -0
- package/.claude/skills/mastermind/techport.md +5 -5
- package/README.md +1 -1
- package/package.json +6 -5
- package/packages/@monomind/cli/.claude/agents/engineering/engineering-security-engineer.md +1 -1
- package/packages/@monomind/cli/.claude/agents/github/code-review-swarm.md +19 -19
- package/packages/@monomind/cli/.claude/agents/github/github-modes.md +4 -4
- package/packages/@monomind/cli/.claude/agents/github/multi-repo-swarm.md +24 -24
- package/packages/@monomind/cli/.claude/agents/github/project-board-sync.md +28 -28
- package/packages/@monomind/cli/.claude/agents/github/swarm-issue.md +26 -26
- package/packages/@monomind/cli/.claude/agents/github/swarm-pr.md +18 -18
- package/packages/@monomind/cli/.claude/agents/github/workflow-automation.md +27 -27
- package/packages/@monomind/cli/.claude/agents/reengineer-squad/git-manager.md +2 -2
- package/packages/@monomind/cli/.claude/commands/mastermind/_repeat.md +4 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/master.md +61 -4
- package/packages/@monomind/cli/.claude/commands/mastermind/references/antigravity-tools.md +60 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/references/claude-code-tools.md +50 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/references/codex-tools.md +64 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/references/copilot-tools.md +49 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/references/gemini-tools.md +63 -0
- package/packages/@monomind/cli/.claude/commands/mastermind/references/pi-tools.md +28 -0
- package/packages/@monomind/cli/.claude/helpers/mastermind-activate.cjs +53 -0
- package/packages/@monomind/cli/.claude/skills/mastermind/_repeat.md +2 -0
- package/packages/@monomind/cli/.claude/skills/mastermind/runorg.md +14 -0
- package/packages/@monomind/cli/.claude/skills/mastermind/techport.md +5 -5
- package/packages/@monomind/cli/README.md +1 -1
- 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/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/index.js +0 -2
- 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/init/executor.js +0 -24
- package/packages/@monomind/cli/dist/src/init/statusline-generator.js +0 -45
- package/packages/@monomind/cli/dist/src/init/types.d.ts +0 -2
- package/packages/@monomind/cli/dist/src/init/types.js +0 -2
- 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/dist/src/ui/dashboard.html +82 -75
- package/packages/@monomind/cli/dist/src/ui/server.mjs +41 -4
- package/packages/@monomind/cli/package.json +3 -4
- package/packages/@monomind/cli/scripts/understand-analyze.mjs +1 -1
- package/packages/@monomind/guidance/README.md +0 -1
- package/packages/@monomind/guidance/package.json +2 -14
- package/scripts/verify-appliance.sh +16 -20
- package/.claude-plugin/README.md +0 -704
- package/.claude-plugin/docs/INSTALLATION.md +0 -258
- package/.claude-plugin/docs/PLUGIN_SUMMARY.md +0 -358
- package/.claude-plugin/docs/QUICKSTART.md +0 -357
- package/.claude-plugin/docs/STRUCTURE.md +0 -122
- package/.claude-plugin/hooks/hooks.json +0 -74
- package/.claude-plugin/marketplace.json +0 -98
- package/.claude-plugin/plugin.json +0 -70
- package/.claude-plugin/scripts/install.sh +0 -234
- package/.claude-plugin/scripts/uninstall.sh +0 -36
- package/.claude-plugin/scripts/verify.sh +0 -102
|
@@ -3,878 +3,8 @@
|
|
|
3
3
|
* Agent management commands for spawning, listing, and controlling agents
|
|
4
4
|
*/
|
|
5
5
|
import { output } from '../output.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import * as fs from 'fs';
|
|
9
|
-
import * as path from 'path';
|
|
10
|
-
/**
|
|
11
|
-
* Update swarm-activity.json metrics after agent count changes.
|
|
12
|
-
* The statusline reads this file to display the swarm agent count.
|
|
13
|
-
*/
|
|
14
|
-
function updateSwarmActivityMetrics(agentCountDelta) {
|
|
15
|
-
try {
|
|
16
|
-
const metricsDir = path.join(process.cwd(), '.monomind', 'metrics');
|
|
17
|
-
const activityPath = path.join(metricsDir, 'swarm-activity.json');
|
|
18
|
-
let data = {
|
|
19
|
-
timestamp: new Date().toISOString(),
|
|
20
|
-
swarm: { active: false, agent_count: 0, coordination_active: false },
|
|
21
|
-
};
|
|
22
|
-
if (fs.existsSync(activityPath) && fs.statSync(activityPath).size <= 10 * 1024 * 1024) {
|
|
23
|
-
data = JSON.parse(fs.readFileSync(activityPath, 'utf-8'));
|
|
24
|
-
}
|
|
25
|
-
else {
|
|
26
|
-
fs.mkdirSync(metricsDir, { recursive: true });
|
|
27
|
-
}
|
|
28
|
-
const swarm = data.swarm ?? {};
|
|
29
|
-
const currentCount = Math.max(0, swarm.agent_count || 0);
|
|
30
|
-
const newCount = Math.max(0, currentCount + agentCountDelta);
|
|
31
|
-
swarm.agent_count = newCount;
|
|
32
|
-
swarm.active = newCount > 0;
|
|
33
|
-
swarm.coordination_active = newCount > 0;
|
|
34
|
-
data.swarm = swarm;
|
|
35
|
-
data.timestamp = new Date().toISOString();
|
|
36
|
-
const tmpPath = activityPath + '.tmp';
|
|
37
|
-
fs.writeFileSync(tmpPath, JSON.stringify(data, null, 2));
|
|
38
|
-
fs.renameSync(tmpPath, activityPath);
|
|
39
|
-
}
|
|
40
|
-
catch {
|
|
41
|
-
// Non-critical — don't fail the command if metrics update fails
|
|
42
|
-
}
|
|
43
|
-
}
|
|
44
|
-
// Available agent types with descriptions
|
|
45
|
-
const AGENT_TYPES = [
|
|
46
|
-
{ value: 'coder', label: 'Coder', hint: 'Code development with neural patterns' },
|
|
47
|
-
{ value: 'researcher', label: 'Researcher', hint: 'Research with web access and data analysis' },
|
|
48
|
-
{ value: 'tester', label: 'Tester', hint: 'Comprehensive testing with automation' },
|
|
49
|
-
{ value: 'reviewer', label: 'Reviewer', hint: 'Code review with security and quality checks' },
|
|
50
|
-
{ value: 'architect', label: 'Architect', hint: 'System design with enterprise patterns' },
|
|
51
|
-
{ value: 'coordinator', label: 'Coordinator', hint: 'Multi-agent orchestration and workflow' },
|
|
52
|
-
{ value: 'analyst', label: 'Analyst', hint: 'Performance analysis and optimization' },
|
|
53
|
-
{ value: 'optimizer', label: 'Optimizer', hint: 'Performance optimization and bottleneck analysis' },
|
|
54
|
-
{ value: 'security-architect', label: 'Security Architect', hint: 'Security architecture and threat modeling' },
|
|
55
|
-
{ value: 'security-auditor', label: 'Security Auditor', hint: 'CVE remediation and security testing' },
|
|
56
|
-
{ value: 'memory-specialist', label: 'Memory Specialist', hint: 'LanceDB ANN search (150x-12,500x faster)' },
|
|
57
|
-
{ value: 'swarm-specialist', label: 'Swarm Specialist', hint: 'Unified coordination engine' },
|
|
58
|
-
{ value: 'performance-engineer', label: 'Performance Engineer', hint: '2.49x-7.47x optimization targets' },
|
|
59
|
-
{ value: 'core-architect', label: 'Core Architect', hint: 'Domain-driven design restructure' },
|
|
60
|
-
{ value: 'test-architect', label: 'Test Architect', hint: 'TDD London School methodology' }
|
|
61
|
-
];
|
|
62
|
-
// Agent spawn subcommand
|
|
63
|
-
const spawnCommand = {
|
|
64
|
-
name: 'spawn',
|
|
65
|
-
description: 'Spawn a new agent',
|
|
66
|
-
options: [
|
|
67
|
-
{
|
|
68
|
-
name: 'type',
|
|
69
|
-
short: 't',
|
|
70
|
-
description: 'Agent type to spawn',
|
|
71
|
-
type: 'string',
|
|
72
|
-
choices: AGENT_TYPES.map(a => a.value)
|
|
73
|
-
},
|
|
74
|
-
{
|
|
75
|
-
name: 'name',
|
|
76
|
-
short: 'n',
|
|
77
|
-
description: 'Agent name/identifier',
|
|
78
|
-
type: 'string'
|
|
79
|
-
},
|
|
80
|
-
{
|
|
81
|
-
name: 'provider',
|
|
82
|
-
short: 'p',
|
|
83
|
-
description: 'Provider to use (anthropic, openrouter, ollama)',
|
|
84
|
-
type: 'string',
|
|
85
|
-
default: 'anthropic'
|
|
86
|
-
},
|
|
87
|
-
{
|
|
88
|
-
name: 'model',
|
|
89
|
-
short: 'm',
|
|
90
|
-
description: 'Model to use',
|
|
91
|
-
type: 'string'
|
|
92
|
-
},
|
|
93
|
-
{
|
|
94
|
-
name: 'task',
|
|
95
|
-
description: 'Initial task for the agent',
|
|
96
|
-
type: 'string'
|
|
97
|
-
},
|
|
98
|
-
{
|
|
99
|
-
name: 'timeout',
|
|
100
|
-
description: 'Agent timeout in seconds',
|
|
101
|
-
type: 'number',
|
|
102
|
-
default: 300
|
|
103
|
-
},
|
|
104
|
-
{
|
|
105
|
-
name: 'auto-tools',
|
|
106
|
-
description: 'Enable automatic tool usage',
|
|
107
|
-
type: 'boolean',
|
|
108
|
-
default: true
|
|
109
|
-
}
|
|
110
|
-
],
|
|
111
|
-
examples: [
|
|
112
|
-
{ command: 'monomind agent spawn --type coder --name bot-1', description: 'Spawn a coder agent' },
|
|
113
|
-
{ command: 'monomind agent spawn -t researcher --task "Research React 19"', description: 'Spawn researcher with task' }
|
|
114
|
-
],
|
|
115
|
-
action: async (ctx) => {
|
|
116
|
-
let agentType = ctx.flags.type?.slice(0, 64) ?? '';
|
|
117
|
-
let agentName = ctx.flags.name?.slice(0, 128) ?? '';
|
|
118
|
-
// Interactive mode if type not specified
|
|
119
|
-
if (!agentType && ctx.interactive) {
|
|
120
|
-
agentType = await select({
|
|
121
|
-
message: 'Select agent type:',
|
|
122
|
-
options: AGENT_TYPES
|
|
123
|
-
});
|
|
124
|
-
}
|
|
125
|
-
// Semantic routing: if --type absent but --task provided, use RouteLayer
|
|
126
|
-
const taskDescription = ctx.flags.task?.slice(0, 2048);
|
|
127
|
-
if (!agentType && taskDescription) {
|
|
128
|
-
try {
|
|
129
|
-
// Builds a RouteLayer with a real local embedding model + headless
|
|
130
|
-
// Claude Code (Haiku) fallback when available; degrades gracefully.
|
|
131
|
-
const { createConfiguredRouteLayer } = await import('../routing/route-layer-factory.js');
|
|
132
|
-
const layer = await createConfiguredRouteLayer();
|
|
133
|
-
const routeResult = await layer.route(taskDescription);
|
|
134
|
-
agentType = routeResult.agentSlug;
|
|
135
|
-
process.stderr.write(`[route] ${routeResult.method}: "${agentType}" (confidence: ${(routeResult.confidence * 100).toFixed(1)}%)\n`);
|
|
136
|
-
}
|
|
137
|
-
catch {
|
|
138
|
-
// RouteLayer unavailable — fall through to error below
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
if (!agentType) {
|
|
142
|
-
output.printError('Agent type is required. Use --type or -t flag, or provide --task for auto-routing.');
|
|
143
|
-
return { success: false, exitCode: 1 };
|
|
144
|
-
}
|
|
145
|
-
// Generate name if not provided
|
|
146
|
-
if (!agentName) {
|
|
147
|
-
agentName = `${agentType}-${Date.now().toString(36)}`;
|
|
148
|
-
}
|
|
149
|
-
output.printInfo(`Spawning ${agentType} agent: ${output.highlight(agentName)}`);
|
|
150
|
-
try {
|
|
151
|
-
// Call MCP tool to spawn agent
|
|
152
|
-
const result = await callMCPTool('agent_spawn', {
|
|
153
|
-
agentType,
|
|
154
|
-
id: agentName,
|
|
155
|
-
config: {
|
|
156
|
-
provider: ctx.flags.provider || 'anthropic',
|
|
157
|
-
model: ctx.flags.model,
|
|
158
|
-
task: ctx.flags.task,
|
|
159
|
-
timeout: ctx.flags.timeout,
|
|
160
|
-
autoTools: ctx.flags['auto-tools'],
|
|
161
|
-
},
|
|
162
|
-
priority: 'normal',
|
|
163
|
-
metadata: {
|
|
164
|
-
name: agentName,
|
|
165
|
-
capabilities: getAgentCapabilities(agentType),
|
|
166
|
-
},
|
|
167
|
-
});
|
|
168
|
-
output.writeln();
|
|
169
|
-
output.printTable({
|
|
170
|
-
columns: [
|
|
171
|
-
{ key: 'property', header: 'Property', width: 15 },
|
|
172
|
-
{ key: 'value', header: 'Value', width: 40 }
|
|
173
|
-
],
|
|
174
|
-
data: [
|
|
175
|
-
{ property: 'ID', value: result.agentId },
|
|
176
|
-
{ property: 'Type', value: result.agentType },
|
|
177
|
-
{ property: 'Name', value: agentName },
|
|
178
|
-
{ property: 'Status', value: result.status },
|
|
179
|
-
{ property: 'Created', value: result.createdAt },
|
|
180
|
-
{ property: 'Capabilities', value: getAgentCapabilities(agentType).join(', ') }
|
|
181
|
-
]
|
|
182
|
-
});
|
|
183
|
-
output.writeln();
|
|
184
|
-
output.printSuccess(`Agent ${agentName} spawned successfully`);
|
|
185
|
-
// Update swarm-activity.json so statusline reflects the new agent count
|
|
186
|
-
updateSwarmActivityMetrics(1);
|
|
187
|
-
if (ctx.flags.format === 'json') {
|
|
188
|
-
output.printJson(result);
|
|
189
|
-
}
|
|
190
|
-
return { success: true, data: result };
|
|
191
|
-
}
|
|
192
|
-
catch (error) {
|
|
193
|
-
if (error instanceof MCPClientError) {
|
|
194
|
-
output.printError(`Failed to spawn agent: ${error.message}`);
|
|
195
|
-
}
|
|
196
|
-
else {
|
|
197
|
-
output.printError(`Unexpected error: ${String(error)}`);
|
|
198
|
-
}
|
|
199
|
-
return { success: false, exitCode: 1 };
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
};
|
|
203
|
-
// Agent list subcommand
|
|
204
|
-
const listCommand = {
|
|
205
|
-
name: 'list',
|
|
206
|
-
aliases: ['ls'],
|
|
207
|
-
description: 'List all active agents',
|
|
208
|
-
options: [
|
|
209
|
-
{
|
|
210
|
-
name: 'all',
|
|
211
|
-
short: 'a',
|
|
212
|
-
description: 'Include inactive agents',
|
|
213
|
-
type: 'boolean',
|
|
214
|
-
default: false
|
|
215
|
-
},
|
|
216
|
-
{
|
|
217
|
-
name: 'type',
|
|
218
|
-
short: 't',
|
|
219
|
-
description: 'Filter by agent type',
|
|
220
|
-
type: 'string'
|
|
221
|
-
},
|
|
222
|
-
{
|
|
223
|
-
name: 'status',
|
|
224
|
-
short: 's',
|
|
225
|
-
description: 'Filter by status',
|
|
226
|
-
type: 'string'
|
|
227
|
-
}
|
|
228
|
-
],
|
|
229
|
-
action: async (ctx) => {
|
|
230
|
-
try {
|
|
231
|
-
// Call MCP tool to list agents
|
|
232
|
-
const result = await callMCPTool('agent_list', {
|
|
233
|
-
status: ctx.flags.all ? 'all' : ctx.flags.status || undefined,
|
|
234
|
-
agentType: ctx.flags.type || undefined,
|
|
235
|
-
limit: 100,
|
|
236
|
-
});
|
|
237
|
-
if (ctx.flags.format === 'json') {
|
|
238
|
-
output.printJson(result);
|
|
239
|
-
return { success: true, data: result };
|
|
240
|
-
}
|
|
241
|
-
output.writeln();
|
|
242
|
-
output.writeln(output.bold('Active Agents'));
|
|
243
|
-
output.writeln();
|
|
244
|
-
if (result.agents.length === 0) {
|
|
245
|
-
output.printInfo('No agents found matching criteria');
|
|
246
|
-
return { success: true, data: result };
|
|
247
|
-
}
|
|
248
|
-
// Format for display
|
|
249
|
-
const displayAgents = result.agents.map(agent => ({
|
|
250
|
-
id: agent.id,
|
|
251
|
-
type: agent.agentType,
|
|
252
|
-
status: agent.status,
|
|
253
|
-
created: new Date(agent.createdAt).toLocaleTimeString(),
|
|
254
|
-
lastActivity: agent.lastActivityAt
|
|
255
|
-
? new Date(agent.lastActivityAt).toLocaleTimeString()
|
|
256
|
-
: 'N/A',
|
|
257
|
-
}));
|
|
258
|
-
output.printTable({
|
|
259
|
-
columns: [
|
|
260
|
-
{ key: 'id', header: 'ID', width: 20 },
|
|
261
|
-
{ key: 'type', header: 'Type', width: 15 },
|
|
262
|
-
{ key: 'status', header: 'Status', width: 12, format: formatStatus },
|
|
263
|
-
{ key: 'created', header: 'Created', width: 12 },
|
|
264
|
-
{ key: 'lastActivity', header: 'Last Activity', width: 12 }
|
|
265
|
-
],
|
|
266
|
-
data: displayAgents
|
|
267
|
-
});
|
|
268
|
-
output.writeln();
|
|
269
|
-
output.printInfo(`Total: ${result.total} agents`);
|
|
270
|
-
return { success: true, data: result };
|
|
271
|
-
}
|
|
272
|
-
catch (error) {
|
|
273
|
-
if (error instanceof MCPClientError) {
|
|
274
|
-
output.printError(`Failed to list agents: ${error.message}`);
|
|
275
|
-
}
|
|
276
|
-
else {
|
|
277
|
-
output.printError(`Unexpected error: ${String(error)}`);
|
|
278
|
-
}
|
|
279
|
-
return { success: false, exitCode: 1 };
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
// Agent status subcommand
|
|
284
|
-
const statusCommand = {
|
|
285
|
-
name: 'status',
|
|
286
|
-
description: 'Show detailed status of an agent',
|
|
287
|
-
options: [
|
|
288
|
-
{
|
|
289
|
-
name: 'id',
|
|
290
|
-
description: 'Agent ID',
|
|
291
|
-
type: 'string'
|
|
292
|
-
}
|
|
293
|
-
],
|
|
294
|
-
action: async (ctx) => {
|
|
295
|
-
let agentId = ctx.args[0] || ctx.flags.id;
|
|
296
|
-
if (!agentId && ctx.interactive) {
|
|
297
|
-
agentId = await input({
|
|
298
|
-
message: 'Enter agent ID:',
|
|
299
|
-
validate: (v) => v.length > 0 || 'Agent ID is required'
|
|
300
|
-
});
|
|
301
|
-
}
|
|
302
|
-
if (!agentId) {
|
|
303
|
-
output.printError('Agent ID is required');
|
|
304
|
-
return { success: false, exitCode: 1 };
|
|
305
|
-
}
|
|
306
|
-
try {
|
|
307
|
-
// Call MCP tool to get agent status
|
|
308
|
-
const status = await callMCPTool('agent_status', {
|
|
309
|
-
agentId,
|
|
310
|
-
includeMetrics: true,
|
|
311
|
-
includeHistory: false,
|
|
312
|
-
});
|
|
313
|
-
if (ctx.flags.format === 'json') {
|
|
314
|
-
output.printJson(status);
|
|
315
|
-
return { success: true, data: status };
|
|
316
|
-
}
|
|
317
|
-
output.writeln();
|
|
318
|
-
output.printBox([
|
|
319
|
-
`Type: ${status.agentType}`,
|
|
320
|
-
`Status: ${formatStatus(status.status)}`,
|
|
321
|
-
`Created: ${new Date(status.createdAt).toLocaleString()}`,
|
|
322
|
-
`Last Activity: ${status.lastActivityAt ? new Date(status.lastActivityAt).toLocaleString() : 'N/A'}`
|
|
323
|
-
].join('\n'), `Agent: ${status.id}`);
|
|
324
|
-
if (status.metrics) {
|
|
325
|
-
output.writeln();
|
|
326
|
-
output.writeln(output.bold('Metrics'));
|
|
327
|
-
const avgExecTime = status.metrics.averageExecutionTime ?? 0;
|
|
328
|
-
const uptime = status.metrics.uptime ?? 0;
|
|
329
|
-
output.printTable({
|
|
330
|
-
columns: [
|
|
331
|
-
{ key: 'metric', header: 'Metric', width: 25 },
|
|
332
|
-
{ key: 'value', header: 'Value', width: 15, align: 'right' }
|
|
333
|
-
],
|
|
334
|
-
data: [
|
|
335
|
-
{ metric: 'Tasks Completed', value: status.metrics.tasksCompleted ?? 0 },
|
|
336
|
-
{ metric: 'Tasks In Progress', value: status.metrics.tasksInProgress ?? 0 },
|
|
337
|
-
{ metric: 'Tasks Failed', value: status.metrics.tasksFailed ?? 0 },
|
|
338
|
-
{ metric: 'Avg Execution Time', value: `${avgExecTime.toFixed(2)}ms` },
|
|
339
|
-
{ metric: 'Uptime', value: `${(uptime / 1000 / 60).toFixed(1)}m` }
|
|
340
|
-
]
|
|
341
|
-
});
|
|
342
|
-
}
|
|
343
|
-
return { success: true, data: status };
|
|
344
|
-
}
|
|
345
|
-
catch (error) {
|
|
346
|
-
if (error instanceof MCPClientError) {
|
|
347
|
-
output.printError(`Failed to get agent status: ${error.message}`);
|
|
348
|
-
}
|
|
349
|
-
else {
|
|
350
|
-
output.printError(`Unexpected error: ${String(error)}`);
|
|
351
|
-
}
|
|
352
|
-
return { success: false, exitCode: 1 };
|
|
353
|
-
}
|
|
354
|
-
}
|
|
355
|
-
};
|
|
356
|
-
// Agent stop subcommand
|
|
357
|
-
const stopCommand = {
|
|
358
|
-
name: 'stop',
|
|
359
|
-
aliases: ['kill'],
|
|
360
|
-
description: 'Stop a running agent',
|
|
361
|
-
options: [
|
|
362
|
-
{
|
|
363
|
-
name: 'force',
|
|
364
|
-
short: 'f',
|
|
365
|
-
description: 'Force stop without graceful shutdown',
|
|
366
|
-
type: 'boolean',
|
|
367
|
-
default: false
|
|
368
|
-
},
|
|
369
|
-
{
|
|
370
|
-
name: 'timeout',
|
|
371
|
-
description: 'Graceful shutdown timeout in seconds',
|
|
372
|
-
type: 'number',
|
|
373
|
-
default: 30
|
|
374
|
-
}
|
|
375
|
-
],
|
|
376
|
-
action: async (ctx) => {
|
|
377
|
-
const agentId = ctx.args[0];
|
|
378
|
-
if (!agentId) {
|
|
379
|
-
output.printError('Agent ID is required');
|
|
380
|
-
return { success: false, exitCode: 1 };
|
|
381
|
-
}
|
|
382
|
-
const force = ctx.flags.force;
|
|
383
|
-
if (!force && ctx.interactive) {
|
|
384
|
-
const confirmed = await confirm({
|
|
385
|
-
message: `Are you sure you want to stop agent ${agentId}?`,
|
|
386
|
-
default: false
|
|
387
|
-
});
|
|
388
|
-
if (!confirmed) {
|
|
389
|
-
output.printInfo('Operation cancelled');
|
|
390
|
-
return { success: true };
|
|
391
|
-
}
|
|
392
|
-
}
|
|
393
|
-
output.printInfo(`Stopping agent ${agentId}...`);
|
|
394
|
-
try {
|
|
395
|
-
// Call MCP tool to terminate agent
|
|
396
|
-
const result = await callMCPTool('agent_terminate', {
|
|
397
|
-
agentId,
|
|
398
|
-
graceful: !force,
|
|
399
|
-
reason: 'Stopped by user via CLI',
|
|
400
|
-
});
|
|
401
|
-
if (!force) {
|
|
402
|
-
output.writeln(output.dim(' Completing current task...'));
|
|
403
|
-
output.writeln(output.dim(' Saving state...'));
|
|
404
|
-
output.writeln(output.dim(' Releasing resources...'));
|
|
405
|
-
}
|
|
406
|
-
output.printSuccess(`Agent ${agentId} stopped successfully`);
|
|
407
|
-
// Update swarm-activity.json so statusline reflects the reduced agent count
|
|
408
|
-
updateSwarmActivityMetrics(-1);
|
|
409
|
-
if (ctx.flags.format === 'json') {
|
|
410
|
-
output.printJson(result);
|
|
411
|
-
}
|
|
412
|
-
return { success: true, data: result };
|
|
413
|
-
}
|
|
414
|
-
catch (error) {
|
|
415
|
-
if (error instanceof MCPClientError) {
|
|
416
|
-
output.printError(`Failed to stop agent: ${error.message}`);
|
|
417
|
-
}
|
|
418
|
-
else {
|
|
419
|
-
output.printError(`Unexpected error: ${String(error)}`);
|
|
420
|
-
}
|
|
421
|
-
return { success: false, exitCode: 1 };
|
|
422
|
-
}
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
// Agent metrics subcommand
|
|
426
|
-
const metricsCommand = {
|
|
427
|
-
name: 'metrics',
|
|
428
|
-
description: 'Show agent performance metrics',
|
|
429
|
-
options: [
|
|
430
|
-
{
|
|
431
|
-
name: 'period',
|
|
432
|
-
short: 'p',
|
|
433
|
-
description: 'Time period (1h, 24h, 7d, 30d)',
|
|
434
|
-
type: 'string',
|
|
435
|
-
default: '24h'
|
|
436
|
-
}
|
|
437
|
-
],
|
|
438
|
-
action: async (ctx) => {
|
|
439
|
-
const agentId = ctx.args[0];
|
|
440
|
-
const period = ctx.flags.period;
|
|
441
|
-
// Collect real metrics from .swarm/ state
|
|
442
|
-
const { existsSync, readFileSync, readdirSync, statSync } = await import('fs');
|
|
443
|
-
const { join } = await import('path');
|
|
444
|
-
let totalAgents = 0;
|
|
445
|
-
let activeAgents = 0;
|
|
446
|
-
let tasksCompleted = 0;
|
|
447
|
-
const typeCounts = {};
|
|
448
|
-
// Read swarm agent state
|
|
449
|
-
const swarmDir = join(process.cwd(), '.swarm');
|
|
450
|
-
const agentsDir = join(swarmDir, 'agents');
|
|
451
|
-
if (existsSync(agentsDir)) {
|
|
452
|
-
try {
|
|
453
|
-
const files = readdirSync(agentsDir).filter(f => f.endsWith('.json'));
|
|
454
|
-
for (const file of files) {
|
|
455
|
-
try {
|
|
456
|
-
const agentFilePath = join(agentsDir, file);
|
|
457
|
-
if (statSync(agentFilePath).size > 512 * 1024)
|
|
458
|
-
continue; // skip files > 512 KB
|
|
459
|
-
const data = JSON.parse(readFileSync(agentFilePath, 'utf-8'));
|
|
460
|
-
totalAgents++;
|
|
461
|
-
const agType = data.type || 'unknown';
|
|
462
|
-
if (!typeCounts[agType])
|
|
463
|
-
typeCounts[agType] = { count: 0, tasks: 0, success: 0 };
|
|
464
|
-
typeCounts[agType].count++;
|
|
465
|
-
if (data.status === 'active' || data.status === 'running')
|
|
466
|
-
activeAgents++;
|
|
467
|
-
if (data.tasksCompleted) {
|
|
468
|
-
typeCounts[agType].tasks += data.tasksCompleted;
|
|
469
|
-
tasksCompleted += data.tasksCompleted;
|
|
470
|
-
}
|
|
471
|
-
if (data.successCount)
|
|
472
|
-
typeCounts[agType].success += data.successCount;
|
|
473
|
-
}
|
|
474
|
-
catch { /* skip malformed */ }
|
|
475
|
-
}
|
|
476
|
-
}
|
|
477
|
-
catch { /* no agents dir */ }
|
|
478
|
-
}
|
|
479
|
-
// Read swarm activity for additional state
|
|
480
|
-
const activityFile = join(swarmDir, 'swarm-activity.json');
|
|
481
|
-
if (existsSync(activityFile) && statSync(activityFile).size <= 10 * 1024 * 1024) {
|
|
482
|
-
try {
|
|
483
|
-
const activity = JSON.parse(readFileSync(activityFile, 'utf-8'));
|
|
484
|
-
if (activity.totalAgents && totalAgents === 0)
|
|
485
|
-
totalAgents = activity.totalAgents;
|
|
486
|
-
if (activity.activeAgents && activeAgents === 0)
|
|
487
|
-
activeAgents = activity.activeAgents;
|
|
488
|
-
}
|
|
489
|
-
catch { /* ignore */ }
|
|
490
|
-
}
|
|
491
|
-
// Read memory.db stats
|
|
492
|
-
let vectorCount = 0;
|
|
493
|
-
const dbPath = join(swarmDir, 'memory.db');
|
|
494
|
-
if (existsSync(dbPath)) {
|
|
495
|
-
try {
|
|
496
|
-
const dbSize = statSync(dbPath).size;
|
|
497
|
-
vectorCount = Math.floor(dbSize / 2048);
|
|
498
|
-
}
|
|
499
|
-
catch { /* ignore */ }
|
|
500
|
-
}
|
|
501
|
-
const byType = Object.entries(typeCounts).map(([type, data]) => ({
|
|
502
|
-
type,
|
|
503
|
-
count: data.count,
|
|
504
|
-
tasks: data.tasks,
|
|
505
|
-
successRate: data.tasks > 0 ? `${Math.round((data.success / data.tasks) * 100)}%` : 'N/A'
|
|
506
|
-
}));
|
|
507
|
-
const avgSuccessRate = tasksCompleted > 0
|
|
508
|
-
? `${Math.round(Object.values(typeCounts).reduce((a, d) => a + d.success, 0) / tasksCompleted * 100)}%`
|
|
509
|
-
: 'N/A';
|
|
510
|
-
const metrics = {
|
|
511
|
-
period,
|
|
512
|
-
summary: {
|
|
513
|
-
totalAgents,
|
|
514
|
-
activeAgents,
|
|
515
|
-
tasksCompleted,
|
|
516
|
-
avgSuccessRate,
|
|
517
|
-
vectorCount,
|
|
518
|
-
note: totalAgents === 0 ? 'No agents spawned yet. Use: agent spawn -t coder' : undefined
|
|
519
|
-
},
|
|
520
|
-
byType,
|
|
521
|
-
performance: {
|
|
522
|
-
memoryVectors: `${vectorCount} vectors`,
|
|
523
|
-
searchBackend: vectorCount > 0 ? 'HNSW-indexed' : 'none'
|
|
524
|
-
}
|
|
525
|
-
};
|
|
526
|
-
if (ctx.flags.format === 'json') {
|
|
527
|
-
output.printJson(metrics);
|
|
528
|
-
return { success: true, data: metrics };
|
|
529
|
-
}
|
|
530
|
-
output.writeln();
|
|
531
|
-
output.writeln(output.bold(`Agent Metrics (${period})`));
|
|
532
|
-
output.writeln();
|
|
533
|
-
output.printTable({
|
|
534
|
-
columns: [
|
|
535
|
-
{ key: 'metric', header: 'Metric', width: 20 },
|
|
536
|
-
{ key: 'value', header: 'Value', width: 15, align: 'right' }
|
|
537
|
-
],
|
|
538
|
-
data: [
|
|
539
|
-
{ metric: 'Total Agents', value: metrics.summary.totalAgents },
|
|
540
|
-
{ metric: 'Active Agents', value: metrics.summary.activeAgents },
|
|
541
|
-
{ metric: 'Tasks Completed', value: metrics.summary.tasksCompleted },
|
|
542
|
-
{ metric: 'Success Rate', value: metrics.summary.avgSuccessRate },
|
|
543
|
-
{ metric: 'Memory Vectors', value: metrics.summary.vectorCount }
|
|
544
|
-
]
|
|
545
|
-
});
|
|
546
|
-
output.writeln();
|
|
547
|
-
output.writeln(output.bold('By Agent Type'));
|
|
548
|
-
output.printTable({
|
|
549
|
-
columns: [
|
|
550
|
-
{ key: 'type', header: 'Type', width: 12 },
|
|
551
|
-
{ key: 'count', header: 'Count', width: 8, align: 'right' },
|
|
552
|
-
{ key: 'tasks', header: 'Tasks', width: 8, align: 'right' },
|
|
553
|
-
{ key: 'successRate', header: 'Success', width: 10, align: 'right' }
|
|
554
|
-
],
|
|
555
|
-
data: metrics.byType
|
|
556
|
-
});
|
|
557
|
-
if (metrics.summary.note) {
|
|
558
|
-
output.writeln();
|
|
559
|
-
output.writeln(output.dim(metrics.summary.note));
|
|
560
|
-
}
|
|
561
|
-
output.writeln();
|
|
562
|
-
output.writeln(output.bold('Memory'));
|
|
563
|
-
output.printList([
|
|
564
|
-
`Vectors: ${output.success(metrics.performance.memoryVectors)}`,
|
|
565
|
-
`Backend: ${output.success(metrics.performance.searchBackend)}`
|
|
566
|
-
]);
|
|
567
|
-
return { success: true, data: metrics };
|
|
568
|
-
}
|
|
569
|
-
};
|
|
570
|
-
// Agent pool subcommand
|
|
571
|
-
const poolCommand = {
|
|
572
|
-
name: 'pool',
|
|
573
|
-
description: 'Manage agent pool for scaling',
|
|
574
|
-
options: [
|
|
575
|
-
{
|
|
576
|
-
name: 'size',
|
|
577
|
-
short: 's',
|
|
578
|
-
description: 'Pool size',
|
|
579
|
-
type: 'number'
|
|
580
|
-
},
|
|
581
|
-
{
|
|
582
|
-
name: 'min',
|
|
583
|
-
description: 'Minimum pool size',
|
|
584
|
-
type: 'number',
|
|
585
|
-
default: 1
|
|
586
|
-
},
|
|
587
|
-
{
|
|
588
|
-
name: 'max',
|
|
589
|
-
description: 'Maximum pool size',
|
|
590
|
-
type: 'number',
|
|
591
|
-
default: 10
|
|
592
|
-
},
|
|
593
|
-
{
|
|
594
|
-
name: 'auto-scale',
|
|
595
|
-
short: 'a',
|
|
596
|
-
description: 'Enable auto-scaling',
|
|
597
|
-
type: 'boolean',
|
|
598
|
-
default: true
|
|
599
|
-
}
|
|
600
|
-
],
|
|
601
|
-
examples: [
|
|
602
|
-
{ command: 'monomind agent pool --size 5', description: 'Set pool size' },
|
|
603
|
-
{ command: 'monomind agent pool --min 2 --max 15', description: 'Configure auto-scaling' }
|
|
604
|
-
],
|
|
605
|
-
action: async (ctx) => {
|
|
606
|
-
try {
|
|
607
|
-
const result = await callMCPTool('agent_pool', {
|
|
608
|
-
size: ctx.flags.size,
|
|
609
|
-
min: ctx.flags.min,
|
|
610
|
-
max: ctx.flags.max,
|
|
611
|
-
autoScale: ctx.flags['auto-scale'] ?? true,
|
|
612
|
-
});
|
|
613
|
-
if (ctx.flags.format === 'json') {
|
|
614
|
-
output.printJson(result);
|
|
615
|
-
return { success: true, data: result };
|
|
616
|
-
}
|
|
617
|
-
output.writeln();
|
|
618
|
-
const utilization = result.utilization ?? 0;
|
|
619
|
-
output.printBox([
|
|
620
|
-
`Pool ID: ${result.poolId ?? 'default'}`,
|
|
621
|
-
`Current Size: ${result.currentSize ?? 0}`,
|
|
622
|
-
`Min/Max: ${result.minSize ?? 0}/${result.maxSize ?? 100}`,
|
|
623
|
-
`Auto-Scale: ${result.autoScale ? 'Yes' : 'No'}`,
|
|
624
|
-
`Utilization: ${(utilization * 100).toFixed(1)}%`
|
|
625
|
-
].join('\n'), 'Agent Pool');
|
|
626
|
-
const agents = result.agents ?? [];
|
|
627
|
-
if (agents.length > 0) {
|
|
628
|
-
output.writeln();
|
|
629
|
-
output.writeln(output.bold('Pool Agents'));
|
|
630
|
-
output.printTable({
|
|
631
|
-
columns: [
|
|
632
|
-
{ key: 'id', header: 'ID', width: 20 },
|
|
633
|
-
{ key: 'type', header: 'Type', width: 15 },
|
|
634
|
-
{ key: 'status', header: 'Status', width: 12, format: formatStatus }
|
|
635
|
-
],
|
|
636
|
-
data: agents
|
|
637
|
-
});
|
|
638
|
-
}
|
|
639
|
-
return { success: true, data: result };
|
|
640
|
-
}
|
|
641
|
-
catch (error) {
|
|
642
|
-
if (error instanceof MCPClientError) {
|
|
643
|
-
output.printError(`Pool error: ${error.message}`);
|
|
644
|
-
}
|
|
645
|
-
else {
|
|
646
|
-
output.printError(`Unexpected error: ${String(error)}`);
|
|
647
|
-
}
|
|
648
|
-
return { success: false, exitCode: 1 };
|
|
649
|
-
}
|
|
650
|
-
}
|
|
651
|
-
};
|
|
652
|
-
// Agent health subcommand
|
|
653
|
-
const healthCommand = {
|
|
654
|
-
name: 'health',
|
|
655
|
-
description: 'Show agent health and metrics',
|
|
656
|
-
options: [
|
|
657
|
-
{
|
|
658
|
-
name: 'id',
|
|
659
|
-
short: 'i',
|
|
660
|
-
description: 'Agent ID (all if not specified)',
|
|
661
|
-
type: 'string'
|
|
662
|
-
},
|
|
663
|
-
{
|
|
664
|
-
name: 'detailed',
|
|
665
|
-
short: 'd',
|
|
666
|
-
description: 'Show detailed health metrics',
|
|
667
|
-
type: 'boolean',
|
|
668
|
-
default: false
|
|
669
|
-
},
|
|
670
|
-
{
|
|
671
|
-
name: 'watch',
|
|
672
|
-
short: 'w',
|
|
673
|
-
description: 'Watch mode (refresh every 5s)',
|
|
674
|
-
type: 'boolean',
|
|
675
|
-
default: false
|
|
676
|
-
}
|
|
677
|
-
],
|
|
678
|
-
examples: [
|
|
679
|
-
{ command: 'monomind agent health', description: 'Show all agents health' },
|
|
680
|
-
{ command: 'monomind agent health -i agent-001 -d', description: 'Detailed health for specific agent' }
|
|
681
|
-
],
|
|
682
|
-
action: async (ctx) => {
|
|
683
|
-
const agentId = ctx.args[0] || ctx.flags.id;
|
|
684
|
-
const detailed = ctx.flags.detailed;
|
|
685
|
-
try {
|
|
686
|
-
const result = await callMCPTool('agent_health', {
|
|
687
|
-
agentId,
|
|
688
|
-
detailed,
|
|
689
|
-
});
|
|
690
|
-
if (ctx.flags.format === 'json') {
|
|
691
|
-
output.printJson(result);
|
|
692
|
-
return { success: true, data: result };
|
|
693
|
-
}
|
|
694
|
-
output.writeln();
|
|
695
|
-
output.writeln(output.bold('Agent Health'));
|
|
696
|
-
output.writeln();
|
|
697
|
-
// Overall summary with null checks
|
|
698
|
-
const overall = result.overall ?? { healthy: 0, degraded: 0, unhealthy: 0, avgCpu: 0, avgMemory: 0 };
|
|
699
|
-
const avgCpu = overall.avgCpu ?? 0;
|
|
700
|
-
const avgMemory = overall.avgMemory ?? 0;
|
|
701
|
-
output.printBox([
|
|
702
|
-
`Healthy: ${output.success(String(overall.healthy ?? 0))}`,
|
|
703
|
-
`Degraded: ${output.warning(String(overall.degraded ?? 0))}`,
|
|
704
|
-
`Unhealthy: ${output.error(String(overall.unhealthy ?? 0))}`,
|
|
705
|
-
`Avg CPU: ${avgCpu.toFixed(1)}%`,
|
|
706
|
-
`Avg Memory: ${(avgMemory * 100).toFixed(1)}%`
|
|
707
|
-
].join(' | '), 'Overall Status');
|
|
708
|
-
const healthAgents = result.agents ?? [];
|
|
709
|
-
output.writeln();
|
|
710
|
-
output.printTable({
|
|
711
|
-
columns: [
|
|
712
|
-
{ key: 'id', header: 'Agent ID', width: 18 },
|
|
713
|
-
{ key: 'type', header: 'Type', width: 12 },
|
|
714
|
-
{ key: 'health', header: 'Health', width: 10, format: formatHealthStatus },
|
|
715
|
-
{ key: 'cpu', header: 'CPU %', width: 8, align: 'right', format: (v) => `${Number(v ?? 0).toFixed(1)}%` },
|
|
716
|
-
{ key: 'memory', header: 'Memory', width: 10, align: 'right', format: (v) => {
|
|
717
|
-
const mem = v;
|
|
718
|
-
if (!mem)
|
|
719
|
-
return '0%';
|
|
720
|
-
return `${(mem.used / mem.limit * 100).toFixed(0)}%`;
|
|
721
|
-
} },
|
|
722
|
-
{ key: 'tasks', header: 'Tasks', width: 12, align: 'right', format: (v) => {
|
|
723
|
-
const t = v;
|
|
724
|
-
if (!t)
|
|
725
|
-
return '0/0';
|
|
726
|
-
return `${t.active ?? 0}/${t.completed ?? 0}`;
|
|
727
|
-
} }
|
|
728
|
-
],
|
|
729
|
-
data: healthAgents
|
|
730
|
-
});
|
|
731
|
-
if (detailed && healthAgents.length > 0) {
|
|
732
|
-
output.writeln();
|
|
733
|
-
output.writeln(output.bold('Detailed Metrics'));
|
|
734
|
-
for (const agent of healthAgents) {
|
|
735
|
-
output.writeln();
|
|
736
|
-
output.writeln(output.highlight(agent.id));
|
|
737
|
-
const uptime = agent.uptime ?? 0;
|
|
738
|
-
const latency = agent.latency ?? { avg: 0, p99: 0 };
|
|
739
|
-
const tasks = agent.tasks ?? { completed: 0, failed: 0, queued: 0 };
|
|
740
|
-
const errors = agent.errors ?? { count: 0 };
|
|
741
|
-
output.printList([
|
|
742
|
-
`Uptime: ${(uptime / 1000 / 60).toFixed(1)} min`,
|
|
743
|
-
`Latency: avg ${(latency.avg ?? 0).toFixed(1)}ms, p99 ${(latency.p99 ?? 0).toFixed(1)}ms`,
|
|
744
|
-
`Tasks: ${tasks.completed ?? 0} completed, ${tasks.failed ?? 0} failed, ${tasks.queued ?? 0} queued`,
|
|
745
|
-
`Errors: ${errors.count ?? 0}${errors.lastError ? ` (${errors.lastError})` : ''}`
|
|
746
|
-
]);
|
|
747
|
-
}
|
|
748
|
-
}
|
|
749
|
-
return { success: true, data: result };
|
|
750
|
-
}
|
|
751
|
-
catch (error) {
|
|
752
|
-
if (error instanceof MCPClientError) {
|
|
753
|
-
output.printError(`Health check error: ${error.message}`);
|
|
754
|
-
}
|
|
755
|
-
else {
|
|
756
|
-
output.printError(`Unexpected error: ${String(error)}`);
|
|
757
|
-
}
|
|
758
|
-
return { success: false, exitCode: 1 };
|
|
759
|
-
}
|
|
760
|
-
}
|
|
761
|
-
};
|
|
762
|
-
// Agent logs subcommand
|
|
763
|
-
const logsCommand = {
|
|
764
|
-
name: 'logs',
|
|
765
|
-
description: 'Show agent activity logs',
|
|
766
|
-
options: [
|
|
767
|
-
{
|
|
768
|
-
name: 'id',
|
|
769
|
-
short: 'i',
|
|
770
|
-
description: 'Agent ID',
|
|
771
|
-
type: 'string'
|
|
772
|
-
},
|
|
773
|
-
{
|
|
774
|
-
name: 'tail',
|
|
775
|
-
short: 'n',
|
|
776
|
-
description: 'Number of recent entries',
|
|
777
|
-
type: 'number',
|
|
778
|
-
default: 50
|
|
779
|
-
},
|
|
780
|
-
{
|
|
781
|
-
name: 'level',
|
|
782
|
-
short: 'l',
|
|
783
|
-
description: 'Minimum log level',
|
|
784
|
-
type: 'string',
|
|
785
|
-
choices: ['debug', 'info', 'warn', 'error'],
|
|
786
|
-
default: 'info'
|
|
787
|
-
},
|
|
788
|
-
{
|
|
789
|
-
name: 'follow',
|
|
790
|
-
short: 'f',
|
|
791
|
-
description: 'Follow log output',
|
|
792
|
-
type: 'boolean',
|
|
793
|
-
default: false
|
|
794
|
-
},
|
|
795
|
-
{
|
|
796
|
-
name: 'since',
|
|
797
|
-
description: 'Show logs since (e.g., "1h", "30m")',
|
|
798
|
-
type: 'string'
|
|
799
|
-
}
|
|
800
|
-
],
|
|
801
|
-
examples: [
|
|
802
|
-
{ command: 'monomind agent logs -i agent-001', description: 'Show agent logs' },
|
|
803
|
-
{ command: 'monomind agent logs -i agent-001 -f', description: 'Follow agent logs' },
|
|
804
|
-
{ command: 'monomind agent logs -l error --since 1h', description: 'Show errors from last hour' }
|
|
805
|
-
],
|
|
806
|
-
action: async (ctx) => {
|
|
807
|
-
const agentId = ((ctx.args[0] || ctx.flags.id) ?? '').slice(0, 128);
|
|
808
|
-
const tail = ctx.flags.tail;
|
|
809
|
-
const level = ctx.flags.level?.slice(0, 32);
|
|
810
|
-
if (!agentId) {
|
|
811
|
-
output.printError('Agent ID is required. Use --id or -i');
|
|
812
|
-
return { success: false, exitCode: 1 };
|
|
813
|
-
}
|
|
814
|
-
try {
|
|
815
|
-
const result = await callMCPTool('agent_logs', {
|
|
816
|
-
agentId,
|
|
817
|
-
tail,
|
|
818
|
-
level,
|
|
819
|
-
since: ctx.flags.since,
|
|
820
|
-
});
|
|
821
|
-
if (ctx.flags.format === 'json') {
|
|
822
|
-
output.printJson(result);
|
|
823
|
-
return { success: true, data: result };
|
|
824
|
-
}
|
|
825
|
-
output.writeln();
|
|
826
|
-
output.writeln(output.bold(`Logs for ${agentId}`));
|
|
827
|
-
output.writeln(output.dim(`Showing ${result.entries.length} of ${result.total} entries`));
|
|
828
|
-
output.writeln();
|
|
829
|
-
for (const entry of result.entries) {
|
|
830
|
-
const time = new Date(entry.timestamp).toLocaleTimeString();
|
|
831
|
-
const levelStr = formatLogLevel(entry.level);
|
|
832
|
-
output.writeln(`${output.dim(time)} ${levelStr} ${entry.message}`);
|
|
833
|
-
if (entry.context && Object.keys(entry.context).length > 0) {
|
|
834
|
-
output.writeln(output.dim(` ${JSON.stringify(entry.context)}`));
|
|
835
|
-
}
|
|
836
|
-
}
|
|
837
|
-
return { success: true, data: result };
|
|
838
|
-
}
|
|
839
|
-
catch (error) {
|
|
840
|
-
if (error instanceof MCPClientError) {
|
|
841
|
-
output.printError(`Logs error: ${error.message}`);
|
|
842
|
-
}
|
|
843
|
-
else {
|
|
844
|
-
output.printError(`Unexpected error: ${String(error)}`);
|
|
845
|
-
}
|
|
846
|
-
return { success: false, exitCode: 1 };
|
|
847
|
-
}
|
|
848
|
-
}
|
|
849
|
-
};
|
|
850
|
-
function formatHealthStatus(health) {
|
|
851
|
-
const h = String(health);
|
|
852
|
-
switch (h) {
|
|
853
|
-
case 'healthy':
|
|
854
|
-
return output.success(h);
|
|
855
|
-
case 'degraded':
|
|
856
|
-
return output.warning(h);
|
|
857
|
-
case 'unhealthy':
|
|
858
|
-
return output.error(h);
|
|
859
|
-
default:
|
|
860
|
-
return h;
|
|
861
|
-
}
|
|
862
|
-
}
|
|
863
|
-
function formatLogLevel(level) {
|
|
864
|
-
switch (level) {
|
|
865
|
-
case 'debug':
|
|
866
|
-
return output.dim('[DEBUG]');
|
|
867
|
-
case 'info':
|
|
868
|
-
return '[INFO] ';
|
|
869
|
-
case 'warn':
|
|
870
|
-
return output.warning('[WARN] ');
|
|
871
|
-
case 'error':
|
|
872
|
-
return output.error('[ERROR]');
|
|
873
|
-
default:
|
|
874
|
-
return `[${level.toUpperCase()}]`;
|
|
875
|
-
}
|
|
876
|
-
}
|
|
877
|
-
// Main agent command
|
|
6
|
+
import { spawnCommand, listCommand, statusCommand, stopCommand } from './agent-lifecycle.js';
|
|
7
|
+
import { metricsCommand, poolCommand, healthCommand, logsCommand } from './agent-ops.js';
|
|
878
8
|
export const agentCommand = {
|
|
879
9
|
name: 'agent',
|
|
880
10
|
description: 'Agent management commands',
|
|
@@ -883,10 +13,9 @@ export const agentCommand = {
|
|
|
883
13
|
examples: [
|
|
884
14
|
{ command: 'monomind agent spawn -t coder', description: 'Spawn a coder agent' },
|
|
885
15
|
{ command: 'monomind agent list', description: 'List all agents' },
|
|
886
|
-
{ command: 'monomind agent status agent-001', description: 'Show agent status' }
|
|
16
|
+
{ command: 'monomind agent status agent-001', description: 'Show agent status' },
|
|
887
17
|
],
|
|
888
|
-
action: async (
|
|
889
|
-
// Show help if no subcommand
|
|
18
|
+
action: async (_ctx) => {
|
|
890
19
|
output.writeln();
|
|
891
20
|
output.writeln(output.bold('Agent Management Commands'));
|
|
892
21
|
output.writeln();
|
|
@@ -906,38 +35,7 @@ export const agentCommand = {
|
|
|
906
35
|
output.writeln();
|
|
907
36
|
output.writeln('Run "monomind agent <subcommand> --help" for subcommand help');
|
|
908
37
|
return { success: true };
|
|
909
|
-
}
|
|
38
|
+
},
|
|
910
39
|
};
|
|
911
|
-
// Helper functions
|
|
912
|
-
function getAgentCapabilities(type) {
|
|
913
|
-
const capabilities = {
|
|
914
|
-
coder: ['code-generation', 'refactoring', 'debugging', 'testing'],
|
|
915
|
-
researcher: ['web-search', 'data-analysis', 'summarization', 'citation'],
|
|
916
|
-
tester: ['unit-testing', 'integration-testing', 'coverage-analysis', 'automation'],
|
|
917
|
-
reviewer: ['code-review', 'security-audit', 'quality-check', 'documentation'],
|
|
918
|
-
architect: ['system-design', 'pattern-analysis', 'scalability', 'documentation'],
|
|
919
|
-
coordinator: ['task-orchestration', 'agent-management', 'workflow-control'],
|
|
920
|
-
'security-architect': ['threat-modeling', 'security-patterns', 'compliance', 'audit'],
|
|
921
|
-
'memory-specialist': ['vector-search', 'lancedb', 'caching', 'optimization'],
|
|
922
|
-
'performance-engineer': ['benchmarking', 'profiling', 'optimization', 'monitoring']
|
|
923
|
-
};
|
|
924
|
-
return capabilities[type] || ['general'];
|
|
925
|
-
}
|
|
926
|
-
function formatStatus(status) {
|
|
927
|
-
const statusStr = String(status);
|
|
928
|
-
switch (statusStr) {
|
|
929
|
-
case 'active':
|
|
930
|
-
return output.success(statusStr);
|
|
931
|
-
case 'idle':
|
|
932
|
-
return output.warning(statusStr);
|
|
933
|
-
case 'inactive':
|
|
934
|
-
case 'stopped':
|
|
935
|
-
return output.dim(statusStr);
|
|
936
|
-
case 'error':
|
|
937
|
-
return output.error(statusStr);
|
|
938
|
-
default:
|
|
939
|
-
return statusStr;
|
|
940
|
-
}
|
|
941
|
-
}
|
|
942
40
|
export default agentCommand;
|
|
943
41
|
//# sourceMappingURL=agent.js.map
|