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
|
@@ -0,0 +1,329 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent operational commands — metrics, pool, health, logs
|
|
3
|
+
*/
|
|
4
|
+
import { output } from '../output.js';
|
|
5
|
+
import { callMCPTool, MCPClientError } from '../mcp-client.js';
|
|
6
|
+
import { formatStatus } from './agent-lifecycle.js';
|
|
7
|
+
// ─── metrics subcommand ──────────────────────────────────────────────────────
|
|
8
|
+
export const metricsCommand = {
|
|
9
|
+
name: 'metrics',
|
|
10
|
+
description: 'Show agent performance metrics',
|
|
11
|
+
options: [
|
|
12
|
+
{ name: 'period', short: 'p', description: 'Time period (1h, 24h, 7d, 30d)', type: 'string', default: '24h' },
|
|
13
|
+
],
|
|
14
|
+
action: async (ctx) => {
|
|
15
|
+
const period = ctx.flags.period;
|
|
16
|
+
const { existsSync, readFileSync, readdirSync, statSync } = await import('fs');
|
|
17
|
+
const { join } = await import('path');
|
|
18
|
+
let totalAgents = 0;
|
|
19
|
+
let activeAgents = 0;
|
|
20
|
+
let tasksCompleted = 0;
|
|
21
|
+
const typeCounts = {};
|
|
22
|
+
const swarmDir = join(process.cwd(), '.swarm');
|
|
23
|
+
const agentsDir = join(swarmDir, 'agents');
|
|
24
|
+
if (existsSync(agentsDir)) {
|
|
25
|
+
try {
|
|
26
|
+
const files = readdirSync(agentsDir).filter(f => f.endsWith('.json'));
|
|
27
|
+
for (const file of files) {
|
|
28
|
+
try {
|
|
29
|
+
const agentFilePath = join(agentsDir, file);
|
|
30
|
+
if (statSync(agentFilePath).size > 512 * 1024)
|
|
31
|
+
continue;
|
|
32
|
+
const data = JSON.parse(readFileSync(agentFilePath, 'utf-8'));
|
|
33
|
+
totalAgents++;
|
|
34
|
+
const agType = data.type || 'unknown';
|
|
35
|
+
if (!typeCounts[agType])
|
|
36
|
+
typeCounts[agType] = { count: 0, tasks: 0, success: 0 };
|
|
37
|
+
typeCounts[agType].count++;
|
|
38
|
+
if (data.status === 'active' || data.status === 'running')
|
|
39
|
+
activeAgents++;
|
|
40
|
+
if (data.tasksCompleted) {
|
|
41
|
+
typeCounts[agType].tasks += data.tasksCompleted;
|
|
42
|
+
tasksCompleted += data.tasksCompleted;
|
|
43
|
+
}
|
|
44
|
+
if (data.successCount)
|
|
45
|
+
typeCounts[agType].success += data.successCount;
|
|
46
|
+
}
|
|
47
|
+
catch { /* skip malformed */ }
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
catch { /* no agents dir */ }
|
|
51
|
+
}
|
|
52
|
+
const activityFile = join(swarmDir, 'swarm-activity.json');
|
|
53
|
+
if (existsSync(activityFile) && statSync(activityFile).size <= 10 * 1024 * 1024) {
|
|
54
|
+
try {
|
|
55
|
+
const activity = JSON.parse(readFileSync(activityFile, 'utf-8'));
|
|
56
|
+
if (activity.totalAgents && totalAgents === 0)
|
|
57
|
+
totalAgents = activity.totalAgents;
|
|
58
|
+
if (activity.activeAgents && activeAgents === 0)
|
|
59
|
+
activeAgents = activity.activeAgents;
|
|
60
|
+
}
|
|
61
|
+
catch { /* ignore */ }
|
|
62
|
+
}
|
|
63
|
+
let vectorCount = 0;
|
|
64
|
+
const dbPath = join(swarmDir, 'memory.db');
|
|
65
|
+
if (existsSync(dbPath)) {
|
|
66
|
+
try {
|
|
67
|
+
vectorCount = Math.floor(statSync(dbPath).size / 2048);
|
|
68
|
+
}
|
|
69
|
+
catch { /* ignore */ }
|
|
70
|
+
}
|
|
71
|
+
const byType = Object.entries(typeCounts).map(([type, data]) => ({
|
|
72
|
+
type, count: data.count, tasks: data.tasks,
|
|
73
|
+
successRate: data.tasks > 0 ? `${Math.round((data.success / data.tasks) * 100)}%` : 'N/A',
|
|
74
|
+
}));
|
|
75
|
+
const avgSuccessRate = tasksCompleted > 0
|
|
76
|
+
? `${Math.round(Object.values(typeCounts).reduce((a, d) => a + d.success, 0) / tasksCompleted * 100)}%`
|
|
77
|
+
: 'N/A';
|
|
78
|
+
const metrics = {
|
|
79
|
+
period,
|
|
80
|
+
summary: {
|
|
81
|
+
totalAgents, activeAgents, tasksCompleted, avgSuccessRate, vectorCount,
|
|
82
|
+
note: totalAgents === 0 ? 'No agents spawned yet. Use: agent spawn -t coder' : undefined,
|
|
83
|
+
},
|
|
84
|
+
byType,
|
|
85
|
+
performance: { memoryVectors: `${vectorCount} vectors`, searchBackend: vectorCount > 0 ? 'HNSW-indexed' : 'none' },
|
|
86
|
+
};
|
|
87
|
+
if (ctx.flags.format === 'json') {
|
|
88
|
+
output.printJson(metrics);
|
|
89
|
+
return { success: true, data: metrics };
|
|
90
|
+
}
|
|
91
|
+
output.writeln();
|
|
92
|
+
output.writeln(output.bold(`Agent Metrics (${period})`));
|
|
93
|
+
output.writeln();
|
|
94
|
+
output.printTable({
|
|
95
|
+
columns: [
|
|
96
|
+
{ key: 'metric', header: 'Metric', width: 20 },
|
|
97
|
+
{ key: 'value', header: 'Value', width: 15, align: 'right' },
|
|
98
|
+
],
|
|
99
|
+
data: [
|
|
100
|
+
{ metric: 'Total Agents', value: metrics.summary.totalAgents },
|
|
101
|
+
{ metric: 'Active Agents', value: metrics.summary.activeAgents },
|
|
102
|
+
{ metric: 'Tasks Completed', value: metrics.summary.tasksCompleted },
|
|
103
|
+
{ metric: 'Success Rate', value: metrics.summary.avgSuccessRate },
|
|
104
|
+
{ metric: 'Memory Vectors', value: metrics.summary.vectorCount },
|
|
105
|
+
],
|
|
106
|
+
});
|
|
107
|
+
output.writeln();
|
|
108
|
+
output.writeln(output.bold('By Agent Type'));
|
|
109
|
+
output.printTable({
|
|
110
|
+
columns: [
|
|
111
|
+
{ key: 'type', header: 'Type', width: 12 },
|
|
112
|
+
{ key: 'count', header: 'Count', width: 8, align: 'right' },
|
|
113
|
+
{ key: 'tasks', header: 'Tasks', width: 8, align: 'right' },
|
|
114
|
+
{ key: 'successRate', header: 'Success', width: 10, align: 'right' },
|
|
115
|
+
],
|
|
116
|
+
data: metrics.byType,
|
|
117
|
+
});
|
|
118
|
+
if (metrics.summary.note) {
|
|
119
|
+
output.writeln();
|
|
120
|
+
output.writeln(output.dim(metrics.summary.note));
|
|
121
|
+
}
|
|
122
|
+
output.writeln();
|
|
123
|
+
output.writeln(output.bold('Memory'));
|
|
124
|
+
output.printList([
|
|
125
|
+
`Vectors: ${output.success(metrics.performance.memoryVectors)}`,
|
|
126
|
+
`Backend: ${output.success(metrics.performance.searchBackend)}`,
|
|
127
|
+
]);
|
|
128
|
+
return { success: true, data: metrics };
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
// ─── pool subcommand ─────────────────────────────────────────────────────────
|
|
132
|
+
export const poolCommand = {
|
|
133
|
+
name: 'pool',
|
|
134
|
+
description: 'Manage agent pool for scaling',
|
|
135
|
+
options: [
|
|
136
|
+
{ name: 'size', short: 's', description: 'Pool size', type: 'number' },
|
|
137
|
+
{ name: 'min', description: 'Minimum pool size', type: 'number', default: 1 },
|
|
138
|
+
{ name: 'max', description: 'Maximum pool size', type: 'number', default: 10 },
|
|
139
|
+
{ name: 'auto-scale', short: 'a', description: 'Enable auto-scaling', type: 'boolean', default: true },
|
|
140
|
+
],
|
|
141
|
+
examples: [
|
|
142
|
+
{ command: 'monomind agent pool --size 5', description: 'Set pool size' },
|
|
143
|
+
{ command: 'monomind agent pool --min 2 --max 15', description: 'Configure auto-scaling' },
|
|
144
|
+
],
|
|
145
|
+
action: async (ctx) => {
|
|
146
|
+
try {
|
|
147
|
+
const result = await callMCPTool('agent_pool', {
|
|
148
|
+
size: ctx.flags.size, min: ctx.flags.min, max: ctx.flags.max,
|
|
149
|
+
autoScale: ctx.flags['auto-scale'] ?? true,
|
|
150
|
+
});
|
|
151
|
+
if (ctx.flags.format === 'json') {
|
|
152
|
+
output.printJson(result);
|
|
153
|
+
return { success: true, data: result };
|
|
154
|
+
}
|
|
155
|
+
output.writeln();
|
|
156
|
+
const utilization = result.utilization ?? 0;
|
|
157
|
+
output.printBox([
|
|
158
|
+
`Pool ID: ${result.poolId ?? 'default'}`,
|
|
159
|
+
`Current Size: ${result.currentSize ?? 0}`,
|
|
160
|
+
`Min/Max: ${result.minSize ?? 0}/${result.maxSize ?? 100}`,
|
|
161
|
+
`Auto-Scale: ${result.autoScale ? 'Yes' : 'No'}`,
|
|
162
|
+
`Utilization: ${(utilization * 100).toFixed(1)}%`,
|
|
163
|
+
].join('\n'), 'Agent Pool');
|
|
164
|
+
const agents = result.agents ?? [];
|
|
165
|
+
if (agents.length > 0) {
|
|
166
|
+
output.writeln();
|
|
167
|
+
output.writeln(output.bold('Pool Agents'));
|
|
168
|
+
output.printTable({
|
|
169
|
+
columns: [
|
|
170
|
+
{ key: 'id', header: 'ID', width: 20 },
|
|
171
|
+
{ key: 'type', header: 'Type', width: 15 },
|
|
172
|
+
{ key: 'status', header: 'Status', width: 12, format: formatStatus },
|
|
173
|
+
],
|
|
174
|
+
data: agents,
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
return { success: true, data: result };
|
|
178
|
+
}
|
|
179
|
+
catch (error) {
|
|
180
|
+
output.printError(error instanceof MCPClientError ? `Pool error: ${error.message}` : `Unexpected error: ${String(error)}`);
|
|
181
|
+
return { success: false, exitCode: 1 };
|
|
182
|
+
}
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
// ─── health subcommand ───────────────────────────────────────────────────────
|
|
186
|
+
function formatHealthStatus(health) {
|
|
187
|
+
switch (String(health)) {
|
|
188
|
+
case 'healthy': return output.success(String(health));
|
|
189
|
+
case 'degraded': return output.warning(String(health));
|
|
190
|
+
case 'unhealthy': return output.error(String(health));
|
|
191
|
+
default: return String(health);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
export const healthCommand = {
|
|
195
|
+
name: 'health',
|
|
196
|
+
description: 'Show agent health and metrics',
|
|
197
|
+
options: [
|
|
198
|
+
{ name: 'id', short: 'i', description: 'Agent ID (all if not specified)', type: 'string' },
|
|
199
|
+
{ name: 'detailed', short: 'd', description: 'Show detailed health metrics', type: 'boolean', default: false },
|
|
200
|
+
{ name: 'watch', short: 'w', description: 'Watch mode (refresh every 5s)', type: 'boolean', default: false },
|
|
201
|
+
],
|
|
202
|
+
examples: [
|
|
203
|
+
{ command: 'monomind agent health', description: 'Show all agents health' },
|
|
204
|
+
{ command: 'monomind agent health -i agent-001 -d', description: 'Detailed health for specific agent' },
|
|
205
|
+
],
|
|
206
|
+
action: async (ctx) => {
|
|
207
|
+
const agentId = ctx.args[0] || ctx.flags.id;
|
|
208
|
+
const detailed = ctx.flags.detailed;
|
|
209
|
+
try {
|
|
210
|
+
const result = await callMCPTool('agent_health', { agentId, detailed });
|
|
211
|
+
if (ctx.flags.format === 'json') {
|
|
212
|
+
output.printJson(result);
|
|
213
|
+
return { success: true, data: result };
|
|
214
|
+
}
|
|
215
|
+
output.writeln();
|
|
216
|
+
output.writeln(output.bold('Agent Health'));
|
|
217
|
+
output.writeln();
|
|
218
|
+
const overall = result.overall ?? { healthy: 0, degraded: 0, unhealthy: 0, avgCpu: 0, avgMemory: 0 };
|
|
219
|
+
output.printBox([
|
|
220
|
+
`Healthy: ${output.success(String(overall.healthy ?? 0))}`,
|
|
221
|
+
`Degraded: ${output.warning(String(overall.degraded ?? 0))}`,
|
|
222
|
+
`Unhealthy: ${output.error(String(overall.unhealthy ?? 0))}`,
|
|
223
|
+
`Avg CPU: ${(overall.avgCpu ?? 0).toFixed(1)}%`,
|
|
224
|
+
`Avg Memory: ${((overall.avgMemory ?? 0) * 100).toFixed(1)}%`,
|
|
225
|
+
].join(' | '), 'Overall Status');
|
|
226
|
+
const healthAgents = result.agents ?? [];
|
|
227
|
+
output.writeln();
|
|
228
|
+
output.printTable({
|
|
229
|
+
columns: [
|
|
230
|
+
{ key: 'id', header: 'Agent ID', width: 18 },
|
|
231
|
+
{ key: 'type', header: 'Type', width: 12 },
|
|
232
|
+
{ key: 'health', header: 'Health', width: 10, format: formatHealthStatus },
|
|
233
|
+
{ key: 'cpu', header: 'CPU %', width: 8, align: 'right', format: (v) => `${Number(v ?? 0).toFixed(1)}%` },
|
|
234
|
+
{ key: 'memory', header: 'Memory', width: 10, align: 'right', format: (v) => {
|
|
235
|
+
const mem = v;
|
|
236
|
+
return mem ? `${(mem.used / mem.limit * 100).toFixed(0)}%` : '0%';
|
|
237
|
+
} },
|
|
238
|
+
{ key: 'tasks', header: 'Tasks', width: 12, align: 'right', format: (v) => {
|
|
239
|
+
const t = v;
|
|
240
|
+
return t ? `${t.active ?? 0}/${t.completed ?? 0}` : '0/0';
|
|
241
|
+
} },
|
|
242
|
+
],
|
|
243
|
+
data: healthAgents,
|
|
244
|
+
});
|
|
245
|
+
if (detailed && healthAgents.length > 0) {
|
|
246
|
+
output.writeln();
|
|
247
|
+
output.writeln(output.bold('Detailed Metrics'));
|
|
248
|
+
for (const agent of healthAgents) {
|
|
249
|
+
output.writeln();
|
|
250
|
+
output.writeln(output.highlight(agent.id));
|
|
251
|
+
const uptime = agent.uptime ?? 0;
|
|
252
|
+
const latency = agent.latency ?? { avg: 0, p99: 0 };
|
|
253
|
+
const tasks = agent.tasks ?? { completed: 0, failed: 0, queued: 0 };
|
|
254
|
+
const errors = agent.errors ?? { count: 0 };
|
|
255
|
+
output.printList([
|
|
256
|
+
`Uptime: ${(uptime / 1000 / 60).toFixed(1)} min`,
|
|
257
|
+
`Latency: avg ${(latency.avg ?? 0).toFixed(1)}ms, p99 ${(latency.p99 ?? 0).toFixed(1)}ms`,
|
|
258
|
+
`Tasks: ${tasks.completed ?? 0} completed, ${tasks.failed ?? 0} failed, ${tasks.queued ?? 0} queued`,
|
|
259
|
+
`Errors: ${errors.count ?? 0}${errors.lastError ? ` (${errors.lastError})` : ''}`,
|
|
260
|
+
]);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return { success: true, data: result };
|
|
264
|
+
}
|
|
265
|
+
catch (error) {
|
|
266
|
+
output.printError(error instanceof MCPClientError ? `Health check error: ${error.message}` : `Unexpected error: ${String(error)}`);
|
|
267
|
+
return { success: false, exitCode: 1 };
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
};
|
|
271
|
+
// ─── logs subcommand ─────────────────────────────────────────────────────────
|
|
272
|
+
function formatLogLevel(level) {
|
|
273
|
+
switch (level) {
|
|
274
|
+
case 'debug': return output.dim('[DEBUG]');
|
|
275
|
+
case 'info': return '[INFO] ';
|
|
276
|
+
case 'warn': return output.warning('[WARN] ');
|
|
277
|
+
case 'error': return output.error('[ERROR]');
|
|
278
|
+
default: return `[${level.toUpperCase()}]`;
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
export const logsCommand = {
|
|
282
|
+
name: 'logs',
|
|
283
|
+
description: 'Show agent activity logs',
|
|
284
|
+
options: [
|
|
285
|
+
{ name: 'id', short: 'i', description: 'Agent ID', type: 'string' },
|
|
286
|
+
{ name: 'tail', short: 'n', description: 'Number of recent entries', type: 'number', default: 50 },
|
|
287
|
+
{ name: 'level', short: 'l', description: 'Minimum log level', type: 'string', choices: ['debug', 'info', 'warn', 'error'], default: 'info' },
|
|
288
|
+
{ name: 'follow', short: 'f', description: 'Follow log output', type: 'boolean', default: false },
|
|
289
|
+
{ name: 'since', description: 'Show logs since (e.g., "1h", "30m")', type: 'string' },
|
|
290
|
+
],
|
|
291
|
+
examples: [
|
|
292
|
+
{ command: 'monomind agent logs -i agent-001', description: 'Show agent logs' },
|
|
293
|
+
{ command: 'monomind agent logs -i agent-001 -f', description: 'Follow agent logs' },
|
|
294
|
+
{ command: 'monomind agent logs -l error --since 1h', description: 'Show errors from last hour' },
|
|
295
|
+
],
|
|
296
|
+
action: async (ctx) => {
|
|
297
|
+
const agentId = ((ctx.args[0] || ctx.flags.id) ?? '').slice(0, 128);
|
|
298
|
+
const tail = ctx.flags.tail;
|
|
299
|
+
const level = ctx.flags.level?.slice(0, 32);
|
|
300
|
+
if (!agentId) {
|
|
301
|
+
output.printError('Agent ID is required. Use --id or -i');
|
|
302
|
+
return { success: false, exitCode: 1 };
|
|
303
|
+
}
|
|
304
|
+
try {
|
|
305
|
+
const result = await callMCPTool('agent_logs', { agentId, tail, level, since: ctx.flags.since });
|
|
306
|
+
if (ctx.flags.format === 'json') {
|
|
307
|
+
output.printJson(result);
|
|
308
|
+
return { success: true, data: result };
|
|
309
|
+
}
|
|
310
|
+
output.writeln();
|
|
311
|
+
output.writeln(output.bold(`Logs for ${agentId}`));
|
|
312
|
+
output.writeln(output.dim(`Showing ${result.entries.length} of ${result.total} entries`));
|
|
313
|
+
output.writeln();
|
|
314
|
+
for (const entry of result.entries) {
|
|
315
|
+
const time = new Date(entry.timestamp).toLocaleTimeString();
|
|
316
|
+
output.writeln(`${output.dim(time)} ${formatLogLevel(entry.level)} ${entry.message}`);
|
|
317
|
+
if (entry.context && Object.keys(entry.context).length > 0) {
|
|
318
|
+
output.writeln(output.dim(` ${JSON.stringify(entry.context)}`));
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
return { success: true, data: result };
|
|
322
|
+
}
|
|
323
|
+
catch (error) {
|
|
324
|
+
output.printError(error instanceof MCPClientError ? `Logs error: ${error.message}` : `Unexpected error: ${String(error)}`);
|
|
325
|
+
return { success: false, exitCode: 1 };
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
//# sourceMappingURL=agent-ops.js.map
|