agentic-flow 1.0.7 → 1.0.8
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/dist/cli/agent-manager.js +451 -0
- package/dist/cli-proxy.js +41 -8
- package/dist/mcp/standalone-stdio.js +133 -2
- package/dist/utils/agentLoader.js +59 -14
- package/dist/utils/cli.js +96 -18
- package/package.json +1 -1
|
@@ -0,0 +1,451 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Agent Management CLI - Create, list, and manage custom agents
|
|
4
|
+
* Supports both npm package agents and local .claude/agents
|
|
5
|
+
* Includes conflict detection and deduplication
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, statSync } from 'fs';
|
|
8
|
+
import { join, dirname, relative, extname } from 'path';
|
|
9
|
+
import { fileURLToPath } from 'url';
|
|
10
|
+
import { createInterface } from 'readline';
|
|
11
|
+
// Get package root and default paths
|
|
12
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
13
|
+
const __dirname = dirname(__filename);
|
|
14
|
+
const packageRoot = join(__dirname, '../..');
|
|
15
|
+
const packageAgentsDir = join(packageRoot, '.claude/agents');
|
|
16
|
+
const localAgentsDir = join(process.cwd(), '.claude/agents');
|
|
17
|
+
export class AgentManager {
|
|
18
|
+
/**
|
|
19
|
+
* Find all agent files from both package and local directories
|
|
20
|
+
* Deduplicates by preferring local over package
|
|
21
|
+
*/
|
|
22
|
+
findAllAgents() {
|
|
23
|
+
const agents = new Map();
|
|
24
|
+
// Load package agents first
|
|
25
|
+
if (existsSync(packageAgentsDir)) {
|
|
26
|
+
this.scanAgentsDirectory(packageAgentsDir, 'package', agents);
|
|
27
|
+
}
|
|
28
|
+
// Load local agents (overrides package agents with same relative path)
|
|
29
|
+
if (existsSync(localAgentsDir)) {
|
|
30
|
+
this.scanAgentsDirectory(localAgentsDir, 'local', agents);
|
|
31
|
+
}
|
|
32
|
+
return agents;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Recursively scan directory for agent markdown files
|
|
36
|
+
*/
|
|
37
|
+
scanAgentsDirectory(dir, source, agents) {
|
|
38
|
+
const baseDir = source === 'package' ? packageAgentsDir : localAgentsDir;
|
|
39
|
+
try {
|
|
40
|
+
const entries = readdirSync(dir);
|
|
41
|
+
for (const entry of entries) {
|
|
42
|
+
const fullPath = join(dir, entry);
|
|
43
|
+
const stat = statSync(fullPath);
|
|
44
|
+
if (stat.isDirectory()) {
|
|
45
|
+
this.scanAgentsDirectory(fullPath, source, agents);
|
|
46
|
+
}
|
|
47
|
+
else if (extname(entry) === '.md' && entry !== 'README.md') {
|
|
48
|
+
const relativePath = relative(baseDir, fullPath);
|
|
49
|
+
const agentInfo = this.parseAgentFile(fullPath, source, relativePath);
|
|
50
|
+
if (agentInfo) {
|
|
51
|
+
// Use relative path as key for deduplication
|
|
52
|
+
// Local agents override package agents
|
|
53
|
+
const existingAgent = agents.get(relativePath);
|
|
54
|
+
if (!existingAgent || source === 'local') {
|
|
55
|
+
agents.set(relativePath, agentInfo);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch (error) {
|
|
62
|
+
console.error(`Error scanning directory ${dir}: ${error.message}`);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Parse agent markdown file and extract metadata
|
|
67
|
+
*/
|
|
68
|
+
parseAgentFile(filePath, source, relativePath) {
|
|
69
|
+
try {
|
|
70
|
+
const content = readFileSync(filePath, 'utf-8');
|
|
71
|
+
// Try frontmatter format first
|
|
72
|
+
const frontmatterMatch = content.match(/^---\n([\s\S]*?)\n---\n([\s\S]*)$/);
|
|
73
|
+
if (frontmatterMatch) {
|
|
74
|
+
const [, frontmatter] = frontmatterMatch;
|
|
75
|
+
const meta = {};
|
|
76
|
+
frontmatter.split('\n').forEach(line => {
|
|
77
|
+
const match = line.match(/^(\w+):\s*(.+)$/);
|
|
78
|
+
if (match) {
|
|
79
|
+
const [, key, value] = match;
|
|
80
|
+
meta[key] = value.replace(/^["']|["']$/g, '');
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
if (meta.name && meta.description) {
|
|
84
|
+
return {
|
|
85
|
+
name: meta.name,
|
|
86
|
+
description: meta.description,
|
|
87
|
+
category: this.getCategoryFromPath(relativePath),
|
|
88
|
+
filePath,
|
|
89
|
+
source,
|
|
90
|
+
relativePath
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// Fallback: extract from markdown headers
|
|
95
|
+
const nameMatch = content.match(/^#\s+(.+)$/m);
|
|
96
|
+
const descMatch = content.match(/^##\s+Description\s*\n\s*(.+)$/m);
|
|
97
|
+
if (nameMatch) {
|
|
98
|
+
return {
|
|
99
|
+
name: nameMatch[1].trim(),
|
|
100
|
+
description: descMatch ? descMatch[1].trim() : 'No description available',
|
|
101
|
+
category: this.getCategoryFromPath(relativePath),
|
|
102
|
+
filePath,
|
|
103
|
+
source,
|
|
104
|
+
relativePath
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
return null;
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
return null;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Get category from file path
|
|
115
|
+
*/
|
|
116
|
+
getCategoryFromPath(relativePath) {
|
|
117
|
+
const parts = relativePath.split('/');
|
|
118
|
+
return parts.length > 1 ? parts[0] : 'custom';
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* List all agents with deduplication
|
|
122
|
+
*/
|
|
123
|
+
list(format = 'summary') {
|
|
124
|
+
const agents = this.findAllAgents();
|
|
125
|
+
if (format === 'json') {
|
|
126
|
+
const agentList = Array.from(agents.values()).map(a => ({
|
|
127
|
+
name: a.name,
|
|
128
|
+
description: a.description,
|
|
129
|
+
category: a.category,
|
|
130
|
+
source: a.source,
|
|
131
|
+
path: a.relativePath
|
|
132
|
+
}));
|
|
133
|
+
console.log(JSON.stringify(agentList, null, 2));
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
// Group by category
|
|
137
|
+
const byCategory = new Map();
|
|
138
|
+
for (const agent of agents.values()) {
|
|
139
|
+
const category = agent.category;
|
|
140
|
+
if (!byCategory.has(category)) {
|
|
141
|
+
byCategory.set(category, []);
|
|
142
|
+
}
|
|
143
|
+
byCategory.get(category).push(agent);
|
|
144
|
+
}
|
|
145
|
+
// Sort categories
|
|
146
|
+
const sortedCategories = Array.from(byCategory.keys()).sort();
|
|
147
|
+
console.log('\n📦 Available Agents:');
|
|
148
|
+
console.log('═'.repeat(80));
|
|
149
|
+
for (const category of sortedCategories) {
|
|
150
|
+
const categoryAgents = byCategory.get(category).sort((a, b) => a.name.localeCompare(b.name));
|
|
151
|
+
console.log(`\n${category.toUpperCase()}:`);
|
|
152
|
+
for (const agent of categoryAgents) {
|
|
153
|
+
const sourceIcon = agent.source === 'local' ? '📝' : '📦';
|
|
154
|
+
if (format === 'detailed') {
|
|
155
|
+
console.log(` ${sourceIcon} ${agent.name}`);
|
|
156
|
+
console.log(` ${agent.description}`);
|
|
157
|
+
console.log(` Source: ${agent.source} (${agent.relativePath})`);
|
|
158
|
+
}
|
|
159
|
+
else {
|
|
160
|
+
console.log(` ${sourceIcon} ${agent.name.padEnd(30)} ${agent.description.substring(0, 45)}...`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
console.log(`\n📊 Total: ${agents.size} agents`);
|
|
165
|
+
console.log(` 📝 Local: ${Array.from(agents.values()).filter(a => a.source === 'local').length}`);
|
|
166
|
+
console.log(` 📦 Package: ${Array.from(agents.values()).filter(a => a.source === 'package').length}`);
|
|
167
|
+
console.log('');
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Create a new agent
|
|
171
|
+
*/
|
|
172
|
+
async create(options) {
|
|
173
|
+
let { name, description, category, systemPrompt, tools } = options;
|
|
174
|
+
// Interactive mode
|
|
175
|
+
if (options.interactive) {
|
|
176
|
+
const rl = createInterface({
|
|
177
|
+
input: process.stdin,
|
|
178
|
+
output: process.stdout
|
|
179
|
+
});
|
|
180
|
+
const question = (prompt) => {
|
|
181
|
+
return new Promise(resolve => rl.question(prompt, resolve));
|
|
182
|
+
};
|
|
183
|
+
console.log('\n🤖 Create New Agent');
|
|
184
|
+
console.log('═'.repeat(80));
|
|
185
|
+
name = await question('Agent name (e.g., my-custom-agent): ');
|
|
186
|
+
description = await question('Description: ');
|
|
187
|
+
category = await question('Category (default: custom): ') || 'custom';
|
|
188
|
+
systemPrompt = await question('System prompt: ');
|
|
189
|
+
const toolsInput = await question('Tools (comma-separated, optional): ');
|
|
190
|
+
tools = toolsInput ? toolsInput.split(',').map(t => t.trim()) : [];
|
|
191
|
+
rl.close();
|
|
192
|
+
}
|
|
193
|
+
// Validate required fields
|
|
194
|
+
if (!name || !description || !systemPrompt) {
|
|
195
|
+
throw new Error('Name, description, and system prompt are required');
|
|
196
|
+
}
|
|
197
|
+
// Normalize name to kebab-case
|
|
198
|
+
const kebabName = name.toLowerCase().replace(/\s+/g, '-').replace(/[^a-z0-9-]/g, '');
|
|
199
|
+
// Check for conflicts
|
|
200
|
+
const agents = this.findAllAgents();
|
|
201
|
+
const conflictingAgent = Array.from(agents.values()).find(a => a.name.toLowerCase() === kebabName.toLowerCase());
|
|
202
|
+
if (conflictingAgent) {
|
|
203
|
+
console.log(`\n⚠️ Warning: Agent "${conflictingAgent.name}" already exists`);
|
|
204
|
+
console.log(` Source: ${conflictingAgent.source}`);
|
|
205
|
+
console.log(` Path: ${conflictingAgent.relativePath}`);
|
|
206
|
+
const rl = createInterface({
|
|
207
|
+
input: process.stdin,
|
|
208
|
+
output: process.stdout
|
|
209
|
+
});
|
|
210
|
+
const answer = await new Promise(resolve => {
|
|
211
|
+
rl.question('\nCreate in local .claude/agents anyway? (y/N): ', resolve);
|
|
212
|
+
});
|
|
213
|
+
rl.close();
|
|
214
|
+
if (answer.toLowerCase() !== 'y') {
|
|
215
|
+
console.log('Cancelled.');
|
|
216
|
+
return;
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
// Create directory structure
|
|
220
|
+
const targetCategory = category || 'custom';
|
|
221
|
+
const targetDir = join(localAgentsDir, targetCategory);
|
|
222
|
+
if (!existsSync(targetDir)) {
|
|
223
|
+
mkdirSync(targetDir, { recursive: true });
|
|
224
|
+
}
|
|
225
|
+
// Generate markdown content
|
|
226
|
+
const markdown = this.generateAgentMarkdown({
|
|
227
|
+
name: kebabName,
|
|
228
|
+
description: description,
|
|
229
|
+
category: targetCategory,
|
|
230
|
+
tools
|
|
231
|
+
}, systemPrompt);
|
|
232
|
+
const filePath = join(targetDir, `${kebabName}.md`);
|
|
233
|
+
if (existsSync(filePath)) {
|
|
234
|
+
throw new Error(`Agent file already exists at ${filePath}`);
|
|
235
|
+
}
|
|
236
|
+
writeFileSync(filePath, markdown, 'utf8');
|
|
237
|
+
console.log(`\n✅ Agent created successfully!`);
|
|
238
|
+
console.log(` Name: ${kebabName}`);
|
|
239
|
+
console.log(` Category: ${targetCategory}`);
|
|
240
|
+
console.log(` Path: ${filePath}`);
|
|
241
|
+
console.log(`\n📝 Usage:`);
|
|
242
|
+
console.log(` npx agentic-flow --agent ${kebabName} --task "Your task"`);
|
|
243
|
+
console.log('');
|
|
244
|
+
}
|
|
245
|
+
/**
|
|
246
|
+
* Generate agent markdown with frontmatter
|
|
247
|
+
*/
|
|
248
|
+
generateAgentMarkdown(metadata, systemPrompt) {
|
|
249
|
+
const toolsLine = metadata.tools && metadata.tools.length > 0
|
|
250
|
+
? `tools: ${metadata.tools.join(', ')}`
|
|
251
|
+
: '';
|
|
252
|
+
return `---
|
|
253
|
+
name: ${metadata.name}
|
|
254
|
+
description: ${metadata.description}
|
|
255
|
+
${metadata.color ? `color: ${metadata.color}` : ''}
|
|
256
|
+
${toolsLine}
|
|
257
|
+
---
|
|
258
|
+
|
|
259
|
+
${systemPrompt}
|
|
260
|
+
|
|
261
|
+
## Usage
|
|
262
|
+
|
|
263
|
+
\`\`\`bash
|
|
264
|
+
npx agentic-flow --agent ${metadata.name} --task "Your task"
|
|
265
|
+
\`\`\`
|
|
266
|
+
|
|
267
|
+
## Examples
|
|
268
|
+
|
|
269
|
+
### Example 1
|
|
270
|
+
\`\`\`bash
|
|
271
|
+
npx agentic-flow --agent ${metadata.name} --task "Example task description"
|
|
272
|
+
\`\`\`
|
|
273
|
+
|
|
274
|
+
---
|
|
275
|
+
*Created: ${new Date().toISOString()}*
|
|
276
|
+
*Source: local*
|
|
277
|
+
`;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Get information about a specific agent
|
|
281
|
+
*/
|
|
282
|
+
info(name) {
|
|
283
|
+
const agents = this.findAllAgents();
|
|
284
|
+
const agent = Array.from(agents.values()).find(a => a.name.toLowerCase() === name.toLowerCase());
|
|
285
|
+
if (!agent) {
|
|
286
|
+
console.log(`\n❌ Agent "${name}" not found`);
|
|
287
|
+
console.log('\nUse "agentic-flow agent list" to see all available agents\n');
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
console.log('\n📋 Agent Information');
|
|
291
|
+
console.log('═'.repeat(80));
|
|
292
|
+
console.log(`Name: ${agent.name}`);
|
|
293
|
+
console.log(`Description: ${agent.description}`);
|
|
294
|
+
console.log(`Category: ${agent.category}`);
|
|
295
|
+
console.log(`Source: ${agent.source === 'local' ? '📝 Local' : '📦 Package'}`);
|
|
296
|
+
console.log(`Path: ${agent.relativePath}`);
|
|
297
|
+
console.log(`Full Path: ${agent.filePath}`);
|
|
298
|
+
console.log('');
|
|
299
|
+
// Show content preview
|
|
300
|
+
try {
|
|
301
|
+
const content = readFileSync(agent.filePath, 'utf-8');
|
|
302
|
+
console.log('Preview:');
|
|
303
|
+
console.log('─'.repeat(80));
|
|
304
|
+
const lines = content.split('\n').slice(0, 20);
|
|
305
|
+
console.log(lines.join('\n'));
|
|
306
|
+
if (content.split('\n').length > 20) {
|
|
307
|
+
console.log('...');
|
|
308
|
+
}
|
|
309
|
+
console.log('');
|
|
310
|
+
}
|
|
311
|
+
catch (error) {
|
|
312
|
+
console.log('Could not read agent file\n');
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Check for conflicts between package and local agents
|
|
317
|
+
*/
|
|
318
|
+
checkConflicts() {
|
|
319
|
+
console.log('\n🔍 Checking for agent conflicts...');
|
|
320
|
+
console.log('═'.repeat(80));
|
|
321
|
+
const packageAgents = new Map();
|
|
322
|
+
const localAgents = new Map();
|
|
323
|
+
if (existsSync(packageAgentsDir)) {
|
|
324
|
+
this.scanAgentsDirectory(packageAgentsDir, 'package', packageAgents);
|
|
325
|
+
}
|
|
326
|
+
if (existsSync(localAgentsDir)) {
|
|
327
|
+
this.scanAgentsDirectory(localAgentsDir, 'local', localAgents);
|
|
328
|
+
}
|
|
329
|
+
// Find conflicts (same relative path in both)
|
|
330
|
+
const conflicts = [];
|
|
331
|
+
for (const [relativePath, localAgent] of localAgents) {
|
|
332
|
+
const packageAgent = packageAgents.get(relativePath);
|
|
333
|
+
if (packageAgent) {
|
|
334
|
+
conflicts.push({ path: relativePath, package: packageAgent, local: localAgent });
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
if (conflicts.length === 0) {
|
|
338
|
+
console.log('\n✅ No conflicts found!\n');
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
console.log(`\n⚠️ Found ${conflicts.length} conflict(s):\n`);
|
|
342
|
+
for (const conflict of conflicts) {
|
|
343
|
+
console.log(`📁 ${conflict.path}`);
|
|
344
|
+
console.log(` 📦 Package: ${conflict.package.name}`);
|
|
345
|
+
console.log(` ${conflict.package.description}`);
|
|
346
|
+
console.log(` 📝 Local: ${conflict.local.name}`);
|
|
347
|
+
console.log(` ${conflict.local.description}`);
|
|
348
|
+
console.log(` ℹ️ Local version will be used\n`);
|
|
349
|
+
}
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
/**
|
|
353
|
+
* CLI command handler
|
|
354
|
+
*/
|
|
355
|
+
export async function handleAgentCommand(args) {
|
|
356
|
+
const command = args[0];
|
|
357
|
+
const manager = new AgentManager();
|
|
358
|
+
switch (command) {
|
|
359
|
+
case undefined:
|
|
360
|
+
case 'help':
|
|
361
|
+
console.log(`
|
|
362
|
+
🤖 Agent Management CLI
|
|
363
|
+
|
|
364
|
+
USAGE:
|
|
365
|
+
npx agentic-flow agent <command> [options]
|
|
366
|
+
|
|
367
|
+
COMMANDS:
|
|
368
|
+
list [format] List all available agents
|
|
369
|
+
format: summary (default), detailed, json
|
|
370
|
+
|
|
371
|
+
create Create a new agent interactively
|
|
372
|
+
create --name NAME Create agent with CLI arguments
|
|
373
|
+
--description DESC
|
|
374
|
+
--category CAT
|
|
375
|
+
--prompt PROMPT
|
|
376
|
+
[--tools TOOLS]
|
|
377
|
+
|
|
378
|
+
info <name> Show detailed information about an agent
|
|
379
|
+
|
|
380
|
+
conflicts Check for conflicts between package and local agents
|
|
381
|
+
|
|
382
|
+
help Show this help message
|
|
383
|
+
|
|
384
|
+
EXAMPLES:
|
|
385
|
+
# List all agents
|
|
386
|
+
npx agentic-flow agent list
|
|
387
|
+
|
|
388
|
+
# List with details
|
|
389
|
+
npx agentic-flow agent list detailed
|
|
390
|
+
|
|
391
|
+
# Create agent interactively
|
|
392
|
+
npx agentic-flow agent create
|
|
393
|
+
|
|
394
|
+
# Create agent with CLI
|
|
395
|
+
npx agentic-flow agent create --name my-agent --description "My custom agent" --prompt "You are a helpful assistant"
|
|
396
|
+
|
|
397
|
+
# Get agent info
|
|
398
|
+
npx agentic-flow agent info coder
|
|
399
|
+
|
|
400
|
+
# Check conflicts
|
|
401
|
+
npx agentic-flow agent conflicts
|
|
402
|
+
|
|
403
|
+
AGENT LOCATIONS:
|
|
404
|
+
📦 Package: ${packageAgentsDir}
|
|
405
|
+
📝 Local: ${localAgentsDir}
|
|
406
|
+
|
|
407
|
+
Note: Local agents override package agents with the same path.
|
|
408
|
+
`);
|
|
409
|
+
break;
|
|
410
|
+
case 'list':
|
|
411
|
+
const format = args[1] || 'summary';
|
|
412
|
+
manager.list(format);
|
|
413
|
+
break;
|
|
414
|
+
case 'create':
|
|
415
|
+
const nameIdx = args.indexOf('--name');
|
|
416
|
+
const descIdx = args.indexOf('--description');
|
|
417
|
+
const catIdx = args.indexOf('--category');
|
|
418
|
+
const promptIdx = args.indexOf('--prompt');
|
|
419
|
+
const toolsIdx = args.indexOf('--tools');
|
|
420
|
+
if (nameIdx === -1 || descIdx === -1 || promptIdx === -1) {
|
|
421
|
+
// Interactive mode
|
|
422
|
+
await manager.create({ interactive: true });
|
|
423
|
+
}
|
|
424
|
+
else {
|
|
425
|
+
// CLI mode
|
|
426
|
+
await manager.create({
|
|
427
|
+
name: args[nameIdx + 1],
|
|
428
|
+
description: args[descIdx + 1],
|
|
429
|
+
category: catIdx !== -1 ? args[catIdx + 1] : 'custom',
|
|
430
|
+
systemPrompt: args[promptIdx + 1],
|
|
431
|
+
tools: toolsIdx !== -1 ? args[toolsIdx + 1].split(',').map(t => t.trim()) : []
|
|
432
|
+
});
|
|
433
|
+
}
|
|
434
|
+
break;
|
|
435
|
+
case 'info':
|
|
436
|
+
if (!args[1]) {
|
|
437
|
+
console.log('\n❌ Please specify an agent name\n');
|
|
438
|
+
console.log('Usage: npx agentic-flow agent info <name>\n');
|
|
439
|
+
process.exit(1);
|
|
440
|
+
}
|
|
441
|
+
manager.info(args[1]);
|
|
442
|
+
break;
|
|
443
|
+
case 'conflicts':
|
|
444
|
+
manager.checkConflicts();
|
|
445
|
+
break;
|
|
446
|
+
default:
|
|
447
|
+
console.log(`\n❌ Unknown command: ${command}\n`);
|
|
448
|
+
console.log('Use "npx agentic-flow agent help" for usage information\n');
|
|
449
|
+
process.exit(1);
|
|
450
|
+
}
|
|
451
|
+
}
|
package/dist/cli-proxy.js
CHANGED
|
@@ -10,6 +10,7 @@ import { parseArgs } from "./utils/cli.js";
|
|
|
10
10
|
import { getAgent, listAgents } from "./utils/agentLoader.js";
|
|
11
11
|
import { directApiAgent } from "./agents/directApiAgent.js";
|
|
12
12
|
import { handleConfigCommand } from "./cli/config-wizard.js";
|
|
13
|
+
import { handleAgentCommand } from "./cli/agent-manager.js";
|
|
13
14
|
import { readFileSync } from 'fs';
|
|
14
15
|
import { resolve, dirname } from 'path';
|
|
15
16
|
import { fileURLToPath } from 'url';
|
|
@@ -36,6 +37,12 @@ class AgenticFlowCLI {
|
|
|
36
37
|
await handleConfigCommand(configArgs);
|
|
37
38
|
process.exit(0);
|
|
38
39
|
}
|
|
40
|
+
if (options.mode === 'agent-manager') {
|
|
41
|
+
// Handle agent management commands
|
|
42
|
+
const agentArgs = process.argv.slice(3); // Skip 'node', 'cli-proxy.js', 'agent'
|
|
43
|
+
await handleAgentCommand(agentArgs);
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
39
46
|
if (options.mode === 'mcp') {
|
|
40
47
|
// Run standalone MCP server directly
|
|
41
48
|
const { spawn } = await import('child_process');
|
|
@@ -235,6 +242,7 @@ USAGE:
|
|
|
235
242
|
COMMANDS:
|
|
236
243
|
config [subcommand] Manage environment configuration (interactive wizard)
|
|
237
244
|
mcp <command> [server] Manage MCP servers (start, stop, status, list)
|
|
245
|
+
agent <command> Agent management (list, create, info, conflicts)
|
|
238
246
|
--list, -l List all available agents
|
|
239
247
|
--agent, -a <name> Run specific agent mode
|
|
240
248
|
|
|
@@ -254,12 +262,37 @@ MCP COMMANDS:
|
|
|
254
262
|
|
|
255
263
|
Available servers: claude-flow, flow-nexus, agentic-payments, all (default)
|
|
256
264
|
|
|
265
|
+
AGENT COMMANDS:
|
|
266
|
+
npx agentic-flow agent list [format] List all agents (summary/detailed/json)
|
|
267
|
+
npx agentic-flow agent create Create new custom agent (interactive)
|
|
268
|
+
npx agentic-flow agent info <name> Show detailed agent information
|
|
269
|
+
npx agentic-flow agent conflicts Check for package/local conflicts
|
|
270
|
+
|
|
257
271
|
OPTIONS:
|
|
258
|
-
--task, -t <task>
|
|
259
|
-
--model, -m <model>
|
|
260
|
-
--provider, -p <name>
|
|
261
|
-
--stream, -s
|
|
262
|
-
--help, -h
|
|
272
|
+
--task, -t <task> Task description for agent mode
|
|
273
|
+
--model, -m <model> Model to use (triggers OpenRouter if contains "/")
|
|
274
|
+
--provider, -p <name> Provider to use (anthropic, openrouter, onnx)
|
|
275
|
+
--stream, -s Enable real-time streaming output
|
|
276
|
+
--help, -h Show this help message
|
|
277
|
+
|
|
278
|
+
API CONFIGURATION:
|
|
279
|
+
--anthropic-key <key> Override ANTHROPIC_API_KEY environment variable
|
|
280
|
+
--openrouter-key <key> Override OPENROUTER_API_KEY environment variable
|
|
281
|
+
|
|
282
|
+
AGENT BEHAVIOR:
|
|
283
|
+
--temperature <0.0-1.0> Sampling temperature (creativity control)
|
|
284
|
+
--max-tokens <number> Maximum tokens in response
|
|
285
|
+
|
|
286
|
+
DIRECTORY:
|
|
287
|
+
--agents-dir <path> Custom agents directory (default: .claude/agents)
|
|
288
|
+
|
|
289
|
+
OUTPUT:
|
|
290
|
+
--output <text|json|md> Output format (text/json/markdown)
|
|
291
|
+
--verbose Enable verbose logging for debugging
|
|
292
|
+
|
|
293
|
+
EXECUTION:
|
|
294
|
+
--timeout <ms> Execution timeout in milliseconds
|
|
295
|
+
--retry Auto-retry on transient errors
|
|
263
296
|
|
|
264
297
|
EXAMPLES:
|
|
265
298
|
# MCP Server Management
|
|
@@ -288,11 +321,11 @@ OPENROUTER MODELS:
|
|
|
288
321
|
- google/gemini-2.5-flash-preview (fastest)
|
|
289
322
|
- See https://openrouter.ai/models for full list
|
|
290
323
|
|
|
291
|
-
MCP TOOLS (
|
|
292
|
-
•
|
|
324
|
+
MCP TOOLS (209+ available):
|
|
325
|
+
• agentic-flow: 6 tools (agent execution, creation, management)
|
|
293
326
|
• claude-flow: 101 tools (neural networks, GitHub, workflows, DAA)
|
|
294
327
|
• flow-nexus: 96 cloud tools (sandboxes, distributed swarms, templates)
|
|
295
|
-
• agentic-payments:
|
|
328
|
+
• agentic-payments: 6 tools (payment authorization, multi-agent consensus)
|
|
296
329
|
|
|
297
330
|
For more information: https://github.com/ruvnet/agentic-flow
|
|
298
331
|
`);
|
|
@@ -19,7 +19,7 @@ console.error('🚀 Starting Agentic-Flow MCP Server (stdio)...');
|
|
|
19
19
|
console.error('📦 Local agentic-flow tools available');
|
|
20
20
|
const server = new FastMCP({
|
|
21
21
|
name: 'agentic-flow',
|
|
22
|
-
version: '1.0.
|
|
22
|
+
version: '1.0.8'
|
|
23
23
|
});
|
|
24
24
|
// Tool: Run agentic-flow agent
|
|
25
25
|
server.addTool({
|
|
@@ -124,7 +124,138 @@ server.addTool({
|
|
|
124
124
|
}
|
|
125
125
|
}
|
|
126
126
|
});
|
|
127
|
-
|
|
127
|
+
// Tool: Create custom agent
|
|
128
|
+
server.addTool({
|
|
129
|
+
name: 'agentic_flow_create_agent',
|
|
130
|
+
description: 'Create a new custom agent in .claude/agents directory. Supports conflict detection and will warn if agent already exists in package or local directories.',
|
|
131
|
+
parameters: z.object({
|
|
132
|
+
name: z.string().describe('Agent name (will be converted to kebab-case, e.g., my-custom-agent)'),
|
|
133
|
+
description: z.string().describe('Agent description (what this agent does)'),
|
|
134
|
+
systemPrompt: z.string().describe('System prompt that defines the agent behavior and personality'),
|
|
135
|
+
category: z.string().optional().default('custom').describe('Category/folder to organize the agent (default: custom)'),
|
|
136
|
+
tools: z.array(z.string()).optional().describe('Optional list of tools this agent can use (e.g., ["web-search", "code-execution"])')
|
|
137
|
+
}),
|
|
138
|
+
execute: async ({ name, description, systemPrompt, category, tools }) => {
|
|
139
|
+
try {
|
|
140
|
+
let cmd = `npx --yes agentic-flow agent create --name "${name}" --description "${description}" --prompt "${systemPrompt}"`;
|
|
141
|
+
if (category && category !== 'custom')
|
|
142
|
+
cmd += ` --category "${category}"`;
|
|
143
|
+
if (tools && tools.length > 0)
|
|
144
|
+
cmd += ` --tools "${tools.join(',')}"`;
|
|
145
|
+
const result = execSync(cmd, {
|
|
146
|
+
encoding: 'utf-8',
|
|
147
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
148
|
+
timeout: 60000,
|
|
149
|
+
input: 'y\n' // Auto-confirm if conflict exists
|
|
150
|
+
});
|
|
151
|
+
return JSON.stringify({
|
|
152
|
+
success: true,
|
|
153
|
+
name,
|
|
154
|
+
category: category || 'custom',
|
|
155
|
+
message: 'Agent created successfully',
|
|
156
|
+
output: result.trim()
|
|
157
|
+
}, null, 2);
|
|
158
|
+
}
|
|
159
|
+
catch (error) {
|
|
160
|
+
throw new Error(`Failed to create agent: ${error.message}`);
|
|
161
|
+
}
|
|
162
|
+
}
|
|
163
|
+
});
|
|
164
|
+
// Tool: List agents with source information
|
|
165
|
+
server.addTool({
|
|
166
|
+
name: 'agentic_flow_list_all_agents',
|
|
167
|
+
description: 'List all available agents including both package agents and custom local agents. Shows source (package or local) and handles deduplication.',
|
|
168
|
+
parameters: z.object({
|
|
169
|
+
format: z.enum(['summary', 'detailed', 'json']).optional().default('summary').describe('Output format: summary (brief list), detailed (full info), json (structured data)'),
|
|
170
|
+
filterSource: z.enum(['all', 'package', 'local']).optional().default('all').describe('Filter by source: all, package (npm distribution), or local (custom .claude/agents)')
|
|
171
|
+
}),
|
|
172
|
+
execute: async ({ format, filterSource }) => {
|
|
173
|
+
try {
|
|
174
|
+
const cmd = `npx --yes agentic-flow agent list ${format || 'summary'}`;
|
|
175
|
+
const result = execSync(cmd, {
|
|
176
|
+
encoding: 'utf-8',
|
|
177
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
178
|
+
timeout: 30000
|
|
179
|
+
});
|
|
180
|
+
if (format === 'json') {
|
|
181
|
+
const agents = JSON.parse(result);
|
|
182
|
+
const filtered = filterSource && filterSource !== 'all'
|
|
183
|
+
? agents.filter((a) => a.source === filterSource)
|
|
184
|
+
: agents;
|
|
185
|
+
return JSON.stringify({
|
|
186
|
+
success: true,
|
|
187
|
+
count: filtered.length,
|
|
188
|
+
filterSource: filterSource || 'all',
|
|
189
|
+
agents: filtered
|
|
190
|
+
}, null, 2);
|
|
191
|
+
}
|
|
192
|
+
return JSON.stringify({
|
|
193
|
+
success: true,
|
|
194
|
+
filterSource: filterSource || 'all',
|
|
195
|
+
output: result.trim()
|
|
196
|
+
}, null, 2);
|
|
197
|
+
}
|
|
198
|
+
catch (error) {
|
|
199
|
+
throw new Error(`Failed to list agents: ${error.message}`);
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
});
|
|
203
|
+
// Tool: Get agent information
|
|
204
|
+
server.addTool({
|
|
205
|
+
name: 'agentic_flow_agent_info',
|
|
206
|
+
description: 'Get detailed information about a specific agent including its source, description, category, and system prompt preview.',
|
|
207
|
+
parameters: z.object({
|
|
208
|
+
name: z.string().describe('Agent name to get information about')
|
|
209
|
+
}),
|
|
210
|
+
execute: async ({ name }) => {
|
|
211
|
+
try {
|
|
212
|
+
const cmd = `npx --yes agentic-flow agent info "${name}"`;
|
|
213
|
+
const result = execSync(cmd, {
|
|
214
|
+
encoding: 'utf-8',
|
|
215
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
216
|
+
timeout: 30000
|
|
217
|
+
});
|
|
218
|
+
return JSON.stringify({
|
|
219
|
+
success: true,
|
|
220
|
+
agent: name,
|
|
221
|
+
output: result.trim()
|
|
222
|
+
}, null, 2);
|
|
223
|
+
}
|
|
224
|
+
catch (error) {
|
|
225
|
+
throw new Error(`Failed to get agent info: ${error.message}`);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
});
|
|
229
|
+
// Tool: Check for agent conflicts
|
|
230
|
+
server.addTool({
|
|
231
|
+
name: 'agentic_flow_check_conflicts',
|
|
232
|
+
description: 'Check for conflicts between package agents and local custom agents. Identifies agents with the same relative path in both locations.',
|
|
233
|
+
parameters: z.object({}),
|
|
234
|
+
execute: async () => {
|
|
235
|
+
try {
|
|
236
|
+
const cmd = `npx --yes agentic-flow agent conflicts`;
|
|
237
|
+
const result = execSync(cmd, {
|
|
238
|
+
encoding: 'utf-8',
|
|
239
|
+
maxBuffer: 10 * 1024 * 1024,
|
|
240
|
+
timeout: 30000
|
|
241
|
+
});
|
|
242
|
+
return JSON.stringify({
|
|
243
|
+
success: true,
|
|
244
|
+
output: result.trim()
|
|
245
|
+
}, null, 2);
|
|
246
|
+
}
|
|
247
|
+
catch (error) {
|
|
248
|
+
throw new Error(`Failed to check conflicts: ${error.message}`);
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
});
|
|
252
|
+
console.error('✅ Registered 6 tools:');
|
|
253
|
+
console.error(' • agentic_flow_agent (execute agent)');
|
|
254
|
+
console.error(' • agentic_flow_list_agents (list 66+ agents)');
|
|
255
|
+
console.error(' • agentic_flow_create_agent (create custom agent)');
|
|
256
|
+
console.error(' • agentic_flow_list_all_agents (list with sources)');
|
|
257
|
+
console.error(' • agentic_flow_agent_info (get agent details)');
|
|
258
|
+
console.error(' • agentic_flow_check_conflicts (conflict detection)');
|
|
128
259
|
console.error('🔌 Starting stdio transport...');
|
|
129
260
|
server.start({ transportType: 'stdio' }).then(() => {
|
|
130
261
|
console.error('✅ Agentic-Flow MCP server running on stdio');
|
|
@@ -79,25 +79,70 @@ function findAgentFiles(dir) {
|
|
|
79
79
|
return files;
|
|
80
80
|
}
|
|
81
81
|
/**
|
|
82
|
-
* Load all agents from .claude/agents directory
|
|
82
|
+
* Load all agents from .claude/agents directory with deduplication
|
|
83
|
+
* Local agents (.claude/agents in CWD) override package agents
|
|
83
84
|
*/
|
|
84
85
|
export function loadAgents(agentsDir) {
|
|
85
86
|
const agents = new Map();
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
87
|
+
const agentsByRelativePath = new Map();
|
|
88
|
+
// If explicit directory is provided, use only that
|
|
89
|
+
if (agentsDir) {
|
|
90
|
+
logger.info('Loading agents from explicit directory', { agentsDir });
|
|
91
|
+
const agentFiles = findAgentFiles(agentsDir);
|
|
92
|
+
for (const filePath of agentFiles) {
|
|
93
|
+
const agent = parseAgentFile(filePath);
|
|
94
|
+
if (agent) {
|
|
95
|
+
agents.set(agent.name, agent);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
return agents;
|
|
99
|
+
}
|
|
100
|
+
// Otherwise, load from both package and local with deduplication
|
|
101
|
+
const localAgentsDir = join(process.cwd(), '.claude/agents');
|
|
102
|
+
// 1. Load package agents first (if they exist)
|
|
103
|
+
if (existsSync(defaultAgentsDir)) {
|
|
104
|
+
logger.info('Loading package agents', { agentsDir: defaultAgentsDir });
|
|
105
|
+
const packageFiles = findAgentFiles(defaultAgentsDir);
|
|
106
|
+
logger.debug('Found package agent files', { count: packageFiles.length });
|
|
107
|
+
for (const filePath of packageFiles) {
|
|
108
|
+
const agent = parseAgentFile(filePath);
|
|
109
|
+
if (agent) {
|
|
110
|
+
const relativePath = filePath.substring(defaultAgentsDir.length + 1);
|
|
111
|
+
agentsByRelativePath.set(relativePath, agent);
|
|
112
|
+
agents.set(agent.name, agent);
|
|
113
|
+
logger.debug('Loaded package agent', { name: agent.name, path: relativePath });
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// 2. Load local agents (override package agents with same relative path)
|
|
118
|
+
if (existsSync(localAgentsDir) && localAgentsDir !== defaultAgentsDir) {
|
|
119
|
+
logger.info('Loading local agents', { agentsDir: localAgentsDir });
|
|
120
|
+
const localFiles = findAgentFiles(localAgentsDir);
|
|
121
|
+
logger.debug('Found local agent files', { count: localFiles.length });
|
|
122
|
+
for (const filePath of localFiles) {
|
|
123
|
+
const agent = parseAgentFile(filePath);
|
|
124
|
+
if (agent) {
|
|
125
|
+
const relativePath = filePath.substring(localAgentsDir.length + 1);
|
|
126
|
+
const existingAgent = agentsByRelativePath.get(relativePath);
|
|
127
|
+
if (existingAgent) {
|
|
128
|
+
logger.info('Local agent overrides package agent', {
|
|
129
|
+
name: agent.name,
|
|
130
|
+
path: relativePath
|
|
131
|
+
});
|
|
132
|
+
// Remove old agent
|
|
133
|
+
agents.delete(existingAgent.name);
|
|
134
|
+
}
|
|
135
|
+
agentsByRelativePath.set(relativePath, agent);
|
|
136
|
+
agents.set(agent.name, agent);
|
|
137
|
+
logger.debug('Loaded local agent', { name: agent.name, path: relativePath });
|
|
138
|
+
}
|
|
98
139
|
}
|
|
99
140
|
}
|
|
100
|
-
logger.info('Agents loaded successfully', {
|
|
141
|
+
logger.info('Agents loaded successfully', {
|
|
142
|
+
total: agents.size,
|
|
143
|
+
package: existsSync(defaultAgentsDir) ? findAgentFiles(defaultAgentsDir).length : 0,
|
|
144
|
+
local: existsSync(localAgentsDir) ? findAgentFiles(localAgentsDir).length : 0
|
|
145
|
+
});
|
|
101
146
|
return agents;
|
|
102
147
|
}
|
|
103
148
|
/**
|
package/dist/utils/cli.js
CHANGED
|
@@ -16,6 +16,11 @@ export function parseArgs() {
|
|
|
16
16
|
options.mode = 'config';
|
|
17
17
|
return options;
|
|
18
18
|
}
|
|
19
|
+
// Check for agent management command
|
|
20
|
+
if (args[0] === 'agent') {
|
|
21
|
+
options.mode = 'agent-manager';
|
|
22
|
+
return options;
|
|
23
|
+
}
|
|
19
24
|
for (let i = 0; i < args.length; i++) {
|
|
20
25
|
const arg = args[i];
|
|
21
26
|
switch (arg) {
|
|
@@ -48,6 +53,38 @@ export function parseArgs() {
|
|
|
48
53
|
case '-l':
|
|
49
54
|
options.mode = 'list';
|
|
50
55
|
break;
|
|
56
|
+
// API Configuration
|
|
57
|
+
case '--anthropic-key':
|
|
58
|
+
options.anthropicApiKey = args[++i];
|
|
59
|
+
break;
|
|
60
|
+
case '--openrouter-key':
|
|
61
|
+
options.openrouterApiKey = args[++i];
|
|
62
|
+
break;
|
|
63
|
+
// Agent Behavior
|
|
64
|
+
case '--temperature':
|
|
65
|
+
options.temperature = parseFloat(args[++i]);
|
|
66
|
+
break;
|
|
67
|
+
case '--max-tokens':
|
|
68
|
+
options.maxTokens = parseInt(args[++i], 10);
|
|
69
|
+
break;
|
|
70
|
+
// Directory Configuration
|
|
71
|
+
case '--agents-dir':
|
|
72
|
+
options.agentsDir = args[++i];
|
|
73
|
+
break;
|
|
74
|
+
// Output Options
|
|
75
|
+
case '--output':
|
|
76
|
+
options.outputFormat = args[++i];
|
|
77
|
+
break;
|
|
78
|
+
case '--verbose':
|
|
79
|
+
options.verbose = true;
|
|
80
|
+
break;
|
|
81
|
+
// Execution Control
|
|
82
|
+
case '--timeout':
|
|
83
|
+
options.timeout = parseInt(args[++i], 10);
|
|
84
|
+
break;
|
|
85
|
+
case '--retry':
|
|
86
|
+
options.retryOnError = true;
|
|
87
|
+
break;
|
|
51
88
|
}
|
|
52
89
|
}
|
|
53
90
|
return options;
|
|
@@ -61,6 +98,8 @@ USAGE:
|
|
|
61
98
|
|
|
62
99
|
COMMANDS:
|
|
63
100
|
mcp <command> [server] Manage MCP servers (start, stop, status, list)
|
|
101
|
+
config [command] Configuration wizard (set, get, list, delete, reset)
|
|
102
|
+
agent <command> Agent management (list, create, info, conflicts)
|
|
64
103
|
--list, -l List all available agents
|
|
65
104
|
--agent, -a <name> Run specific agent mode
|
|
66
105
|
(default) Run parallel mode (3 agents)
|
|
@@ -74,28 +113,67 @@ MCP COMMANDS:
|
|
|
74
113
|
Available servers: claude-flow, flow-nexus, agentic-payments, all (default)
|
|
75
114
|
|
|
76
115
|
OPTIONS:
|
|
77
|
-
--task, -t <task>
|
|
78
|
-
--model, -m <model>
|
|
79
|
-
--provider, -p <name>
|
|
80
|
-
--stream, -s
|
|
81
|
-
|
|
116
|
+
--task, -t <task> Task description for agent mode
|
|
117
|
+
--model, -m <model> Model to use (supports OpenRouter models)
|
|
118
|
+
--provider, -p <name> Provider (anthropic, openrouter, onnx)
|
|
119
|
+
--stream, -s Enable real-time streaming output
|
|
120
|
+
|
|
121
|
+
API CONFIGURATION:
|
|
122
|
+
--anthropic-key <key> Override ANTHROPIC_API_KEY
|
|
123
|
+
--openrouter-key <key> Override OPENROUTER_API_KEY
|
|
124
|
+
|
|
125
|
+
AGENT BEHAVIOR:
|
|
126
|
+
--temperature <0.0-1.0> Sampling temperature (creativity)
|
|
127
|
+
--max-tokens <number> Maximum response tokens
|
|
128
|
+
|
|
129
|
+
DIRECTORY:
|
|
130
|
+
--agents-dir <path> Custom agents directory
|
|
131
|
+
|
|
132
|
+
OUTPUT:
|
|
133
|
+
--output <text|json|md> Output format
|
|
134
|
+
--verbose Enable verbose logging
|
|
135
|
+
|
|
136
|
+
EXECUTION:
|
|
137
|
+
--timeout <ms> Execution timeout
|
|
138
|
+
--retry Auto-retry on errors
|
|
139
|
+
|
|
140
|
+
--help, -h Show this help message
|
|
82
141
|
|
|
83
142
|
EXAMPLES:
|
|
143
|
+
# Agent Management
|
|
144
|
+
npx agentic-flow agent list # List all agents with sources
|
|
145
|
+
npx agentic-flow agent create # Interactive agent creator
|
|
146
|
+
npx agentic-flow agent info coder # Get agent details
|
|
147
|
+
npx agentic-flow agent conflicts # Check for conflicts
|
|
148
|
+
|
|
149
|
+
# Configuration
|
|
150
|
+
npx agentic-flow config # Interactive config wizard
|
|
151
|
+
npx agentic-flow config set PROVIDER openrouter
|
|
152
|
+
npx agentic-flow config list # View all settings
|
|
153
|
+
|
|
84
154
|
# MCP Server Management
|
|
85
155
|
npx agentic-flow mcp start # Start all MCP servers
|
|
86
|
-
npx agentic-flow mcp
|
|
87
|
-
|
|
88
|
-
|
|
156
|
+
npx agentic-flow mcp list # List all 209+ MCP tools
|
|
157
|
+
|
|
158
|
+
# Agent Execution (Basic)
|
|
159
|
+
npx agentic-flow --list # List all agents
|
|
160
|
+
npx agentic-flow --agent coder --task "Build REST API"
|
|
161
|
+
|
|
162
|
+
# Agent Execution (Advanced)
|
|
163
|
+
npx agentic-flow --agent coder --task "Build API" \\
|
|
164
|
+
--provider openrouter \\
|
|
165
|
+
--model "meta-llama/llama-3.1-8b-instruct" \\
|
|
166
|
+
--temperature 0.7 \\
|
|
167
|
+
--max-tokens 2000 \\
|
|
168
|
+
--output json \\
|
|
169
|
+
--verbose
|
|
89
170
|
|
|
90
|
-
# Agent Execution
|
|
91
|
-
npx agentic-flow --
|
|
92
|
-
|
|
93
|
-
npx agentic-flow --agent coder --task "Build REST API" --model "meta-llama/llama-3.1-8b-instruct"
|
|
94
|
-
npx agentic-flow --agent coder --task "Create hello world" --provider onnx
|
|
95
|
-
npx agentic-flow --agent coder --task "Build REST API" --stream
|
|
171
|
+
# Agent Execution (Custom)
|
|
172
|
+
npx agentic-flow --agent my-custom-agent --task "Your task" \\
|
|
173
|
+
--agents-dir ./my-agents
|
|
96
174
|
|
|
97
175
|
# Parallel Mode
|
|
98
|
-
npx agentic-flow # Run 3 agents in parallel
|
|
176
|
+
npx agentic-flow # Run 3 agents in parallel
|
|
99
177
|
|
|
100
178
|
ENVIRONMENT VARIABLES:
|
|
101
179
|
ANTHROPIC_API_KEY Anthropic API key (for Claude models)
|
|
@@ -111,11 +189,11 @@ ENVIRONMENT VARIABLES:
|
|
|
111
189
|
ENABLE_STREAMING Enable streaming (true/false)
|
|
112
190
|
HEALTH_PORT Health check port (default: 8080)
|
|
113
191
|
|
|
114
|
-
MCP TOOLS (
|
|
115
|
-
•
|
|
192
|
+
MCP TOOLS (209+ available):
|
|
193
|
+
• agentic-flow: 6 tools (agent execution, creation, management)
|
|
116
194
|
• claude-flow: 101 tools (neural networks, GitHub, workflows, DAA)
|
|
117
195
|
• flow-nexus: 96 cloud tools (sandboxes, distributed swarms, templates)
|
|
118
|
-
• agentic-payments:
|
|
196
|
+
• agentic-payments: 6 tools (payment authorization, multi-agent consensus)
|
|
119
197
|
|
|
120
198
|
For more information, visit: https://github.com/ruvnet/agentic-flow
|
|
121
199
|
`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "agentic-flow",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.8",
|
|
4
4
|
"description": "Production-ready AI agent orchestration platform with 66 specialized agents, 111 MCP tools, and autonomous multi-agent swarms. Built by @ruvnet with Claude Agent SDK, neural networks, memory persistence, GitHub integration, and distributed consensus protocols.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.js",
|