claude-flow 1.0.2 ā 1.0.4
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/README.md +35 -3
- package/bin/claude-flow +0 -0
- package/package.json +1 -1
- package/src/cli/cli-core.ts +1 -1
- package/src/cli/commands/claude.ts +175 -0
- package/src/cli/commands/index.ts +421 -3
package/README.md
CHANGED
|
@@ -177,7 +177,19 @@ npx claude-flow task create code "Implement authentication" --priority 9
|
|
|
177
177
|
npx claude-flow task list --verbose
|
|
178
178
|
```
|
|
179
179
|
|
|
180
|
-
### 5. **
|
|
180
|
+
### 5. **Spawn Claude Instances** š
|
|
181
|
+
```bash
|
|
182
|
+
# Spawn Claude with specific configuration
|
|
183
|
+
npx claude-flow claude spawn "implement user authentication" --research --parallel
|
|
184
|
+
|
|
185
|
+
# Run with custom tools
|
|
186
|
+
npx claude-flow claude spawn "fix payment bug" --tools "View,Edit,Bash" --no-permissions
|
|
187
|
+
|
|
188
|
+
# Execute batch workflow
|
|
189
|
+
npx claude-flow claude batch examples/claude-workflow.json --dry-run
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
### 6. **Monitor System Status**
|
|
181
193
|
```bash
|
|
182
194
|
# Check system health
|
|
183
195
|
npx claude-flow status
|
|
@@ -343,8 +355,28 @@ npx claude-flow mcp <subcommand>
|
|
|
343
355
|
#### `monitor` - Real-time Monitoring
|
|
344
356
|
```bash
|
|
345
357
|
npx claude-flow monitor [options]
|
|
346
|
-
--interval <
|
|
347
|
-
--
|
|
358
|
+
-i, --interval <seconds> Update interval (default: 2)
|
|
359
|
+
-c, --compact Compact view mode
|
|
360
|
+
-f, --focus <component> Focus on specific component
|
|
361
|
+
```
|
|
362
|
+
|
|
363
|
+
#### `claude` - Spawn Claude Instances š
|
|
364
|
+
```bash
|
|
365
|
+
npx claude-flow claude <subcommand>
|
|
366
|
+
spawn <task> Spawn Claude with specific configuration
|
|
367
|
+
-t, --tools <tools> Allowed tools (comma-separated)
|
|
368
|
+
--no-permissions Use --dangerously-skip-permissions flag
|
|
369
|
+
-c, --config <file> MCP config file path
|
|
370
|
+
-m, --mode <mode> Development mode (full/backend-only/frontend-only/api-only)
|
|
371
|
+
--parallel Enable parallel execution with BatchTool
|
|
372
|
+
--research Enable web research with WebFetchTool
|
|
373
|
+
--coverage <n> Test coverage target percentage (default: 80)
|
|
374
|
+
--commit <freq> Commit frequency (phase/feature/manual)
|
|
375
|
+
-v, --verbose Enable verbose output
|
|
376
|
+
-d, --dry-run Show what would be executed without running
|
|
377
|
+
|
|
378
|
+
batch <workflow-file> Execute multiple Claude instances from workflow
|
|
379
|
+
--dry-run Show what would be executed without running
|
|
348
380
|
```
|
|
349
381
|
|
|
350
382
|
#### `config` - Configuration Management
|
package/bin/claude-flow
CHANGED
|
Binary file
|
package/package.json
CHANGED
package/src/cli/cli-core.ts
CHANGED
|
@@ -8,7 +8,7 @@ import { red, green, yellow, blue, bold, cyan } from "https://deno.land/std@0.22
|
|
|
8
8
|
import { ensureDir } from "https://deno.land/std@0.224.0/fs/mod.ts";
|
|
9
9
|
import { join } from "https://deno.land/std@0.224.0/path/mod.ts";
|
|
10
10
|
|
|
11
|
-
export const VERSION = "1.0.
|
|
11
|
+
export const VERSION = "1.0.3";
|
|
12
12
|
|
|
13
13
|
interface CommandContext {
|
|
14
14
|
args: string[];
|
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude instance management commands
|
|
3
|
+
*/
|
|
4
|
+
|
|
5
|
+
import { Command } from '@cliffy/command';
|
|
6
|
+
import { colors } from '@cliffy/ansi/colors';
|
|
7
|
+
import { spawn } from 'node:child_process';
|
|
8
|
+
import { generateId } from '../../utils/helpers.ts';
|
|
9
|
+
|
|
10
|
+
export const claudeCommand = new Command()
|
|
11
|
+
.description('Manage Claude instances')
|
|
12
|
+
.action(() => {
|
|
13
|
+
claudeCommand.showHelp();
|
|
14
|
+
})
|
|
15
|
+
.command('spawn', new Command()
|
|
16
|
+
.description('Spawn a new Claude instance with specific configuration')
|
|
17
|
+
.arguments('<task:string>')
|
|
18
|
+
.option('-t, --tools <tools:string>', 'Allowed tools (comma-separated)', {
|
|
19
|
+
default: 'View,Edit,Replace,GlobTool,GrepTool,LS,Bash'
|
|
20
|
+
})
|
|
21
|
+
.option('--no-permissions', 'Use --dangerously-skip-permissions flag')
|
|
22
|
+
.option('-c, --config <config:string>', 'MCP config file path')
|
|
23
|
+
.option('-m, --mode <mode:string>', 'Development mode (full, backend-only, frontend-only, api-only)', {
|
|
24
|
+
default: 'full'
|
|
25
|
+
})
|
|
26
|
+
.option('--parallel', 'Enable parallel execution with BatchTool')
|
|
27
|
+
.option('--research', 'Enable web research with WebFetchTool')
|
|
28
|
+
.option('--coverage <coverage:number>', 'Test coverage target', { default: 80 })
|
|
29
|
+
.option('--commit <frequency:string>', 'Commit frequency (phase, feature, manual)', {
|
|
30
|
+
default: 'phase'
|
|
31
|
+
})
|
|
32
|
+
.option('-v, --verbose', 'Enable verbose output')
|
|
33
|
+
.option('--dry-run', 'Show what would be executed without running')
|
|
34
|
+
.action(async (options: any, task: string) => {
|
|
35
|
+
try {
|
|
36
|
+
const instanceId = generateId('claude');
|
|
37
|
+
|
|
38
|
+
// Build allowed tools list
|
|
39
|
+
let tools = options.tools;
|
|
40
|
+
if (options.parallel && !tools.includes('BatchTool')) {
|
|
41
|
+
tools += ',BatchTool,dispatch_agent';
|
|
42
|
+
}
|
|
43
|
+
if (options.research && !tools.includes('WebFetchTool')) {
|
|
44
|
+
tools += ',WebFetchTool';
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
// Build Claude command
|
|
48
|
+
const claudeArgs = [task];
|
|
49
|
+
claudeArgs.push('--allowedTools', tools);
|
|
50
|
+
|
|
51
|
+
if (options.noPermissions) {
|
|
52
|
+
claudeArgs.push('--dangerously-skip-permissions');
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
if (options.config) {
|
|
56
|
+
claudeArgs.push('--mcp-config', options.config);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
if (options.verbose) {
|
|
60
|
+
claudeArgs.push('--verbose');
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
if (options.dryRun) {
|
|
64
|
+
console.log(colors.yellow('DRY RUN - Would execute:'));
|
|
65
|
+
console.log(colors.gray(`claude ${claudeArgs.join(' ')}`));
|
|
66
|
+
console.log('\nConfiguration:');
|
|
67
|
+
console.log(` Instance ID: ${instanceId}`);
|
|
68
|
+
console.log(` Task: ${task}`);
|
|
69
|
+
console.log(` Tools: ${tools}`);
|
|
70
|
+
console.log(` Mode: ${options.mode}`);
|
|
71
|
+
console.log(` Coverage: ${options.coverage}%`);
|
|
72
|
+
console.log(` Commit: ${options.commit}`);
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
console.log(colors.green(`Spawning Claude instance: ${instanceId}`));
|
|
77
|
+
console.log(colors.gray(`Task: ${task}`));
|
|
78
|
+
console.log(colors.gray(`Tools: ${tools}`));
|
|
79
|
+
|
|
80
|
+
// Spawn Claude process
|
|
81
|
+
const claude = spawn('claude', claudeArgs, {
|
|
82
|
+
stdio: 'inherit',
|
|
83
|
+
env: {
|
|
84
|
+
...process.env,
|
|
85
|
+
CLAUDE_INSTANCE_ID: instanceId,
|
|
86
|
+
CLAUDE_FLOW_MODE: options.mode,
|
|
87
|
+
CLAUDE_FLOW_COVERAGE: options.coverage.toString(),
|
|
88
|
+
CLAUDE_FLOW_COMMIT: options.commit,
|
|
89
|
+
}
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
claude.on('error', (err) => {
|
|
93
|
+
console.error(colors.red('Failed to spawn Claude:'), err.message);
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
claude.on('exit', (code) => {
|
|
97
|
+
if (code === 0) {
|
|
98
|
+
console.log(colors.green(`Claude instance ${instanceId} completed successfully`));
|
|
99
|
+
} else {
|
|
100
|
+
console.log(colors.red(`Claude instance ${instanceId} exited with code ${code}`));
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
} catch (error) {
|
|
105
|
+
console.error(colors.red('Failed to spawn Claude:'), (error as Error).message);
|
|
106
|
+
}
|
|
107
|
+
}),
|
|
108
|
+
)
|
|
109
|
+
.command('batch', new Command()
|
|
110
|
+
.description('Spawn multiple Claude instances from workflow')
|
|
111
|
+
.arguments('<workflow-file:string>')
|
|
112
|
+
.option('--dry-run', 'Show what would be executed without running')
|
|
113
|
+
.action(async (options: any, workflowFile: string) => {
|
|
114
|
+
try {
|
|
115
|
+
const content = await Deno.readTextFile(workflowFile);
|
|
116
|
+
const workflow = JSON.parse(content);
|
|
117
|
+
|
|
118
|
+
console.log(colors.green('Loading workflow:'), workflow.name || 'Unnamed');
|
|
119
|
+
console.log(colors.gray(`Tasks: ${workflow.tasks?.length || 0}`));
|
|
120
|
+
|
|
121
|
+
if (!workflow.tasks || workflow.tasks.length === 0) {
|
|
122
|
+
console.log(colors.yellow('No tasks found in workflow'));
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
for (const task of workflow.tasks) {
|
|
127
|
+
const claudeArgs = [task.description || task.name];
|
|
128
|
+
|
|
129
|
+
// Add tools
|
|
130
|
+
if (task.tools) {
|
|
131
|
+
claudeArgs.push('--allowedTools', Array.isArray(task.tools) ? task.tools.join(',') : task.tools);
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
// Add flags
|
|
135
|
+
if (task.skipPermissions) {
|
|
136
|
+
claudeArgs.push('--dangerously-skip-permissions');
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
if (task.config) {
|
|
140
|
+
claudeArgs.push('--mcp-config', task.config);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (options.dryRun) {
|
|
144
|
+
console.log(colors.yellow(`\nDRY RUN - Task: ${task.name || task.id}`));
|
|
145
|
+
console.log(colors.gray(`claude ${claudeArgs.join(' ')}`));
|
|
146
|
+
} else {
|
|
147
|
+
console.log(colors.blue(`\nSpawning Claude for task: ${task.name || task.id}`));
|
|
148
|
+
|
|
149
|
+
const claude = spawn('claude', claudeArgs, {
|
|
150
|
+
stdio: 'inherit',
|
|
151
|
+
env: {
|
|
152
|
+
...process.env,
|
|
153
|
+
CLAUDE_TASK_ID: task.id || generateId('task'),
|
|
154
|
+
CLAUDE_TASK_TYPE: task.type || 'general',
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
// Wait for completion if sequential
|
|
159
|
+
if (!workflow.parallel) {
|
|
160
|
+
await new Promise((resolve) => {
|
|
161
|
+
claude.on('exit', resolve);
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
if (!options.dryRun && workflow.parallel) {
|
|
168
|
+
console.log(colors.green('\nAll Claude instances spawned in parallel mode'));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
} catch (error) {
|
|
172
|
+
console.error(colors.red('Failed to process workflow:'), (error as Error).message);
|
|
173
|
+
}
|
|
174
|
+
}),
|
|
175
|
+
);
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { CLI, success, error, warning, info, VERSION } from "../cli-core.ts";
|
|
2
2
|
import type { Command, CommandContext } from "../cli-core.ts";
|
|
3
|
-
import { bold, blue } from "https://deno.land/std@0.224.0/fmt/colors.ts";
|
|
3
|
+
import { bold, blue, yellow } from "https://deno.land/std@0.224.0/fmt/colors.ts";
|
|
4
4
|
import { Orchestrator } from "../../core/orchestrator-fixed.ts";
|
|
5
5
|
import { ConfigManager } from "../../core/config.ts";
|
|
6
6
|
import { MemoryManager } from "../../memory/manager.ts";
|
|
@@ -607,12 +607,430 @@ export function setupCommands(cli: CLI): void {
|
|
|
607
607
|
},
|
|
608
608
|
});
|
|
609
609
|
|
|
610
|
+
// Claude command
|
|
611
|
+
cli.command({
|
|
612
|
+
name: "claude",
|
|
613
|
+
description: "Spawn Claude instances with specific configurations",
|
|
614
|
+
aliases: ["cl"],
|
|
615
|
+
options: [
|
|
616
|
+
{
|
|
617
|
+
name: "tools",
|
|
618
|
+
short: "t",
|
|
619
|
+
description: "Allowed tools (comma-separated)",
|
|
620
|
+
type: "string",
|
|
621
|
+
default: "View,Edit,Replace,GlobTool,GrepTool,LS,Bash",
|
|
622
|
+
},
|
|
623
|
+
{
|
|
624
|
+
name: "no-permissions",
|
|
625
|
+
description: "Use --dangerously-skip-permissions flag",
|
|
626
|
+
type: "boolean",
|
|
627
|
+
},
|
|
628
|
+
{
|
|
629
|
+
name: "config",
|
|
630
|
+
short: "c",
|
|
631
|
+
description: "MCP config file path",
|
|
632
|
+
type: "string",
|
|
633
|
+
},
|
|
634
|
+
{
|
|
635
|
+
name: "mode",
|
|
636
|
+
short: "m",
|
|
637
|
+
description: "Development mode (full, backend-only, frontend-only, api-only)",
|
|
638
|
+
type: "string",
|
|
639
|
+
default: "full",
|
|
640
|
+
},
|
|
641
|
+
{
|
|
642
|
+
name: "parallel",
|
|
643
|
+
description: "Enable parallel execution with BatchTool",
|
|
644
|
+
type: "boolean",
|
|
645
|
+
},
|
|
646
|
+
{
|
|
647
|
+
name: "research",
|
|
648
|
+
description: "Enable web research with WebFetchTool",
|
|
649
|
+
type: "boolean",
|
|
650
|
+
},
|
|
651
|
+
{
|
|
652
|
+
name: "coverage",
|
|
653
|
+
description: "Test coverage target percentage",
|
|
654
|
+
type: "number",
|
|
655
|
+
default: 80,
|
|
656
|
+
},
|
|
657
|
+
{
|
|
658
|
+
name: "commit",
|
|
659
|
+
description: "Commit frequency (phase, feature, manual)",
|
|
660
|
+
type: "string",
|
|
661
|
+
default: "phase",
|
|
662
|
+
},
|
|
663
|
+
{
|
|
664
|
+
name: "verbose",
|
|
665
|
+
short: "v",
|
|
666
|
+
description: "Enable verbose output",
|
|
667
|
+
type: "boolean",
|
|
668
|
+
},
|
|
669
|
+
{
|
|
670
|
+
name: "dry-run",
|
|
671
|
+
short: "d",
|
|
672
|
+
description: "Show what would be executed without running",
|
|
673
|
+
type: "boolean",
|
|
674
|
+
},
|
|
675
|
+
],
|
|
676
|
+
action: async (ctx: CommandContext) => {
|
|
677
|
+
const subcommand = ctx.args[0];
|
|
678
|
+
|
|
679
|
+
switch (subcommand) {
|
|
680
|
+
case "spawn": {
|
|
681
|
+
// Find where flags start (arguments starting with -)
|
|
682
|
+
let taskEndIndex = ctx.args.length;
|
|
683
|
+
for (let i = 1; i < ctx.args.length; i++) {
|
|
684
|
+
if (ctx.args[i].startsWith("-")) {
|
|
685
|
+
taskEndIndex = i;
|
|
686
|
+
break;
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
|
|
690
|
+
const task = ctx.args.slice(1, taskEndIndex).join(" ");
|
|
691
|
+
if (!task) {
|
|
692
|
+
error("Usage: claude spawn <task description>");
|
|
693
|
+
break;
|
|
694
|
+
}
|
|
695
|
+
|
|
696
|
+
try {
|
|
697
|
+
// Build allowed tools list
|
|
698
|
+
let tools = ctx.flags.tools as string || "View,Edit,Replace,GlobTool,GrepTool,LS,Bash";
|
|
699
|
+
|
|
700
|
+
if (ctx.flags.parallel) {
|
|
701
|
+
tools += ",BatchTool,dispatch_agent";
|
|
702
|
+
}
|
|
703
|
+
|
|
704
|
+
if (ctx.flags.research) {
|
|
705
|
+
tools += ",WebFetchTool";
|
|
706
|
+
}
|
|
707
|
+
|
|
708
|
+
// Build Claude command
|
|
709
|
+
const claudeCmd = ["claude", `"${task}"`];
|
|
710
|
+
claudeCmd.push("--allowedTools", tools);
|
|
711
|
+
|
|
712
|
+
if (ctx.flags.noPermissions || ctx.flags["skip-permissions"]) {
|
|
713
|
+
claudeCmd.push("--dangerously-skip-permissions");
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
if (ctx.flags.config) {
|
|
717
|
+
claudeCmd.push("--mcp-config", ctx.flags.config as string);
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
if (ctx.flags.verbose) {
|
|
721
|
+
claudeCmd.push("--verbose");
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const instanceId = `claude-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
725
|
+
|
|
726
|
+
if (ctx.flags.dryRun || ctx.flags["dry-run"] || ctx.flags.d) {
|
|
727
|
+
warning("DRY RUN - Would execute:");
|
|
728
|
+
console.log(`Command: ${claudeCmd.join(" ")}`);
|
|
729
|
+
console.log(`Instance ID: ${instanceId}`);
|
|
730
|
+
console.log(`Task: ${task}`);
|
|
731
|
+
console.log(`Tools: ${tools}`);
|
|
732
|
+
console.log(`Mode: ${ctx.flags.mode || "full"}`);
|
|
733
|
+
return;
|
|
734
|
+
}
|
|
735
|
+
|
|
736
|
+
success(`Spawning Claude instance: ${instanceId}`);
|
|
737
|
+
console.log(`š Task: ${task}`);
|
|
738
|
+
console.log(`š§ Tools: ${tools}`);
|
|
739
|
+
console.log(`āļø Mode: ${ctx.flags.mode || "full"}`);
|
|
740
|
+
|
|
741
|
+
// Execute Claude command
|
|
742
|
+
const command = new Deno.Command("claude", {
|
|
743
|
+
args: claudeCmd.slice(1).map(arg => arg.replace(/^"|"$/g, '')),
|
|
744
|
+
env: {
|
|
745
|
+
...Deno.env.toObject(),
|
|
746
|
+
CLAUDE_INSTANCE_ID: instanceId,
|
|
747
|
+
CLAUDE_FLOW_MODE: ctx.flags.mode as string || "full",
|
|
748
|
+
CLAUDE_FLOW_COVERAGE: (ctx.flags.coverage || 80).toString(),
|
|
749
|
+
CLAUDE_FLOW_COMMIT: ctx.flags.commit as string || "phase",
|
|
750
|
+
},
|
|
751
|
+
stdin: "inherit",
|
|
752
|
+
stdout: "inherit",
|
|
753
|
+
stderr: "inherit",
|
|
754
|
+
});
|
|
755
|
+
|
|
756
|
+
const child = command.spawn();
|
|
757
|
+
const status = await child.status;
|
|
758
|
+
|
|
759
|
+
if (status.success) {
|
|
760
|
+
success(`Claude instance ${instanceId} completed successfully`);
|
|
761
|
+
} else {
|
|
762
|
+
error(`Claude instance ${instanceId} exited with code ${status.code}`);
|
|
763
|
+
}
|
|
764
|
+
|
|
765
|
+
} catch (err) {
|
|
766
|
+
error(`Failed to spawn Claude: ${(err as Error).message}`);
|
|
767
|
+
}
|
|
768
|
+
break;
|
|
769
|
+
}
|
|
770
|
+
|
|
771
|
+
case "batch": {
|
|
772
|
+
const workflowFile = ctx.args[1];
|
|
773
|
+
if (!workflowFile) {
|
|
774
|
+
error("Usage: claude batch <workflow-file>");
|
|
775
|
+
break;
|
|
776
|
+
}
|
|
777
|
+
|
|
778
|
+
try {
|
|
779
|
+
const content = await Deno.readTextFile(workflowFile);
|
|
780
|
+
const workflow = JSON.parse(content);
|
|
781
|
+
|
|
782
|
+
success(`Loading workflow: ${workflow.name || "Unnamed"}`);
|
|
783
|
+
console.log(`š Tasks: ${workflow.tasks?.length || 0}`);
|
|
784
|
+
|
|
785
|
+
if (!workflow.tasks || workflow.tasks.length === 0) {
|
|
786
|
+
warning("No tasks found in workflow");
|
|
787
|
+
return;
|
|
788
|
+
}
|
|
789
|
+
|
|
790
|
+
const promises = [];
|
|
791
|
+
|
|
792
|
+
for (const task of workflow.tasks) {
|
|
793
|
+
const claudeCmd = ["claude", `"${task.description || task.name}"`];
|
|
794
|
+
|
|
795
|
+
// Add tools
|
|
796
|
+
if (task.tools) {
|
|
797
|
+
const toolsList = Array.isArray(task.tools) ? task.tools.join(",") : task.tools;
|
|
798
|
+
claudeCmd.push("--allowedTools", toolsList);
|
|
799
|
+
}
|
|
800
|
+
|
|
801
|
+
// Add flags
|
|
802
|
+
if (task.skipPermissions || task.dangerouslySkipPermissions) {
|
|
803
|
+
claudeCmd.push("--dangerously-skip-permissions");
|
|
804
|
+
}
|
|
805
|
+
|
|
806
|
+
if (task.config) {
|
|
807
|
+
claudeCmd.push("--mcp-config", task.config);
|
|
808
|
+
}
|
|
809
|
+
|
|
810
|
+
const taskId = task.id || `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
811
|
+
|
|
812
|
+
if (ctx.flags.dryRun || ctx.flags["dry-run"]) {
|
|
813
|
+
console.log(`\n${yellow("DRY RUN")} - Task: ${task.name || taskId}`);
|
|
814
|
+
console.log(`Command: ${claudeCmd.join(" ")}`);
|
|
815
|
+
continue;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
console.log(`\nš Spawning Claude for task: ${task.name || taskId}`);
|
|
819
|
+
|
|
820
|
+
const command = new Deno.Command("claude", {
|
|
821
|
+
args: claudeCmd.slice(1).map(arg => arg.replace(/^"|"$/g, '')),
|
|
822
|
+
env: {
|
|
823
|
+
...Deno.env.toObject(),
|
|
824
|
+
CLAUDE_TASK_ID: taskId,
|
|
825
|
+
CLAUDE_TASK_TYPE: task.type || "general",
|
|
826
|
+
},
|
|
827
|
+
stdin: "inherit",
|
|
828
|
+
stdout: "inherit",
|
|
829
|
+
stderr: "inherit",
|
|
830
|
+
});
|
|
831
|
+
|
|
832
|
+
const child = command.spawn();
|
|
833
|
+
|
|
834
|
+
if (workflow.parallel) {
|
|
835
|
+
promises.push(child.status);
|
|
836
|
+
} else {
|
|
837
|
+
// Wait for completion if sequential
|
|
838
|
+
const status = await child.status;
|
|
839
|
+
if (!status.success) {
|
|
840
|
+
error(`Task ${taskId} failed with code ${status.code}`);
|
|
841
|
+
}
|
|
842
|
+
}
|
|
843
|
+
}
|
|
844
|
+
|
|
845
|
+
if (workflow.parallel && promises.length > 0) {
|
|
846
|
+
success("All Claude instances spawned in parallel mode");
|
|
847
|
+
const results = await Promise.all(promises);
|
|
848
|
+
const failed = results.filter(s => !s.success).length;
|
|
849
|
+
if (failed > 0) {
|
|
850
|
+
warning(`${failed} tasks failed`);
|
|
851
|
+
} else {
|
|
852
|
+
success("All tasks completed successfully");
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
} catch (err) {
|
|
857
|
+
error(`Failed to process workflow: ${(err as Error).message}`);
|
|
858
|
+
}
|
|
859
|
+
break;
|
|
860
|
+
}
|
|
861
|
+
|
|
862
|
+
default: {
|
|
863
|
+
console.log("Available subcommands: spawn, batch");
|
|
864
|
+
console.log("\nExamples:");
|
|
865
|
+
console.log(" claude-flow claude spawn \"implement user authentication\" --research --parallel");
|
|
866
|
+
console.log(" claude-flow claude spawn \"fix bug in payment system\" --no-permissions");
|
|
867
|
+
console.log(" claude-flow claude batch workflow.json --dry-run");
|
|
868
|
+
break;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
},
|
|
872
|
+
});
|
|
873
|
+
|
|
874
|
+
// Monitor command
|
|
875
|
+
cli.command({
|
|
876
|
+
name: "monitor",
|
|
877
|
+
description: "Live monitoring dashboard",
|
|
878
|
+
options: [
|
|
879
|
+
{
|
|
880
|
+
name: "interval",
|
|
881
|
+
short: "i",
|
|
882
|
+
description: "Update interval in seconds",
|
|
883
|
+
type: "number",
|
|
884
|
+
default: 2,
|
|
885
|
+
},
|
|
886
|
+
{
|
|
887
|
+
name: "compact",
|
|
888
|
+
short: "c",
|
|
889
|
+
description: "Compact view mode",
|
|
890
|
+
type: "boolean",
|
|
891
|
+
},
|
|
892
|
+
{
|
|
893
|
+
name: "focus",
|
|
894
|
+
short: "f",
|
|
895
|
+
description: "Focus on specific component",
|
|
896
|
+
type: "string",
|
|
897
|
+
},
|
|
898
|
+
],
|
|
899
|
+
action: async (ctx: CommandContext) => {
|
|
900
|
+
try {
|
|
901
|
+
const persist = await getPersistence();
|
|
902
|
+
const stats = await persist.getStats();
|
|
903
|
+
|
|
904
|
+
// Check if orchestrator is running
|
|
905
|
+
const isRunning = await Deno.stat("orchestrator.log").then(() => true).catch(() => false);
|
|
906
|
+
|
|
907
|
+
if (!isRunning) {
|
|
908
|
+
warning("Orchestrator is not running. Start it first with 'claude-flow start'");
|
|
909
|
+
return;
|
|
910
|
+
}
|
|
911
|
+
|
|
912
|
+
info("Starting live monitoring dashboard...");
|
|
913
|
+
console.log("Press Ctrl+C to exit");
|
|
914
|
+
|
|
915
|
+
// Simple monitoring loop
|
|
916
|
+
const interval = (ctx.flags.interval as number || ctx.flags.i as number || 2) * 1000;
|
|
917
|
+
const isCompact = ctx.flags.compact as boolean || ctx.flags.c as boolean || false;
|
|
918
|
+
let running = true;
|
|
919
|
+
|
|
920
|
+
const cleanup = () => {
|
|
921
|
+
running = false;
|
|
922
|
+
console.log("\nMonitor stopped");
|
|
923
|
+
Deno.exit(0);
|
|
924
|
+
};
|
|
925
|
+
|
|
926
|
+
Deno.addSignalListener("SIGINT", cleanup);
|
|
927
|
+
Deno.addSignalListener("SIGTERM", cleanup);
|
|
928
|
+
|
|
929
|
+
// Hide cursor
|
|
930
|
+
Deno.stdout.writeSync(new TextEncoder().encode('\x1b[?25l'));
|
|
931
|
+
|
|
932
|
+
while (running) {
|
|
933
|
+
try {
|
|
934
|
+
// Clear screen
|
|
935
|
+
console.clear();
|
|
936
|
+
|
|
937
|
+
// Get latest stats
|
|
938
|
+
const currentStats = await persist.getStats();
|
|
939
|
+
const agents = await persist.getActiveAgents();
|
|
940
|
+
const tasks = await persist.getActiveTasks();
|
|
941
|
+
|
|
942
|
+
// Header
|
|
943
|
+
success("Claude-Flow Live Monitor");
|
|
944
|
+
console.log("ā".repeat(50));
|
|
945
|
+
|
|
946
|
+
// System overview
|
|
947
|
+
console.log("\nš System Overview:");
|
|
948
|
+
console.log(` š¢ Status: ${isRunning ? 'Running' : 'Stopped'}`);
|
|
949
|
+
console.log(` š¤ Agents: ${currentStats.activeAgents} active (${currentStats.totalAgents} total)`);
|
|
950
|
+
console.log(` š Tasks: ${currentStats.pendingTasks} pending (${currentStats.totalTasks} total)`);
|
|
951
|
+
console.log(` ā
Completed: ${currentStats.completedTasks} tasks`);
|
|
952
|
+
|
|
953
|
+
// Active agents
|
|
954
|
+
if (agents.length > 0 && !isCompact) {
|
|
955
|
+
console.log("\nš¤ Active Agents:");
|
|
956
|
+
for (const agent of agents.slice(0, 5)) {
|
|
957
|
+
console.log(` ⢠${agent.id.substring(0, 20)}... (${agent.type}) - ${agent.status}`);
|
|
958
|
+
}
|
|
959
|
+
if (agents.length > 5) {
|
|
960
|
+
console.log(` ... and ${agents.length - 5} more`);
|
|
961
|
+
}
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
// Active tasks
|
|
965
|
+
if (tasks.length > 0 && !isCompact) {
|
|
966
|
+
console.log("\nš Active Tasks:");
|
|
967
|
+
for (const task of tasks.slice(0, 5)) {
|
|
968
|
+
const assignedTo = task.assignedAgent ? `ā ${task.assignedAgent.substring(0, 15)}...` : '(unassigned)';
|
|
969
|
+
console.log(` ⢠${task.id.substring(0, 20)}... (${task.type}) - ${task.status} ${assignedTo}`);
|
|
970
|
+
}
|
|
971
|
+
if (tasks.length > 5) {
|
|
972
|
+
console.log(` ... and ${tasks.length - 5} more`);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
|
|
976
|
+
// Footer
|
|
977
|
+
console.log("\n" + "ā".repeat(50));
|
|
978
|
+
console.log(`Last updated: ${new Date().toLocaleTimeString()} ⢠Interval: ${interval/1000}s`);
|
|
979
|
+
|
|
980
|
+
await new Promise(resolve => setTimeout(resolve, interval));
|
|
981
|
+
} catch (err) {
|
|
982
|
+
error(`Monitor error: ${(err as Error).message}`);
|
|
983
|
+
await new Promise(resolve => setTimeout(resolve, interval));
|
|
984
|
+
}
|
|
985
|
+
}
|
|
986
|
+
|
|
987
|
+
// Show cursor
|
|
988
|
+
Deno.stdout.writeSync(new TextEncoder().encode('\x1b[?25h'));
|
|
989
|
+
|
|
990
|
+
} catch (err) {
|
|
991
|
+
error(`Failed to start monitor: ${(err as Error).message}`);
|
|
992
|
+
}
|
|
993
|
+
},
|
|
994
|
+
});
|
|
995
|
+
|
|
610
996
|
// Help command
|
|
611
997
|
cli.command({
|
|
612
998
|
name: "help",
|
|
613
999
|
description: "Show help information",
|
|
614
|
-
action: () => {
|
|
615
|
-
|
|
1000
|
+
action: (ctx: CommandContext) => {
|
|
1001
|
+
const command = ctx.args[0];
|
|
1002
|
+
|
|
1003
|
+
if (command === "claude") {
|
|
1004
|
+
console.log(bold(blue("Claude Instance Management")));
|
|
1005
|
+
console.log();
|
|
1006
|
+
console.log("Spawn and manage Claude Code instances with specific configurations.");
|
|
1007
|
+
console.log();
|
|
1008
|
+
console.log(bold("Subcommands:"));
|
|
1009
|
+
console.log(" spawn <task> Spawn Claude with specific configuration");
|
|
1010
|
+
console.log(" batch <file> Execute multiple Claude instances from workflow");
|
|
1011
|
+
console.log();
|
|
1012
|
+
console.log(bold("Spawn Options:"));
|
|
1013
|
+
console.log(" -t, --tools <tools> Allowed tools (comma-separated)");
|
|
1014
|
+
console.log(" --no-permissions Use --dangerously-skip-permissions flag");
|
|
1015
|
+
console.log(" -c, --config <file> MCP config file path");
|
|
1016
|
+
console.log(" -m, --mode <mode> Development mode (full/backend-only/frontend-only/api-only)");
|
|
1017
|
+
console.log(" --parallel Enable parallel execution with BatchTool");
|
|
1018
|
+
console.log(" --research Enable web research with WebFetchTool");
|
|
1019
|
+
console.log(" --coverage <n> Test coverage target percentage (default: 80)");
|
|
1020
|
+
console.log(" --commit <freq> Commit frequency (phase/feature/manual)");
|
|
1021
|
+
console.log(" -v, --verbose Enable verbose output");
|
|
1022
|
+
console.log(" -d, --dry-run Show what would be executed without running");
|
|
1023
|
+
console.log();
|
|
1024
|
+
console.log(bold("Examples:"));
|
|
1025
|
+
console.log(` ${blue("claude-flow claude spawn")} "implement user authentication" --research --parallel`);
|
|
1026
|
+
console.log(` ${blue("claude-flow claude spawn")} "fix payment bug" --tools "View,Edit,Bash" --no-permissions`);
|
|
1027
|
+
console.log(` ${blue("claude-flow claude batch")} workflow.json --dry-run`);
|
|
1028
|
+
console.log();
|
|
1029
|
+
console.log("For more information, see: https://github.com/ruvnet/claude-code-flow/docs/11-claude-spawning.md");
|
|
1030
|
+
} else {
|
|
1031
|
+
// Show general help
|
|
1032
|
+
cli.showHelp();
|
|
1033
|
+
}
|
|
616
1034
|
},
|
|
617
1035
|
});
|
|
618
1036
|
}
|