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,288 @@
|
|
|
1
|
+
#!/usr/bin/env deno run --allow-read
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Example Configuration Validator
|
|
5
|
+
* Validates all example configuration files for correctness
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { walk } from "https://deno.land/std@0.220.0/fs/mod.ts";
|
|
9
|
+
|
|
10
|
+
interface ValidationResult {
|
|
11
|
+
file: string;
|
|
12
|
+
valid: boolean;
|
|
13
|
+
errors: string[];
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
interface ConfigSchema {
|
|
17
|
+
[key: string]: {
|
|
18
|
+
type: string;
|
|
19
|
+
required?: boolean;
|
|
20
|
+
properties?: ConfigSchema;
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const CLAUDE_FLOW_CONFIG_SCHEMA: ConfigSchema = {
|
|
25
|
+
orchestrator: {
|
|
26
|
+
type: 'object',
|
|
27
|
+
required: true,
|
|
28
|
+
properties: {
|
|
29
|
+
maxConcurrentAgents: { type: 'number' },
|
|
30
|
+
taskQueueSize: { type: 'number' },
|
|
31
|
+
healthCheckInterval: { type: 'number' },
|
|
32
|
+
shutdownTimeout: { type: 'number' },
|
|
33
|
+
},
|
|
34
|
+
},
|
|
35
|
+
terminal: {
|
|
36
|
+
type: 'object',
|
|
37
|
+
properties: {
|
|
38
|
+
type: { type: 'string' },
|
|
39
|
+
poolSize: { type: 'number' },
|
|
40
|
+
recycleAfter: { type: 'number' },
|
|
41
|
+
healthCheckInterval: { type: 'number' },
|
|
42
|
+
commandTimeout: { type: 'number' },
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
memory: {
|
|
46
|
+
type: 'object',
|
|
47
|
+
properties: {
|
|
48
|
+
backend: { type: 'string' },
|
|
49
|
+
cacheSizeMB: { type: 'number' },
|
|
50
|
+
syncInterval: { type: 'number' },
|
|
51
|
+
conflictResolution: { type: 'string' },
|
|
52
|
+
retentionDays: { type: 'number' },
|
|
53
|
+
},
|
|
54
|
+
},
|
|
55
|
+
coordination: {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: {
|
|
58
|
+
maxRetries: { type: 'number' },
|
|
59
|
+
retryDelay: { type: 'number' },
|
|
60
|
+
deadlockDetection: { type: 'boolean' },
|
|
61
|
+
resourceTimeout: { type: 'number' },
|
|
62
|
+
messageTimeout: { type: 'number' },
|
|
63
|
+
},
|
|
64
|
+
},
|
|
65
|
+
mcp: {
|
|
66
|
+
type: 'object',
|
|
67
|
+
properties: {
|
|
68
|
+
transport: { type: 'string' },
|
|
69
|
+
port: { type: 'number' },
|
|
70
|
+
tlsEnabled: { type: 'boolean' },
|
|
71
|
+
},
|
|
72
|
+
},
|
|
73
|
+
logging: {
|
|
74
|
+
type: 'object',
|
|
75
|
+
properties: {
|
|
76
|
+
level: { type: 'string' },
|
|
77
|
+
format: { type: 'string' },
|
|
78
|
+
destination: { type: 'string' },
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
const WORKFLOW_SCHEMA: ConfigSchema = {
|
|
84
|
+
name: { type: 'string', required: true },
|
|
85
|
+
description: { type: 'string' },
|
|
86
|
+
tasks: {
|
|
87
|
+
type: 'array',
|
|
88
|
+
required: true,
|
|
89
|
+
properties: {
|
|
90
|
+
id: { type: 'string', required: true },
|
|
91
|
+
type: { type: 'string', required: true },
|
|
92
|
+
description: { type: 'string', required: true },
|
|
93
|
+
dependencies: { type: 'array' },
|
|
94
|
+
assignTo: { type: 'string' },
|
|
95
|
+
priority: { type: 'string' },
|
|
96
|
+
timeout: { type: 'number' },
|
|
97
|
+
},
|
|
98
|
+
},
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
function validateType(value: any, expectedType: string): boolean {
|
|
102
|
+
switch (expectedType) {
|
|
103
|
+
case 'string':
|
|
104
|
+
return typeof value === 'string';
|
|
105
|
+
case 'number':
|
|
106
|
+
return typeof value === 'number';
|
|
107
|
+
case 'boolean':
|
|
108
|
+
return typeof value === 'boolean';
|
|
109
|
+
case 'array':
|
|
110
|
+
return Array.isArray(value);
|
|
111
|
+
case 'object':
|
|
112
|
+
return typeof value === 'object' && value !== null && !Array.isArray(value);
|
|
113
|
+
default:
|
|
114
|
+
return false;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
function validateObject(obj: any, schema: ConfigSchema, path = ''): string[] {
|
|
119
|
+
const errors: string[] = [];
|
|
120
|
+
|
|
121
|
+
// Check required fields
|
|
122
|
+
for (const [key, spec] of Object.entries(schema)) {
|
|
123
|
+
if (spec.required && !(key in obj)) {
|
|
124
|
+
errors.push(`${path}${key} is required but missing`);
|
|
125
|
+
continue;
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (key in obj) {
|
|
129
|
+
const value = obj[key];
|
|
130
|
+
const currentPath = path ? `${path}${key}.` : `${key}.`;
|
|
131
|
+
|
|
132
|
+
if (!validateType(value, spec.type)) {
|
|
133
|
+
errors.push(`${path}${key} should be of type ${spec.type}, got ${typeof value}`);
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
// Validate nested objects
|
|
138
|
+
if (spec.type === 'object' && spec.properties) {
|
|
139
|
+
errors.push(...validateObject(value, spec.properties, currentPath));
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Validate array items
|
|
143
|
+
if (spec.type === 'array' && spec.properties && Array.isArray(value)) {
|
|
144
|
+
value.forEach((item, index) => {
|
|
145
|
+
if (typeof item === 'object') {
|
|
146
|
+
errors.push(...validateObject(item, spec.properties!, `${currentPath}[${index}].`));
|
|
147
|
+
}
|
|
148
|
+
});
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
return errors;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
function validateClaudeFlowConfig(config: any): string[] {
|
|
157
|
+
return validateObject(config, CLAUDE_FLOW_CONFIG_SCHEMA);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
function validateWorkflow(workflow: any): string[] {
|
|
161
|
+
const errors = validateObject(workflow, WORKFLOW_SCHEMA);
|
|
162
|
+
|
|
163
|
+
// Additional workflow-specific validations
|
|
164
|
+
if (workflow.tasks && Array.isArray(workflow.tasks)) {
|
|
165
|
+
const taskIds = new Set<string>();
|
|
166
|
+
|
|
167
|
+
for (const [index, task] of workflow.tasks.entries()) {
|
|
168
|
+
// Check for duplicate task IDs
|
|
169
|
+
if (taskIds.has(task.id)) {
|
|
170
|
+
errors.push(`Duplicate task ID "${task.id}" found at index ${index}`);
|
|
171
|
+
} else {
|
|
172
|
+
taskIds.add(task.id);
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Validate dependencies reference existing tasks
|
|
176
|
+
if (task.dependencies && Array.isArray(task.dependencies)) {
|
|
177
|
+
for (const dep of task.dependencies) {
|
|
178
|
+
if (!taskIds.has(dep) && !workflow.tasks.slice(0, index).some((t: any) => t.id === dep)) {
|
|
179
|
+
errors.push(`Task "${task.id}" depends on non-existent task "${dep}"`);
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
// Validate priority values
|
|
185
|
+
if (task.priority && !['low', 'medium', 'high', 'critical'].includes(task.priority)) {
|
|
186
|
+
errors.push(`Task "${task.id}" has invalid priority "${task.priority}"`);
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
// Validate timeout is positive
|
|
190
|
+
if (task.timeout && task.timeout <= 0) {
|
|
191
|
+
errors.push(`Task "${task.id}" has invalid timeout ${task.timeout}`);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
return errors;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
async function validateFile(filePath: string): Promise<ValidationResult> {
|
|
200
|
+
const result: ValidationResult = {
|
|
201
|
+
file: filePath,
|
|
202
|
+
valid: false,
|
|
203
|
+
errors: [],
|
|
204
|
+
};
|
|
205
|
+
|
|
206
|
+
try {
|
|
207
|
+
const content = await Deno.readTextFile(filePath);
|
|
208
|
+
const config = JSON.parse(content);
|
|
209
|
+
|
|
210
|
+
// Determine validation type based on file name/content
|
|
211
|
+
if (filePath.includes('workflow') || config.tasks) {
|
|
212
|
+
result.errors = validateWorkflow(config);
|
|
213
|
+
} else if (filePath.includes('config') || config.orchestrator) {
|
|
214
|
+
result.errors = validateClaudeFlowConfig(config);
|
|
215
|
+
} else {
|
|
216
|
+
result.errors.push('Unknown configuration file type');
|
|
217
|
+
}
|
|
218
|
+
|
|
219
|
+
result.valid = result.errors.length === 0;
|
|
220
|
+
} catch (error) {
|
|
221
|
+
if (error instanceof SyntaxError) {
|
|
222
|
+
result.errors.push(`Invalid JSON: ${error.message}`);
|
|
223
|
+
} else {
|
|
224
|
+
result.errors.push(`Failed to read file: ${error.message}`);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return result;
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
async function main(): Promise<void> {
|
|
232
|
+
console.log('Validating example configurations...\n');
|
|
233
|
+
|
|
234
|
+
const results: ValidationResult[] = [];
|
|
235
|
+
|
|
236
|
+
// Find all JSON files in examples directory
|
|
237
|
+
for await (const entry of walk('./examples', { exts: ['.json'] })) {
|
|
238
|
+
if (entry.isFile) {
|
|
239
|
+
const result = await validateFile(entry.path);
|
|
240
|
+
results.push(result);
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
// Also check any config files in the root
|
|
245
|
+
const rootConfigFiles = ['claude-flow.config.json', 'config.json'];
|
|
246
|
+
for (const filename of rootConfigFiles) {
|
|
247
|
+
try {
|
|
248
|
+
await Deno.stat(filename);
|
|
249
|
+
const result = await validateFile(filename);
|
|
250
|
+
results.push(result);
|
|
251
|
+
} catch {
|
|
252
|
+
// File doesn't exist, skip
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
if (results.length === 0) {
|
|
257
|
+
console.log('No configuration files found to validate.');
|
|
258
|
+
return;
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Report results
|
|
262
|
+
let hasErrors = false;
|
|
263
|
+
|
|
264
|
+
for (const result of results) {
|
|
265
|
+
if (result.valid) {
|
|
266
|
+
console.log(`✅ ${result.file}: Valid`);
|
|
267
|
+
} else {
|
|
268
|
+
console.log(`❌ ${result.file}: Invalid`);
|
|
269
|
+
for (const error of result.errors) {
|
|
270
|
+
console.log(` - ${error}`);
|
|
271
|
+
}
|
|
272
|
+
hasErrors = true;
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
console.log(`\nValidated ${results.length} configuration files.`);
|
|
277
|
+
|
|
278
|
+
if (hasErrors) {
|
|
279
|
+
console.error('❌ Some configuration files have errors!');
|
|
280
|
+
Deno.exit(1);
|
|
281
|
+
} else {
|
|
282
|
+
console.log('✅ All configuration files are valid!');
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
|
|
286
|
+
if (import.meta.main) {
|
|
287
|
+
await main();
|
|
288
|
+
}
|
|
@@ -0,0 +1,273 @@
|
|
|
1
|
+
#!/usr/bin/env -S deno run --allow-all
|
|
2
|
+
/**
|
|
3
|
+
* Claude-Flow CLI - Core implementation without external dependencies
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import { parse } from "https://deno.land/std@0.224.0/flags/mod.ts";
|
|
7
|
+
import { red, green, yellow, blue, bold, cyan } from "https://deno.land/std@0.224.0/fmt/colors.ts";
|
|
8
|
+
import { ensureDir } from "https://deno.land/std@0.224.0/fs/mod.ts";
|
|
9
|
+
import { join } from "https://deno.land/std@0.224.0/path/mod.ts";
|
|
10
|
+
|
|
11
|
+
export const VERSION = "1.0.0";
|
|
12
|
+
|
|
13
|
+
interface CommandContext {
|
|
14
|
+
args: string[];
|
|
15
|
+
flags: Record<string, unknown>;
|
|
16
|
+
config?: Record<string, unknown> | undefined;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface Command {
|
|
20
|
+
name: string;
|
|
21
|
+
description: string;
|
|
22
|
+
aliases?: string[];
|
|
23
|
+
subcommands?: Command[];
|
|
24
|
+
action?: (ctx: CommandContext) => Promise<void> | void;
|
|
25
|
+
options?: Option[];
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
interface Option {
|
|
29
|
+
name: string;
|
|
30
|
+
short?: string;
|
|
31
|
+
description: string;
|
|
32
|
+
type?: "string" | "boolean" | "number";
|
|
33
|
+
default?: unknown;
|
|
34
|
+
required?: boolean;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
class CLI {
|
|
38
|
+
private commands: Map<string, Command> = new Map();
|
|
39
|
+
private globalOptions: Option[] = [
|
|
40
|
+
{
|
|
41
|
+
name: "help",
|
|
42
|
+
short: "h",
|
|
43
|
+
description: "Show help",
|
|
44
|
+
type: "boolean",
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
name: "version",
|
|
48
|
+
short: "v",
|
|
49
|
+
description: "Show version",
|
|
50
|
+
type: "boolean",
|
|
51
|
+
},
|
|
52
|
+
{
|
|
53
|
+
name: "config",
|
|
54
|
+
short: "c",
|
|
55
|
+
description: "Path to configuration file",
|
|
56
|
+
type: "string",
|
|
57
|
+
},
|
|
58
|
+
{
|
|
59
|
+
name: "verbose",
|
|
60
|
+
description: "Enable verbose logging",
|
|
61
|
+
type: "boolean",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
name: "log-level",
|
|
65
|
+
description: "Set log level (debug, info, warn, error)",
|
|
66
|
+
type: "string",
|
|
67
|
+
default: "info",
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
constructor(private name: string, private description: string) {}
|
|
72
|
+
|
|
73
|
+
command(cmd: Command): this {
|
|
74
|
+
this.commands.set(cmd.name, cmd);
|
|
75
|
+
if (cmd.aliases) {
|
|
76
|
+
for (const alias of cmd.aliases) {
|
|
77
|
+
this.commands.set(alias, cmd);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return this;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
async run(args = Deno.args): Promise<void> {
|
|
84
|
+
const flags = parse(args, {
|
|
85
|
+
boolean: this.getBooleanFlags(),
|
|
86
|
+
string: this.getStringFlags(),
|
|
87
|
+
alias: this.getAliases(),
|
|
88
|
+
default: this.getDefaults(),
|
|
89
|
+
stopEarly: true,
|
|
90
|
+
unknown: () => true,
|
|
91
|
+
});
|
|
92
|
+
|
|
93
|
+
if (flags.version || flags.v) {
|
|
94
|
+
console.log(`${this.name} v${VERSION}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const commandName = flags._[0]?.toString() || "";
|
|
99
|
+
|
|
100
|
+
if (!commandName || flags.help || flags.h) {
|
|
101
|
+
this.showHelp();
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
const command = this.commands.get(commandName);
|
|
106
|
+
if (!command) {
|
|
107
|
+
console.error(red(`Unknown command: ${commandName}`));
|
|
108
|
+
console.log(`Run "${this.name} help" for available commands`);
|
|
109
|
+
Deno.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const ctx: CommandContext = {
|
|
113
|
+
args: flags._.slice(1).map(String),
|
|
114
|
+
flags: flags as Record<string, unknown>,
|
|
115
|
+
config: await this.loadConfig(flags.config as string),
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
try {
|
|
119
|
+
if (command.action) {
|
|
120
|
+
await command.action(ctx);
|
|
121
|
+
} else {
|
|
122
|
+
console.log(yellow(`Command '${commandName}' has no action defined`));
|
|
123
|
+
}
|
|
124
|
+
} catch (error) {
|
|
125
|
+
console.error(red(`Error executing command '${commandName}':`), (error as Error).message);
|
|
126
|
+
if (flags.verbose) {
|
|
127
|
+
console.error(error);
|
|
128
|
+
}
|
|
129
|
+
Deno.exit(1);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
private async loadConfig(configPath?: string): Promise<Record<string, unknown> | undefined> {
|
|
134
|
+
const path = configPath || "claude-flow.config.json";
|
|
135
|
+
try {
|
|
136
|
+
const content = await Deno.readTextFile(path);
|
|
137
|
+
return JSON.parse(content);
|
|
138
|
+
} catch {
|
|
139
|
+
return undefined;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
private getBooleanFlags(): string[] {
|
|
144
|
+
const flags: string[] = [];
|
|
145
|
+
for (const opt of [...this.globalOptions, ...this.getAllOptions()]) {
|
|
146
|
+
if (opt.type === "boolean") {
|
|
147
|
+
flags.push(opt.name);
|
|
148
|
+
if (opt.short) flags.push(opt.short);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
return flags;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
private getStringFlags(): string[] {
|
|
155
|
+
const flags: string[] = [];
|
|
156
|
+
for (const opt of [...this.globalOptions, ...this.getAllOptions()]) {
|
|
157
|
+
if (opt.type === "string" || opt.type === "number") {
|
|
158
|
+
flags.push(opt.name);
|
|
159
|
+
if (opt.short) flags.push(opt.short);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
return flags;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
private getAliases(): Record<string, string> {
|
|
166
|
+
const aliases: Record<string, string> = {};
|
|
167
|
+
for (const opt of [...this.globalOptions, ...this.getAllOptions()]) {
|
|
168
|
+
if (opt.short) {
|
|
169
|
+
aliases[opt.short] = opt.name;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return aliases;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
private getDefaults(): Record<string, unknown> {
|
|
176
|
+
const defaults: Record<string, unknown> = {};
|
|
177
|
+
for (const opt of [...this.globalOptions, ...this.getAllOptions()]) {
|
|
178
|
+
if (opt.default !== undefined) {
|
|
179
|
+
defaults[opt.name] = opt.default;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return defaults;
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
private getAllOptions(): Option[] {
|
|
186
|
+
const options: Option[] = [];
|
|
187
|
+
for (const cmd of this.commands.values()) {
|
|
188
|
+
if (cmd.options) {
|
|
189
|
+
options.push(...cmd.options);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
return options;
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
private showHelp(): void {
|
|
196
|
+
console.log(`
|
|
197
|
+
${bold(blue(`🧠 ${this.name} v${VERSION}`))} - ${this.description}
|
|
198
|
+
|
|
199
|
+
${bold("USAGE:")}
|
|
200
|
+
${this.name} [COMMAND] [OPTIONS]
|
|
201
|
+
|
|
202
|
+
${bold("COMMANDS:")}
|
|
203
|
+
${this.formatCommands()}
|
|
204
|
+
|
|
205
|
+
${bold("GLOBAL OPTIONS:")}
|
|
206
|
+
${this.formatOptions(this.globalOptions)}
|
|
207
|
+
|
|
208
|
+
${bold("EXAMPLES:")}
|
|
209
|
+
${this.name} start # Start orchestrator
|
|
210
|
+
${this.name} agent spawn researcher --name "Bot" # Spawn research agent
|
|
211
|
+
${this.name} task create research "Analyze data" # Create task
|
|
212
|
+
${this.name} config init # Initialize config
|
|
213
|
+
${this.name} status # Show system status
|
|
214
|
+
|
|
215
|
+
For more detailed help on specific commands, use:
|
|
216
|
+
${this.name} [COMMAND] --help
|
|
217
|
+
|
|
218
|
+
Documentation: https://github.com/ruvnet/claude-code-flow
|
|
219
|
+
Issues: https://github.com/ruvnet/claude-code-flow/issues
|
|
220
|
+
|
|
221
|
+
Created by rUv - Built with ❤️ for the Claude community
|
|
222
|
+
`);
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
private formatCommands(): string {
|
|
226
|
+
const commands = Array.from(new Set(this.commands.values()));
|
|
227
|
+
return commands
|
|
228
|
+
.map(cmd => ` ${cmd.name.padEnd(20)} ${cmd.description}`)
|
|
229
|
+
.join("\n");
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
private formatOptions(options: Option[]): string {
|
|
233
|
+
return options
|
|
234
|
+
.map(opt => {
|
|
235
|
+
const flags = opt.short ? `-${opt.short}, --${opt.name}` : ` --${opt.name}`;
|
|
236
|
+
return ` ${flags.padEnd(25)} ${opt.description}`;
|
|
237
|
+
})
|
|
238
|
+
.join("\n");
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
// Helper functions
|
|
243
|
+
function success(message: string): void {
|
|
244
|
+
console.log(green(`✅ ${message}`));
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
function error(message: string): void {
|
|
248
|
+
console.error(red(`❌ ${message}`));
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
function warning(message: string): void {
|
|
252
|
+
console.warn(yellow(`⚠️ ${message}`));
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
function info(message: string): void {
|
|
256
|
+
console.log(blue(`ℹ️ ${message}`));
|
|
257
|
+
}
|
|
258
|
+
|
|
259
|
+
// Export for use in other modules
|
|
260
|
+
export { CLI, success, error, warning, info };
|
|
261
|
+
export type { Command, CommandContext, Option };
|
|
262
|
+
|
|
263
|
+
// Main CLI setup if running directly
|
|
264
|
+
if (import.meta.main) {
|
|
265
|
+
const cli = new CLI("claude-flow", "Advanced AI Agent Orchestration System");
|
|
266
|
+
|
|
267
|
+
// Import and register all commands
|
|
268
|
+
const { setupCommands } = await import("./commands/index.ts");
|
|
269
|
+
setupCommands(cli);
|
|
270
|
+
|
|
271
|
+
// Run the CLI
|
|
272
|
+
await cli.run();
|
|
273
|
+
}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Agent management commands
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from '@cliffy/command';
|
|
6
|
+
import { Table } from '@cliffy/table';
|
|
7
|
+
import { colors } from '@cliffy/ansi/colors';
|
|
8
|
+
import { AgentProfile } from '../../utils/types.ts';
|
|
9
|
+
import { generateId } from '../../utils/helpers.ts';
|
|
10
|
+
|
|
11
|
+
export const agentCommand = new Command()
|
|
12
|
+
.description('Manage Claude-Flow agents')
|
|
13
|
+
.action(() => {
|
|
14
|
+
agentCommand.showHelp();
|
|
15
|
+
})
|
|
16
|
+
.command('list', new Command()
|
|
17
|
+
.description('List all agents')
|
|
18
|
+
.action(async () => {
|
|
19
|
+
// In a real implementation, this would connect to the running orchestrator
|
|
20
|
+
console.log(colors.yellow('Agent listing requires a running Claude-Flow instance'));
|
|
21
|
+
}),
|
|
22
|
+
)
|
|
23
|
+
.command('spawn', new Command()
|
|
24
|
+
.description('Spawn a new agent')
|
|
25
|
+
.arguments('<type:string>')
|
|
26
|
+
.option('-n, --name <name:string>', 'Agent name')
|
|
27
|
+
.option('-p, --priority <priority:number>', 'Agent priority', { default: 0 })
|
|
28
|
+
.option('-m, --max-tasks <max:number>', 'Maximum concurrent tasks', { default: 5 })
|
|
29
|
+
.option('--system-prompt <prompt:string>', 'Custom system prompt')
|
|
30
|
+
.action(async (options: any, type: string) => {
|
|
31
|
+
const profile: AgentProfile = {
|
|
32
|
+
id: generateId('agent'),
|
|
33
|
+
name: options.name || `${type}-agent`,
|
|
34
|
+
type: type as any,
|
|
35
|
+
capabilities: getCapabilitiesForType(type),
|
|
36
|
+
systemPrompt: options.systemPrompt || getDefaultPromptForType(type),
|
|
37
|
+
maxConcurrentTasks: options.maxTasks,
|
|
38
|
+
priority: options.priority,
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
console.log(colors.green('Agent profile created:'));
|
|
42
|
+
console.log(JSON.stringify(profile, null, 2));
|
|
43
|
+
console.log(colors.yellow('\nTo spawn this agent, ensure Claude-Flow is running'));
|
|
44
|
+
}),
|
|
45
|
+
)
|
|
46
|
+
.command('terminate', new Command()
|
|
47
|
+
.description('Terminate an agent')
|
|
48
|
+
.arguments('<agent-id:string>')
|
|
49
|
+
.action(async (options: any, agentId: string) => {
|
|
50
|
+
console.log(colors.yellow(`Terminating agent ${agentId} requires a running Claude-Flow instance`));
|
|
51
|
+
}),
|
|
52
|
+
)
|
|
53
|
+
.command('info', new Command()
|
|
54
|
+
.description('Get information about an agent')
|
|
55
|
+
.arguments('<agent-id:string>')
|
|
56
|
+
.action(async (options: any, agentId: string) => {
|
|
57
|
+
console.log(colors.yellow(`Agent info requires a running Claude-Flow instance`));
|
|
58
|
+
}),
|
|
59
|
+
);
|
|
60
|
+
|
|
61
|
+
function getCapabilitiesForType(type: string): string[] {
|
|
62
|
+
const capabilities: Record<string, string[]> = {
|
|
63
|
+
coordinator: ['task-assignment', 'planning', 'delegation'],
|
|
64
|
+
researcher: ['web-search', 'information-gathering', 'analysis'],
|
|
65
|
+
implementer: ['code-generation', 'file-manipulation', 'testing'],
|
|
66
|
+
analyst: ['data-analysis', 'pattern-recognition', 'reporting'],
|
|
67
|
+
custom: ['user-defined'],
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
return capabilities[type] || capabilities.custom;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
function getDefaultPromptForType(type: string): string {
|
|
74
|
+
const prompts: Record<string, string> = {
|
|
75
|
+
coordinator: 'You are a coordination agent responsible for planning and delegating tasks.',
|
|
76
|
+
researcher: 'You are a research agent specialized in gathering and analyzing information.',
|
|
77
|
+
implementer: 'You are an implementation agent focused on writing code and creating solutions.',
|
|
78
|
+
analyst: 'You are an analysis agent that identifies patterns and generates insights.',
|
|
79
|
+
custom: 'You are a custom agent. Follow the user\'s instructions.',
|
|
80
|
+
};
|
|
81
|
+
|
|
82
|
+
return prompts[type] || prompts.custom;
|
|
83
|
+
}
|