claude-flow 1.0.0
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/LICENSE +21 -0
- package/README.md +612 -0
- package/bin/claude-flow +0 -0
- package/bin/claude-flow-simple +0 -0
- package/bin/claude-flow-typecheck +0 -0
- package/deno.json +84 -0
- package/package.json +45 -0
- package/scripts/check-links.ts +274 -0
- package/scripts/check-performance-regression.ts +168 -0
- package/scripts/claude-sparc.sh +562 -0
- package/scripts/coverage-report.ts +692 -0
- package/scripts/demo-task-system.ts +224 -0
- package/scripts/install.js +72 -0
- package/scripts/test-batch-tasks.ts +29 -0
- package/scripts/test-coordination-features.ts +238 -0
- package/scripts/test-mcp.ts +251 -0
- package/scripts/test-runner.ts +571 -0
- package/scripts/validate-examples.ts +288 -0
- package/src/cli/cli-core.ts +273 -0
- package/src/cli/commands/agent.ts +83 -0
- package/src/cli/commands/config.ts +442 -0
- package/src/cli/commands/help.ts +765 -0
- package/src/cli/commands/index.ts +963 -0
- package/src/cli/commands/mcp.ts +191 -0
- package/src/cli/commands/memory.ts +74 -0
- package/src/cli/commands/monitor.ts +403 -0
- package/src/cli/commands/session.ts +595 -0
- package/src/cli/commands/start.ts +156 -0
- package/src/cli/commands/status.ts +345 -0
- package/src/cli/commands/task.ts +79 -0
- package/src/cli/commands/workflow.ts +763 -0
- package/src/cli/completion.ts +553 -0
- package/src/cli/formatter.ts +310 -0
- package/src/cli/index.ts +211 -0
- package/src/cli/main.ts +23 -0
- package/src/cli/repl.ts +1050 -0
- package/src/cli/simple-cli.js +211 -0
- package/src/cli/simple-cli.ts +211 -0
- package/src/coordination/README.md +400 -0
- package/src/coordination/advanced-scheduler.ts +487 -0
- package/src/coordination/circuit-breaker.ts +366 -0
- package/src/coordination/conflict-resolution.ts +490 -0
- package/src/coordination/dependency-graph.ts +475 -0
- package/src/coordination/index.ts +63 -0
- package/src/coordination/manager.ts +460 -0
- package/src/coordination/messaging.ts +290 -0
- package/src/coordination/metrics.ts +585 -0
- package/src/coordination/resources.ts +322 -0
- package/src/coordination/scheduler.ts +390 -0
- package/src/coordination/work-stealing.ts +224 -0
- package/src/core/config.ts +627 -0
- package/src/core/event-bus.ts +186 -0
- package/src/core/json-persistence.ts +183 -0
- package/src/core/logger.ts +262 -0
- package/src/core/orchestrator-fixed.ts +312 -0
- package/src/core/orchestrator.ts +1234 -0
- package/src/core/persistence.ts +276 -0
- package/src/mcp/auth.ts +438 -0
- package/src/mcp/claude-flow-tools.ts +1280 -0
- package/src/mcp/load-balancer.ts +510 -0
- package/src/mcp/router.ts +240 -0
- package/src/mcp/server.ts +548 -0
- package/src/mcp/session-manager.ts +418 -0
- package/src/mcp/tools.ts +180 -0
- package/src/mcp/transports/base.ts +21 -0
- package/src/mcp/transports/http.ts +457 -0
- package/src/mcp/transports/stdio.ts +254 -0
- package/src/memory/backends/base.ts +22 -0
- package/src/memory/backends/markdown.ts +283 -0
- package/src/memory/backends/sqlite.ts +329 -0
- package/src/memory/cache.ts +238 -0
- package/src/memory/indexer.ts +238 -0
- package/src/memory/manager.ts +572 -0
- package/src/terminal/adapters/base.ts +29 -0
- package/src/terminal/adapters/native.ts +504 -0
- package/src/terminal/adapters/vscode.ts +340 -0
- package/src/terminal/manager.ts +308 -0
- package/src/terminal/pool.ts +271 -0
- package/src/terminal/session.ts +250 -0
- package/src/terminal/vscode-bridge.ts +242 -0
- package/src/utils/errors.ts +231 -0
- package/src/utils/helpers.ts +476 -0
- package/src/utils/types.ts +493 -0
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Start command for Claude-Flow
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from '@cliffy/command';
|
|
6
|
+
import { colors } from '@cliffy/ansi/colors';
|
|
7
|
+
import { Orchestrator } from '../../core/orchestrator.ts';
|
|
8
|
+
import { eventBus } from '../../core/event-bus.ts';
|
|
9
|
+
import { logger } from '../../core/logger.ts';
|
|
10
|
+
import { configManager } from '../../core/config.ts';
|
|
11
|
+
import { TerminalManager } from '../../terminal/manager.ts';
|
|
12
|
+
import { MemoryManager } from '../../memory/manager.ts';
|
|
13
|
+
import { CoordinationManager } from '../../coordination/manager.ts';
|
|
14
|
+
import { MCPServer } from '../../mcp/server.ts';
|
|
15
|
+
import { SystemEvents } from '../../utils/types.ts';
|
|
16
|
+
// Spinner is not available in the current cliffy version, use simple text instead
|
|
17
|
+
|
|
18
|
+
export const startCommand = new Command()
|
|
19
|
+
.description('Start the Claude-Flow orchestration system')
|
|
20
|
+
.option('-d, --daemon', 'Run as daemon in background')
|
|
21
|
+
.option('-p, --port <port:number>', 'MCP server port', { default: 3000 })
|
|
22
|
+
.option('--mcp-transport <transport:string>', 'MCP transport type (stdio, http)', {
|
|
23
|
+
default: 'stdio',
|
|
24
|
+
})
|
|
25
|
+
.action(async (options: any) => {
|
|
26
|
+
console.log(colors.cyan('Starting Claude-Flow...'));
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
// Load configuration
|
|
30
|
+
const config = await configManager.load(options.config || undefined);
|
|
31
|
+
|
|
32
|
+
// Override MCP settings from CLI options
|
|
33
|
+
if (options.port) {
|
|
34
|
+
config.mcp.port = options.port;
|
|
35
|
+
}
|
|
36
|
+
if (options.mcpTransport) {
|
|
37
|
+
config.mcp.transport = options.mcpTransport as any;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
// Create components
|
|
41
|
+
const terminalManager = new TerminalManager(
|
|
42
|
+
config.terminal,
|
|
43
|
+
eventBus,
|
|
44
|
+
logger,
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
const memoryManager = new MemoryManager(
|
|
48
|
+
config.memory,
|
|
49
|
+
eventBus,
|
|
50
|
+
logger,
|
|
51
|
+
);
|
|
52
|
+
|
|
53
|
+
const coordinationManager = new CoordinationManager(
|
|
54
|
+
config.coordination,
|
|
55
|
+
eventBus,
|
|
56
|
+
logger,
|
|
57
|
+
);
|
|
58
|
+
|
|
59
|
+
const mcpServer = new MCPServer(
|
|
60
|
+
config.mcp,
|
|
61
|
+
eventBus,
|
|
62
|
+
logger,
|
|
63
|
+
);
|
|
64
|
+
|
|
65
|
+
// Create orchestrator
|
|
66
|
+
const orchestrator = new Orchestrator(
|
|
67
|
+
config,
|
|
68
|
+
terminalManager,
|
|
69
|
+
memoryManager,
|
|
70
|
+
coordinationManager,
|
|
71
|
+
mcpServer,
|
|
72
|
+
eventBus,
|
|
73
|
+
logger,
|
|
74
|
+
);
|
|
75
|
+
|
|
76
|
+
// Initialize orchestrator
|
|
77
|
+
await orchestrator.initialize();
|
|
78
|
+
|
|
79
|
+
// spinner.stop();
|
|
80
|
+
console.log(colors.green.bold('✓'), 'Claude-Flow started successfully!');
|
|
81
|
+
|
|
82
|
+
if (config.mcp.transport === 'http') {
|
|
83
|
+
console.log(colors.cyan('MCP server listening on'),
|
|
84
|
+
colors.yellow(`http://${config.mcp.host || 'localhost'}:${config.mcp.port}`));
|
|
85
|
+
} else {
|
|
86
|
+
console.log(colors.cyan('MCP server listening on'), colors.yellow('stdio'));
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// Set up graceful shutdown
|
|
90
|
+
const shutdown = async () => {
|
|
91
|
+
console.log('\n' + colors.yellow('Shutting down Claude-Flow...'));
|
|
92
|
+
eventBus.emit('shutdown');
|
|
93
|
+
await orchestrator.shutdown();
|
|
94
|
+
console.log(colors.green.bold('✓'), 'Shutdown complete');
|
|
95
|
+
Deno.exit(0);
|
|
96
|
+
};
|
|
97
|
+
|
|
98
|
+
Deno.addSignalListener('SIGINT', shutdown);
|
|
99
|
+
Deno.addSignalListener('SIGTERM', shutdown);
|
|
100
|
+
|
|
101
|
+
// Set up event listeners for logging
|
|
102
|
+
setupEventListeners();
|
|
103
|
+
|
|
104
|
+
if (options.daemon) {
|
|
105
|
+
console.log(colors.gray('Running in daemon mode. Press Ctrl+C to stop.'));
|
|
106
|
+
// Keep the process running
|
|
107
|
+
await new Promise<void>((resolve) => {
|
|
108
|
+
// This promise will only resolve when shutdown is called
|
|
109
|
+
eventBus.once('shutdown', resolve);
|
|
110
|
+
});
|
|
111
|
+
} else {
|
|
112
|
+
console.log(colors.gray('Press Ctrl+C to stop.'));
|
|
113
|
+
// Keep the process running in interactive mode
|
|
114
|
+
await new Promise<void>((resolve) => {
|
|
115
|
+
// This promise will only resolve when shutdown is called
|
|
116
|
+
eventBus.once('shutdown', resolve);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
} catch (error) {
|
|
120
|
+
// spinner.stop();
|
|
121
|
+
throw error;
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
function setupEventListeners(): void {
|
|
126
|
+
// Log important events
|
|
127
|
+
eventBus.on(SystemEvents.AGENT_SPAWNED, (data: any) => {
|
|
128
|
+
const { agentId, profile } = data;
|
|
129
|
+
console.log(colors.blue('→'), `Agent spawned: ${colors.cyan(agentId)} (${profile.type})`);
|
|
130
|
+
});
|
|
131
|
+
|
|
132
|
+
eventBus.on(SystemEvents.AGENT_TERMINATED, (data: any) => {
|
|
133
|
+
const { agentId, reason } = data;
|
|
134
|
+
console.log(colors.red('←'), `Agent terminated: ${colors.cyan(agentId)} - ${reason}`);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
eventBus.on(SystemEvents.TASK_ASSIGNED, (data: any) => {
|
|
138
|
+
const { taskId, agentId } = data;
|
|
139
|
+
console.log(colors.magenta('◆'), `Task ${colors.yellow(taskId)} assigned to ${colors.cyan(agentId)}`);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
eventBus.on(SystemEvents.TASK_COMPLETED, (data: any) => {
|
|
143
|
+
const { taskId } = data;
|
|
144
|
+
console.log(colors.green('✓'), `Task completed: ${colors.yellow(taskId)}`);
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
eventBus.on(SystemEvents.TASK_FAILED, (data: any) => {
|
|
148
|
+
const { taskId, error } = data;
|
|
149
|
+
console.log(colors.red('✗'), `Task failed: ${colors.yellow(taskId)} - ${error.message}`);
|
|
150
|
+
});
|
|
151
|
+
|
|
152
|
+
eventBus.on(SystemEvents.SYSTEM_ERROR, (data: any) => {
|
|
153
|
+
const { component, error } = data;
|
|
154
|
+
console.error(colors.red.bold('System Error:'), `${component} - ${error.message}`);
|
|
155
|
+
});
|
|
156
|
+
}
|
|
@@ -0,0 +1,345 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Status command for Claude-Flow
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from '@cliffy/command';
|
|
6
|
+
import { colors } from '@cliffy/ansi/colors';
|
|
7
|
+
import { Table } from '@cliffy/table';
|
|
8
|
+
import { formatHealthStatus, formatDuration, formatStatusIndicator } from '../formatter.ts';
|
|
9
|
+
|
|
10
|
+
export const statusCommand = new Command()
|
|
11
|
+
.description('Show Claude-Flow system status')
|
|
12
|
+
.option('-w, --watch', 'Watch mode - continuously update status')
|
|
13
|
+
.option('-i, --interval <seconds:number>', 'Update interval in seconds', { default: 5 })
|
|
14
|
+
.option('-c, --component <name:string>', 'Show status for specific component')
|
|
15
|
+
.option('--json', 'Output in JSON format')
|
|
16
|
+
.action(async (options: any) => {
|
|
17
|
+
if (options.watch) {
|
|
18
|
+
await watchStatus(options);
|
|
19
|
+
} else {
|
|
20
|
+
await showStatus(options);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
async function showStatus(options: any): Promise<void> {
|
|
25
|
+
try {
|
|
26
|
+
// In a real implementation, this would connect to the running orchestrator
|
|
27
|
+
const status = await getSystemStatus();
|
|
28
|
+
|
|
29
|
+
if (options.json) {
|
|
30
|
+
console.log(JSON.stringify(status, null, 2));
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (options.component) {
|
|
35
|
+
showComponentStatus(status, options.component);
|
|
36
|
+
} else {
|
|
37
|
+
showFullStatus(status);
|
|
38
|
+
}
|
|
39
|
+
} catch (error) {
|
|
40
|
+
if ((error as Error).message.includes('ECONNREFUSED') || (error as Error).message.includes('connection refused')) {
|
|
41
|
+
console.error(colors.red('✗ Claude-Flow is not running'));
|
|
42
|
+
console.log(colors.gray('Start it with: claude-flow start'));
|
|
43
|
+
} else {
|
|
44
|
+
console.error(colors.red('Error getting status:'), (error as Error).message);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
async function watchStatus(options: any): Promise<void> {
|
|
50
|
+
const interval = options.interval * 1000;
|
|
51
|
+
|
|
52
|
+
console.log(colors.cyan('Watching Claude-Flow status...'));
|
|
53
|
+
console.log(colors.gray(`Update interval: ${options.interval}s`));
|
|
54
|
+
console.log(colors.gray('Press Ctrl+C to stop\n'));
|
|
55
|
+
|
|
56
|
+
// eslint-disable-next-line no-constant-condition
|
|
57
|
+
while (true) {
|
|
58
|
+
// Clear screen and show status
|
|
59
|
+
console.clear();
|
|
60
|
+
console.log(colors.cyan.bold('Claude-Flow Status Monitor'));
|
|
61
|
+
console.log(colors.gray(`Last updated: ${new Date().toLocaleTimeString()}\n`));
|
|
62
|
+
|
|
63
|
+
try {
|
|
64
|
+
await showStatus({ ...options, json: false });
|
|
65
|
+
} catch (error) {
|
|
66
|
+
console.error(colors.red('Status update failed:'), (error as Error).message);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
await new Promise(resolve => setTimeout(resolve, interval));
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function showFullStatus(status: any): void {
|
|
74
|
+
// System overview
|
|
75
|
+
console.log(colors.cyan.bold('System Overview'));
|
|
76
|
+
console.log('─'.repeat(50));
|
|
77
|
+
|
|
78
|
+
const statusIcon = formatStatusIndicator(status.overall);
|
|
79
|
+
console.log(`${statusIcon} Overall Status: ${getStatusColor(status.overall)(status.overall.toUpperCase())}`);
|
|
80
|
+
console.log(`${colors.white('Uptime:')} ${formatDuration(status.uptime)}`);
|
|
81
|
+
console.log(`${colors.white('Version:')} ${status.version}`);
|
|
82
|
+
console.log(`${colors.white('Started:')} ${new Date(status.startTime).toLocaleString()}`);
|
|
83
|
+
console.log();
|
|
84
|
+
|
|
85
|
+
// Components status
|
|
86
|
+
console.log(colors.cyan.bold('Components'));
|
|
87
|
+
console.log('─'.repeat(50));
|
|
88
|
+
|
|
89
|
+
const componentTable = new Table()
|
|
90
|
+
.header(['Component', 'Status', 'Uptime', 'Details'])
|
|
91
|
+
.border(true);
|
|
92
|
+
|
|
93
|
+
for (const [name, component] of Object.entries(status.components)) {
|
|
94
|
+
const comp = component as any;
|
|
95
|
+
const statusIcon = formatStatusIndicator(comp.status);
|
|
96
|
+
const statusText = getStatusColor(comp.status)(comp.status.toUpperCase());
|
|
97
|
+
|
|
98
|
+
componentTable.push([
|
|
99
|
+
colors.white(name),
|
|
100
|
+
`${statusIcon} ${statusText}`,
|
|
101
|
+
formatDuration(comp.uptime || 0),
|
|
102
|
+
comp.details || '-'
|
|
103
|
+
]);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
componentTable.render();
|
|
107
|
+
console.log();
|
|
108
|
+
|
|
109
|
+
// Resource usage
|
|
110
|
+
if (status.resources) {
|
|
111
|
+
console.log(colors.cyan.bold('Resource Usage'));
|
|
112
|
+
console.log('─'.repeat(50));
|
|
113
|
+
|
|
114
|
+
const resourceTable = new Table()
|
|
115
|
+
.header(['Resource', 'Used', 'Total', 'Percentage'])
|
|
116
|
+
.border(true);
|
|
117
|
+
|
|
118
|
+
for (const [name, resource] of Object.entries(status.resources)) {
|
|
119
|
+
const res = resource as any;
|
|
120
|
+
const percentage = ((res.used / res.total) * 100).toFixed(1);
|
|
121
|
+
const color = getResourceColor(parseFloat(percentage));
|
|
122
|
+
|
|
123
|
+
resourceTable.push([
|
|
124
|
+
colors.white(name),
|
|
125
|
+
res.used.toString(),
|
|
126
|
+
res.total.toString(),
|
|
127
|
+
color(`${percentage}%`)
|
|
128
|
+
]);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
resourceTable.render();
|
|
132
|
+
console.log();
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
// Active agents
|
|
136
|
+
if (status.agents) {
|
|
137
|
+
console.log(colors.cyan.bold(`Active Agents (${status.agents.length})`));
|
|
138
|
+
console.log('─'.repeat(50));
|
|
139
|
+
|
|
140
|
+
if (status.agents.length > 0) {
|
|
141
|
+
const agentTable = new Table()
|
|
142
|
+
.header(['ID', 'Name', 'Type', 'Status', 'Tasks'])
|
|
143
|
+
.border(true);
|
|
144
|
+
|
|
145
|
+
for (const agent of status.agents) {
|
|
146
|
+
const statusIcon = formatStatusIndicator(agent.status);
|
|
147
|
+
const statusText = getStatusColor(agent.status)(agent.status);
|
|
148
|
+
|
|
149
|
+
agentTable.push([
|
|
150
|
+
colors.gray(agent.id.substring(0, 8) + '...'),
|
|
151
|
+
colors.white(agent.name),
|
|
152
|
+
colors.cyan(agent.type),
|
|
153
|
+
`${statusIcon} ${statusText}`,
|
|
154
|
+
agent.activeTasks.toString()
|
|
155
|
+
]);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
agentTable.render();
|
|
159
|
+
} else {
|
|
160
|
+
console.log(colors.gray('No active agents'));
|
|
161
|
+
}
|
|
162
|
+
console.log();
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Recent tasks
|
|
166
|
+
if (status.recentTasks) {
|
|
167
|
+
console.log(colors.cyan.bold(`Recent Tasks (${status.recentTasks.length})`));
|
|
168
|
+
console.log('─'.repeat(50));
|
|
169
|
+
|
|
170
|
+
if (status.recentTasks.length > 0) {
|
|
171
|
+
const taskTable = new Table()
|
|
172
|
+
.header(['ID', 'Type', 'Status', 'Agent', 'Duration'])
|
|
173
|
+
.border(true);
|
|
174
|
+
|
|
175
|
+
for (const task of status.recentTasks.slice(0, 10)) { // Show last 10
|
|
176
|
+
const statusIcon = formatStatusIndicator(task.status);
|
|
177
|
+
const statusText = getStatusColor(task.status)(task.status);
|
|
178
|
+
|
|
179
|
+
taskTable.push([
|
|
180
|
+
colors.gray(task.id.substring(0, 8) + '...'),
|
|
181
|
+
colors.white(task.type),
|
|
182
|
+
`${statusIcon} ${statusText}`,
|
|
183
|
+
task.agent ? colors.cyan(task.agent.substring(0, 12) + '...') : '-',
|
|
184
|
+
task.duration ? formatDuration(task.duration) : '-'
|
|
185
|
+
]);
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
taskTable.render();
|
|
189
|
+
} else {
|
|
190
|
+
console.log(colors.gray('No recent tasks'));
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
function showComponentStatus(status: any, componentName: string): void {
|
|
196
|
+
const component = status.components[componentName];
|
|
197
|
+
|
|
198
|
+
if (!component) {
|
|
199
|
+
console.error(colors.red(`Component '${componentName}' not found`));
|
|
200
|
+
console.log(colors.gray('Available components:'), Object.keys(status.components).join(', '));
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
console.log(colors.cyan.bold(`${componentName} Status`));
|
|
205
|
+
console.log('─'.repeat(30));
|
|
206
|
+
|
|
207
|
+
const statusIcon = formatStatusIndicator(component.status);
|
|
208
|
+
console.log(`${statusIcon} Status: ${getStatusColor(component.status)(component.status.toUpperCase())}`);
|
|
209
|
+
|
|
210
|
+
if (component.uptime) {
|
|
211
|
+
console.log(`${colors.white('Uptime:')} ${formatDuration(component.uptime)}`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if (component.details) {
|
|
215
|
+
console.log(`${colors.white('Details:')} ${component.details}`);
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
if (component.metrics) {
|
|
219
|
+
console.log('\n' + colors.cyan.bold('Metrics'));
|
|
220
|
+
console.log('─'.repeat(20));
|
|
221
|
+
|
|
222
|
+
for (const [metric, value] of Object.entries(component.metrics)) {
|
|
223
|
+
console.log(`${colors.white(metric + ':')} ${value}`);
|
|
224
|
+
}
|
|
225
|
+
}
|
|
226
|
+
|
|
227
|
+
if (component.errors && component.errors.length > 0) {
|
|
228
|
+
console.log('\n' + colors.red.bold('Recent Errors'));
|
|
229
|
+
console.log('─'.repeat(20));
|
|
230
|
+
|
|
231
|
+
for (const error of component.errors.slice(0, 5)) {
|
|
232
|
+
console.log(colors.red(`• ${error.message}`));
|
|
233
|
+
console.log(colors.gray(` ${new Date(error.timestamp).toLocaleString()}`));
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
async function getSystemStatus(): Promise<any> {
|
|
239
|
+
// Mock status for now - in production, this would call the orchestrator API
|
|
240
|
+
return {
|
|
241
|
+
overall: 'healthy',
|
|
242
|
+
version: '1.0.0',
|
|
243
|
+
uptime: Date.now() - (Date.now() - 3600000), // 1 hour ago
|
|
244
|
+
startTime: new Date(Date.now() - 3600000),
|
|
245
|
+
components: {
|
|
246
|
+
orchestrator: {
|
|
247
|
+
status: 'healthy',
|
|
248
|
+
uptime: 3600000,
|
|
249
|
+
details: 'Managing 3 agents'
|
|
250
|
+
},
|
|
251
|
+
terminal: {
|
|
252
|
+
status: 'healthy',
|
|
253
|
+
uptime: 3600000,
|
|
254
|
+
details: 'Pool: 2/5 active sessions'
|
|
255
|
+
},
|
|
256
|
+
memory: {
|
|
257
|
+
status: 'healthy',
|
|
258
|
+
uptime: 3600000,
|
|
259
|
+
details: 'SQLite + 95MB cache'
|
|
260
|
+
},
|
|
261
|
+
coordination: {
|
|
262
|
+
status: 'healthy',
|
|
263
|
+
uptime: 3600000,
|
|
264
|
+
details: '12 active tasks'
|
|
265
|
+
},
|
|
266
|
+
mcp: {
|
|
267
|
+
status: 'healthy',
|
|
268
|
+
uptime: 3600000,
|
|
269
|
+
details: 'Listening on stdio'
|
|
270
|
+
}
|
|
271
|
+
},
|
|
272
|
+
resources: {
|
|
273
|
+
'Memory (MB)': { used: 256, total: 1024 },
|
|
274
|
+
'CPU (%)': { used: 15, total: 100 },
|
|
275
|
+
'Agents': { used: 3, total: 10 },
|
|
276
|
+
'Tasks': { used: 12, total: 100 }
|
|
277
|
+
},
|
|
278
|
+
agents: [
|
|
279
|
+
{
|
|
280
|
+
id: 'agent-001',
|
|
281
|
+
name: 'Coordinator Agent',
|
|
282
|
+
type: 'coordinator',
|
|
283
|
+
status: 'active',
|
|
284
|
+
activeTasks: 2
|
|
285
|
+
},
|
|
286
|
+
{
|
|
287
|
+
id: 'agent-002',
|
|
288
|
+
name: 'Research Agent',
|
|
289
|
+
type: 'researcher',
|
|
290
|
+
status: 'active',
|
|
291
|
+
activeTasks: 5
|
|
292
|
+
},
|
|
293
|
+
{
|
|
294
|
+
id: 'agent-003',
|
|
295
|
+
name: 'Implementation Agent',
|
|
296
|
+
type: 'implementer',
|
|
297
|
+
status: 'idle',
|
|
298
|
+
activeTasks: 0
|
|
299
|
+
}
|
|
300
|
+
],
|
|
301
|
+
recentTasks: [
|
|
302
|
+
{
|
|
303
|
+
id: 'task-001',
|
|
304
|
+
type: 'research',
|
|
305
|
+
status: 'completed',
|
|
306
|
+
agent: 'agent-002',
|
|
307
|
+
duration: 45000
|
|
308
|
+
},
|
|
309
|
+
{
|
|
310
|
+
id: 'task-002',
|
|
311
|
+
type: 'coordination',
|
|
312
|
+
status: 'running',
|
|
313
|
+
agent: 'agent-001',
|
|
314
|
+
duration: null
|
|
315
|
+
}
|
|
316
|
+
]
|
|
317
|
+
};
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
function getStatusColor(status: string) {
|
|
321
|
+
switch (status.toLowerCase()) {
|
|
322
|
+
case 'healthy':
|
|
323
|
+
case 'active':
|
|
324
|
+
case 'completed':
|
|
325
|
+
return colors.green;
|
|
326
|
+
case 'degraded':
|
|
327
|
+
case 'warning':
|
|
328
|
+
case 'idle':
|
|
329
|
+
return colors.yellow;
|
|
330
|
+
case 'unhealthy':
|
|
331
|
+
case 'error':
|
|
332
|
+
case 'failed':
|
|
333
|
+
return colors.red;
|
|
334
|
+
case 'running':
|
|
335
|
+
return colors.cyan;
|
|
336
|
+
default:
|
|
337
|
+
return colors.white;
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
function getResourceColor(percentage: number) {
|
|
342
|
+
if (percentage >= 90) return colors.red;
|
|
343
|
+
if (percentage >= 75) return colors.yellow;
|
|
344
|
+
return colors.green;
|
|
345
|
+
}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Task management commands
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from '@cliffy/command';
|
|
6
|
+
import { colors } from '@cliffy/ansi/colors';
|
|
7
|
+
import { Task } from '../../utils/types.ts';
|
|
8
|
+
import { generateId } from '../../utils/helpers.ts';
|
|
9
|
+
|
|
10
|
+
export const taskCommand = new Command()
|
|
11
|
+
.description('Manage tasks')
|
|
12
|
+
.action(() => {
|
|
13
|
+
taskCommand.showHelp();
|
|
14
|
+
})
|
|
15
|
+
.command('create', new Command()
|
|
16
|
+
.description('Create a new task')
|
|
17
|
+
.arguments('<type:string> <description:string>')
|
|
18
|
+
.option('-p, --priority <priority:number>', 'Task priority', { default: 0 })
|
|
19
|
+
.option('-d, --dependencies <deps:string>', 'Comma-separated list of dependency task IDs')
|
|
20
|
+
.option('-i, --input <input:string>', 'Task input as JSON')
|
|
21
|
+
.option('-a, --assign <agent:string>', 'Assign to specific agent')
|
|
22
|
+
.action(async (options: any, type: string, description: string) => {
|
|
23
|
+
const task: Task = {
|
|
24
|
+
id: generateId('task'),
|
|
25
|
+
type,
|
|
26
|
+
description,
|
|
27
|
+
priority: options.priority,
|
|
28
|
+
dependencies: options.dependencies ? options.dependencies.split(',') : [],
|
|
29
|
+
assignedAgent: options.assign,
|
|
30
|
+
status: 'pending',
|
|
31
|
+
input: options.input ? JSON.parse(options.input) : {},
|
|
32
|
+
createdAt: new Date(),
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
console.log(colors.green('Task created:'));
|
|
36
|
+
console.log(JSON.stringify(task, null, 2));
|
|
37
|
+
console.log(colors.yellow('\nTo submit this task, ensure Claude-Flow is running'));
|
|
38
|
+
}),
|
|
39
|
+
)
|
|
40
|
+
.command('list', new Command()
|
|
41
|
+
.description('List all tasks')
|
|
42
|
+
.option('-s, --status <status:string>', 'Filter by status')
|
|
43
|
+
.option('-a, --agent <agent:string>', 'Filter by assigned agent')
|
|
44
|
+
.action(async (options: any) => {
|
|
45
|
+
console.log(colors.yellow('Task listing requires a running Claude-Flow instance'));
|
|
46
|
+
}),
|
|
47
|
+
)
|
|
48
|
+
.command('status', new Command()
|
|
49
|
+
.description('Get task status')
|
|
50
|
+
.arguments('<task-id:string>')
|
|
51
|
+
.action(async (options: any, taskId: string) => {
|
|
52
|
+
console.log(colors.yellow(`Task status requires a running Claude-Flow instance`));
|
|
53
|
+
}),
|
|
54
|
+
)
|
|
55
|
+
.command('cancel', new Command()
|
|
56
|
+
.description('Cancel a task')
|
|
57
|
+
.arguments('<task-id:string>')
|
|
58
|
+
.option('-r, --reason <reason:string>', 'Cancellation reason')
|
|
59
|
+
.action(async (options: any, taskId: string) => {
|
|
60
|
+
console.log(colors.yellow(`Cancelling task ${taskId} requires a running Claude-Flow instance`));
|
|
61
|
+
}),
|
|
62
|
+
)
|
|
63
|
+
.command('workflow', new Command()
|
|
64
|
+
.description('Execute a workflow from file')
|
|
65
|
+
.arguments('<workflow-file:string>')
|
|
66
|
+
.action(async (options: any, workflowFile: string) => {
|
|
67
|
+
try {
|
|
68
|
+
const content = await Deno.readTextFile(workflowFile);
|
|
69
|
+
const workflow = JSON.parse(content);
|
|
70
|
+
|
|
71
|
+
console.log(colors.green('Workflow loaded:'));
|
|
72
|
+
console.log(`- Name: ${workflow.name || 'Unnamed'}`);
|
|
73
|
+
console.log(`- Tasks: ${workflow.tasks?.length || 0}`);
|
|
74
|
+
console.log(colors.yellow('\nTo execute this workflow, ensure Claude-Flow is running'));
|
|
75
|
+
} catch (error) {
|
|
76
|
+
console.error(colors.red('Failed to load workflow:'), (error as Error).message);
|
|
77
|
+
}
|
|
78
|
+
}),
|
|
79
|
+
);
|