claude-flow 3.7.0-alpha.75 → 3.7.0-alpha.77
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/package.json +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/init.js +21 -1
- package/v3/@claude-flow/cli/dist/src/init/executor.js +41 -0
- package/v3/@claude-flow/cli/dist/src/init/types.d.ts +23 -0
- package/v3/@claude-flow/cli/dist/src/init/types.js +18 -5
- package/v3/@claude-flow/cli/dist/src/mcp-tools/agent-tools.js +31 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/swarm-tools.d.ts +28 -0
- package/v3/@claude-flow/cli/dist/src/mcp-tools/swarm-tools.js +4 -2
- package/v3/@claude-flow/cli/dist/src/services/headless-worker-executor.js +26 -3
- package/v3/@claude-flow/cli/package.json +1 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-flow",
|
|
3
|
-
"version": "3.7.0-alpha.
|
|
3
|
+
"version": "3.7.0-alpha.77",
|
|
4
4
|
"description": "Ruflo - Enterprise AI agent orchestration for Claude Code. Deploy 60+ specialized agents in coordinated swarms with self-learning, fault-tolerant consensus, vector memory, and MCP integration",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"type": "module",
|
|
@@ -145,7 +145,14 @@ const initAction = async (ctx) => {
|
|
|
145
145
|
const full = ctx.flags.full;
|
|
146
146
|
const skipClaude = ctx.flags['skip-claude'];
|
|
147
147
|
const onlyClaude = ctx.flags['only-claude'];
|
|
148
|
-
|
|
148
|
+
// #2098A — the parser handles `--no-foo` by stripping the prefix and
|
|
149
|
+
// storing `flags.foo = false` (parser.ts:291-294), not by storing
|
|
150
|
+
// `flags['no-foo'] = true`. So `--no-global` lands as
|
|
151
|
+
// `ctx.flags.global === false`. The old read of `flags['no-global']`
|
|
152
|
+
// was always undefined and silently no-op'd — every user with the flag
|
|
153
|
+
// set still got `~/.claude/CLAUDE.md` modified. Read the real key.
|
|
154
|
+
const noGlobal = ctx.flags['no-global'] === true || ctx.flags['global'] === false;
|
|
155
|
+
const allAgents = ctx.flags['all-agents'];
|
|
149
156
|
const codexMode = ctx.flags.codex;
|
|
150
157
|
const dualMode = ctx.flags.dual;
|
|
151
158
|
const cwd = ctx.cwd;
|
|
@@ -204,6 +211,12 @@ const initAction = async (ctx) => {
|
|
|
204
211
|
if (onlyClaude) {
|
|
205
212
|
options.components.runtime = false;
|
|
206
213
|
}
|
|
214
|
+
// ADR-128 Phase 3 — restore full agent set (98 agents) when user explicitly
|
|
215
|
+
// requests it. Default is the ~24-agent substrate (core, consensus, swarm,
|
|
216
|
+
// sparc, testing). Pass --all-agents to get the old behavior.
|
|
217
|
+
if (allAgents) {
|
|
218
|
+
options.agents.all = true;
|
|
219
|
+
}
|
|
207
220
|
// #1744 — opt-out of the user-global ~/.claude/CLAUDE.md "Ruflo Integration"
|
|
208
221
|
// pointer block. Default behavior (off) preserves current install for users
|
|
209
222
|
// who rely on it; opting in via --no-global keeps the global file pristine.
|
|
@@ -969,6 +982,12 @@ export const initCommand = {
|
|
|
969
982
|
type: 'boolean',
|
|
970
983
|
default: false,
|
|
971
984
|
},
|
|
985
|
+
{
|
|
986
|
+
name: 'all-agents',
|
|
987
|
+
description: 'Install all agent categories (ADR-128: default is ~24 substrate agents; this restores the full set of ~89)',
|
|
988
|
+
type: 'boolean',
|
|
989
|
+
default: false,
|
|
990
|
+
},
|
|
972
991
|
],
|
|
973
992
|
examples: [
|
|
974
993
|
{ command: 'claude-flow init', description: 'Initialize with default configuration' },
|
|
@@ -990,6 +1009,7 @@ export const initCommand = {
|
|
|
990
1009
|
{ command: 'claude-flow init --codex', description: 'Initialize for OpenAI Codex (AGENTS.md)' },
|
|
991
1010
|
{ command: 'claude-flow init --codex --full', description: 'Codex init with all 137+ skills' },
|
|
992
1011
|
{ command: 'claude-flow init --dual', description: 'Initialize for both Claude Code and Codex' },
|
|
1012
|
+
{ command: 'claude-flow init --all-agents', description: 'Install all agent categories (~89 agents; ADR-128 opt-in)' },
|
|
993
1013
|
],
|
|
994
1014
|
action: initAction,
|
|
995
1015
|
};
|
|
@@ -67,6 +67,10 @@ const SKILLS_MAP = {
|
|
|
67
67
|
};
|
|
68
68
|
/**
|
|
69
69
|
* Commands to copy based on configuration
|
|
70
|
+
* ADR-128 Phase 4: every subdirectory under .claude/commands/ now has a
|
|
71
|
+
* corresponding key. The flow-nexus/ dir was deleted (belongs to the plugin).
|
|
72
|
+
* New substrate keys default true; opt-in keys (pair, training, stream-chain,
|
|
73
|
+
* truth, verify) default false per ADR-128 §Phase 3 opt-in rationale.
|
|
70
74
|
*/
|
|
71
75
|
const COMMANDS_MAP = {
|
|
72
76
|
core: ['claude-flow-help.md', 'claude-flow-swarm.md', 'claude-flow-memory.md'],
|
|
@@ -77,6 +81,19 @@ const COMMANDS_MAP = {
|
|
|
77
81
|
monitoring: ['monitoring'],
|
|
78
82
|
optimization: ['optimization'],
|
|
79
83
|
sparc: ['sparc'],
|
|
84
|
+
// ADR-128 Phase 4 promotions (previously orphaned)
|
|
85
|
+
agents: ['agents'],
|
|
86
|
+
coordination: ['coordination'],
|
|
87
|
+
hiveMind: ['hive-mind'],
|
|
88
|
+
memory: ['memory'],
|
|
89
|
+
swarm: ['swarm'],
|
|
90
|
+
workflows: ['workflows'],
|
|
91
|
+
// Opt-in categories (non-universal; default false in CommandsConfig)
|
|
92
|
+
pair: ['pair'],
|
|
93
|
+
training: ['training'],
|
|
94
|
+
streamChain: ['stream-chain'],
|
|
95
|
+
truth: ['truth'],
|
|
96
|
+
verify: ['verify'],
|
|
80
97
|
};
|
|
81
98
|
/**
|
|
82
99
|
* Agents to copy based on configuration
|
|
@@ -869,6 +886,30 @@ async function copyCommands(targetDir, options, result) {
|
|
|
869
886
|
commandsToCopy.push(...COMMANDS_MAP.optimization);
|
|
870
887
|
if (commandsConfig.sparc)
|
|
871
888
|
commandsToCopy.push(...COMMANDS_MAP.sparc);
|
|
889
|
+
// ADR-128 Phase 4 substrate promotions
|
|
890
|
+
if (commandsConfig.agents)
|
|
891
|
+
commandsToCopy.push(...(COMMANDS_MAP.agents || []));
|
|
892
|
+
if (commandsConfig.coordination)
|
|
893
|
+
commandsToCopy.push(...(COMMANDS_MAP.coordination || []));
|
|
894
|
+
if (commandsConfig.hiveMind)
|
|
895
|
+
commandsToCopy.push(...(COMMANDS_MAP.hiveMind || []));
|
|
896
|
+
if (commandsConfig.memory)
|
|
897
|
+
commandsToCopy.push(...(COMMANDS_MAP.memory || []));
|
|
898
|
+
if (commandsConfig.swarm)
|
|
899
|
+
commandsToCopy.push(...(COMMANDS_MAP.swarm || []));
|
|
900
|
+
if (commandsConfig.workflows)
|
|
901
|
+
commandsToCopy.push(...(COMMANDS_MAP.workflows || []));
|
|
902
|
+
// ADR-128 Phase 4 opt-in categories
|
|
903
|
+
if (commandsConfig.pair)
|
|
904
|
+
commandsToCopy.push(...(COMMANDS_MAP.pair || []));
|
|
905
|
+
if (commandsConfig.training)
|
|
906
|
+
commandsToCopy.push(...(COMMANDS_MAP.training || []));
|
|
907
|
+
if (commandsConfig.streamChain)
|
|
908
|
+
commandsToCopy.push(...(COMMANDS_MAP.streamChain || []));
|
|
909
|
+
if (commandsConfig.truth)
|
|
910
|
+
commandsToCopy.push(...(COMMANDS_MAP.truth || []));
|
|
911
|
+
if (commandsConfig.verify)
|
|
912
|
+
commandsToCopy.push(...(COMMANDS_MAP.verify || []));
|
|
872
913
|
}
|
|
873
914
|
// Find source commands directory
|
|
874
915
|
const sourceCommandsDir = findSourceDir('commands', options.sourceBaseDir);
|
|
@@ -81,6 +81,7 @@ export interface SkillsConfig {
|
|
|
81
81
|
}
|
|
82
82
|
/**
|
|
83
83
|
* Commands configuration
|
|
84
|
+
* ADR-128 Phase 4: new keys for promoted substrate dirs and opt-in categories.
|
|
84
85
|
*/
|
|
85
86
|
export interface CommandsConfig {
|
|
86
87
|
/** Include core commands */
|
|
@@ -99,6 +100,28 @@ export interface CommandsConfig {
|
|
|
99
100
|
optimization: boolean;
|
|
100
101
|
/** Include SPARC commands */
|
|
101
102
|
sparc: boolean;
|
|
103
|
+
/** Include agents commands */
|
|
104
|
+
agents?: boolean;
|
|
105
|
+
/** Include coordination commands */
|
|
106
|
+
coordination?: boolean;
|
|
107
|
+
/** Include hive-mind commands */
|
|
108
|
+
hiveMind?: boolean;
|
|
109
|
+
/** Include memory commands */
|
|
110
|
+
memory?: boolean;
|
|
111
|
+
/** Include swarm commands */
|
|
112
|
+
swarm?: boolean;
|
|
113
|
+
/** Include workflows commands */
|
|
114
|
+
workflows?: boolean;
|
|
115
|
+
/** Include pair programming commands (opt-in) */
|
|
116
|
+
pair?: boolean;
|
|
117
|
+
/** Include training commands (opt-in) */
|
|
118
|
+
training?: boolean;
|
|
119
|
+
/** Include stream-chain commands (opt-in) */
|
|
120
|
+
streamChain?: boolean;
|
|
121
|
+
/** Include truth commands (opt-in) */
|
|
122
|
+
truth?: boolean;
|
|
123
|
+
/** Include verify commands (opt-in) */
|
|
124
|
+
verify?: boolean;
|
|
102
125
|
/** Include all commands */
|
|
103
126
|
all: boolean;
|
|
104
127
|
}
|
|
@@ -89,21 +89,34 @@ export const DEFAULT_INIT_OPTIONS = {
|
|
|
89
89
|
monitoring: true,
|
|
90
90
|
optimization: true,
|
|
91
91
|
sparc: true,
|
|
92
|
+
// ADR-128 Phase 4 substrate promotions (default true — core swarm substrate)
|
|
93
|
+
agents: true,
|
|
94
|
+
coordination: true,
|
|
95
|
+
hiveMind: true,
|
|
96
|
+
memory: true,
|
|
97
|
+
swarm: true,
|
|
98
|
+
workflows: true,
|
|
99
|
+
// ADR-128 Phase 4 opt-in (default false — not universal)
|
|
100
|
+
pair: false,
|
|
101
|
+
training: false,
|
|
102
|
+
streamChain: false,
|
|
103
|
+
truth: false,
|
|
104
|
+
verify: false,
|
|
92
105
|
all: false,
|
|
93
106
|
},
|
|
94
107
|
agents: {
|
|
95
108
|
core: true,
|
|
96
109
|
consensus: true,
|
|
97
|
-
github:
|
|
98
|
-
hiveMind:
|
|
110
|
+
github: false, // ADR-128 Phase 3: opt-in via --agents=github or --all-agents
|
|
111
|
+
hiveMind: false, // ADR-128 Phase 3: opt-in via --all-agents
|
|
99
112
|
sparc: true,
|
|
100
113
|
swarm: true,
|
|
101
114
|
browser: true,
|
|
102
|
-
v3:
|
|
103
|
-
optimization:
|
|
115
|
+
v3: false, // ADR-128 Phase 3: opt-in via --agents=v3 or --all-agents
|
|
116
|
+
optimization: false, // ADR-128 Phase 3: opt-in via --all-agents
|
|
104
117
|
testing: true,
|
|
105
118
|
dualMode: false, // Optional: enable with --dual flag
|
|
106
|
-
all: true
|
|
119
|
+
all: false, // ADR-128 Phase 3: was true; use --all-agents to restore
|
|
107
120
|
},
|
|
108
121
|
statusline: {
|
|
109
122
|
enabled: true,
|
|
@@ -174,6 +174,10 @@ export const agentTools = [
|
|
|
174
174
|
properties: {
|
|
175
175
|
agentType: { type: 'string', description: 'Type of agent to spawn' },
|
|
176
176
|
agentId: { type: 'string', description: 'Optional custom agent ID' },
|
|
177
|
+
// #2085 — accept swarmId so spawned agents register in the
|
|
178
|
+
// swarm.agents array that swarm_status reports. Omit to register
|
|
179
|
+
// with the most-recently-created swarm.
|
|
180
|
+
swarmId: { type: 'string', description: 'Optional swarm to register the agent with (defaults to most-recent swarm)' },
|
|
177
181
|
config: { type: 'object', description: 'Agent configuration' },
|
|
178
182
|
domain: { type: 'string', description: 'Agent domain' },
|
|
179
183
|
model: {
|
|
@@ -217,6 +221,33 @@ export const agentTools = [
|
|
|
217
221
|
};
|
|
218
222
|
store.agents[agentId] = agent;
|
|
219
223
|
saveAgentStore(store);
|
|
224
|
+
// #2085 — also push to the swarm store's agents array so that
|
|
225
|
+
// swarm_status reports the new agent. Without this, agent_spawn
|
|
226
|
+
// and swarm_status read/write separate stores and agents added
|
|
227
|
+
// post-init never show up in swarm_status.agents — confirmed for
|
|
228
|
+
// all topologies (hierarchical, mesh, etc.).
|
|
229
|
+
try {
|
|
230
|
+
const { loadSwarmStore: _loadSwarmStore, saveSwarmStore: _saveSwarmStore } = await import('./swarm-tools.js');
|
|
231
|
+
const swarmStore = _loadSwarmStore();
|
|
232
|
+
let targetSwarmId = input.swarmId || '';
|
|
233
|
+
if (!targetSwarmId) {
|
|
234
|
+
// Default to the most-recently-created swarm.
|
|
235
|
+
const all = Object.values(swarmStore.swarms);
|
|
236
|
+
const latest = all.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime())[0];
|
|
237
|
+
targetSwarmId = latest?.swarmId || '';
|
|
238
|
+
}
|
|
239
|
+
if (targetSwarmId && swarmStore.swarms[targetSwarmId]) {
|
|
240
|
+
const swarm = swarmStore.swarms[targetSwarmId];
|
|
241
|
+
if (!Array.isArray(swarm.agents))
|
|
242
|
+
swarm.agents = [];
|
|
243
|
+
// Idempotent — don't duplicate if agent_spawn is retried.
|
|
244
|
+
if (!swarm.agents.includes(agentId)) {
|
|
245
|
+
swarm.agents.push(agentId);
|
|
246
|
+
_saveSwarmStore(swarmStore);
|
|
247
|
+
}
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
catch { /* swarm store unavailable — agent still registered globally */ }
|
|
220
251
|
// Record agent in graph database (ADR-087, best-effort)
|
|
221
252
|
try {
|
|
222
253
|
const { addNode } = await import('../ruvector/graph-backend.js');
|
|
@@ -5,5 +5,33 @@
|
|
|
5
5
|
* Replaces previous stub implementations with real state tracking.
|
|
6
6
|
*/
|
|
7
7
|
import { type MCPTool } from './types.js';
|
|
8
|
+
interface SwarmState {
|
|
9
|
+
swarmId: string;
|
|
10
|
+
topology: string;
|
|
11
|
+
maxAgents: number;
|
|
12
|
+
status: 'initializing' | 'running' | 'paused' | 'shutting_down' | 'terminated';
|
|
13
|
+
agents: string[];
|
|
14
|
+
tasks: string[];
|
|
15
|
+
config: Record<string, unknown>;
|
|
16
|
+
createdAt: string;
|
|
17
|
+
updatedAt: string;
|
|
18
|
+
/**
|
|
19
|
+
* #1799 — process that initialized this swarm. Used by reconciliation
|
|
20
|
+
* on `loadSwarmStore()` to detect orphan entries whose host process has
|
|
21
|
+
* already exited (common on Windows where backgrounded daemons don't
|
|
22
|
+
* always survive shell exit). Optional for backward compat with
|
|
23
|
+
* pre-#1799 stores.
|
|
24
|
+
*/
|
|
25
|
+
pid?: number;
|
|
26
|
+
/** Reason set when status was forced to 'terminated' by reconciliation. */
|
|
27
|
+
terminationReason?: string;
|
|
28
|
+
}
|
|
29
|
+
interface SwarmStore {
|
|
30
|
+
swarms: Record<string, SwarmState>;
|
|
31
|
+
version: string;
|
|
32
|
+
}
|
|
33
|
+
export declare function loadSwarmStore(): SwarmStore;
|
|
34
|
+
export declare function saveSwarmStore(store: SwarmStore): void;
|
|
8
35
|
export declare const swarmTools: MCPTool[];
|
|
36
|
+
export {};
|
|
9
37
|
//# sourceMappingURL=swarm-tools.d.ts.map
|
|
@@ -78,7 +78,9 @@ function reconcileOrphanSwarms(store) {
|
|
|
78
78
|
}
|
|
79
79
|
return reconciled;
|
|
80
80
|
}
|
|
81
|
-
|
|
81
|
+
// #2085 — exported so `agent-tools.ts agent_spawn` can push into
|
|
82
|
+
// `swarm.agents` (the field `swarm_status` reads).
|
|
83
|
+
export function loadSwarmStore() {
|
|
82
84
|
let store = { swarms: {}, version: '3.0.0' };
|
|
83
85
|
try {
|
|
84
86
|
const path = getSwarmStatePath();
|
|
@@ -99,7 +101,7 @@ function loadSwarmStore() {
|
|
|
99
101
|
}
|
|
100
102
|
return store;
|
|
101
103
|
}
|
|
102
|
-
function saveSwarmStore(store) {
|
|
104
|
+
export function saveSwarmStore(store) {
|
|
103
105
|
ensureSwarmDir();
|
|
104
106
|
writeFileSync(getSwarmStatePath(), JSON.stringify(store, null, 2), 'utf-8');
|
|
105
107
|
}
|
|
@@ -859,11 +859,19 @@ Analyze the above codebase context and provide your response following the forma
|
|
|
859
859
|
// writes the prompt and closes stdin atomically — the EOF still
|
|
860
860
|
// unblocks `claude --print` (the original concern in #1395) but no
|
|
861
861
|
// shell tokenization touches the prompt.
|
|
862
|
+
// #2098B / #2093 — `claude --print` can spawn grandchildren (MCP
|
|
863
|
+
// server stdio bridges, plugin tools). When the head times out a
|
|
864
|
+
// plain `child.kill()` only signals the head; grandchildren get
|
|
865
|
+
// reparented to init and survive — the symptom @maxstefanakis1114
|
|
866
|
+
// diagnosed as a 5-second redispatch + subprocess-table growth.
|
|
867
|
+
// `detached: true` puts the child in its own process group so we
|
|
868
|
+
// can signal the whole tree with `process.kill(-pid, sig)`.
|
|
862
869
|
const child = spawn('claude', ['--print'], {
|
|
863
870
|
cwd: this.projectRoot,
|
|
864
871
|
env,
|
|
865
872
|
stdio: ['pipe', 'pipe', 'pipe'],
|
|
866
873
|
windowsHide: true, // Prevent phantom console windows on Windows
|
|
874
|
+
detached: process.platform !== 'win32',
|
|
867
875
|
});
|
|
868
876
|
try {
|
|
869
877
|
child.stdin?.end(prompt);
|
|
@@ -872,14 +880,29 @@ Analyze the above codebase context and provide your response following the forma
|
|
|
872
880
|
// stdin already closed (e.g. spawn failed) — `error` handler below
|
|
873
881
|
// will surface the real cause.
|
|
874
882
|
}
|
|
883
|
+
// Kill the whole process group on POSIX, fall back to the child on
|
|
884
|
+
// Windows (where setsid-style detach isn't available the same way).
|
|
885
|
+
const killTree = (signal) => {
|
|
886
|
+
if (process.platform !== 'win32' && typeof child.pid === 'number') {
|
|
887
|
+
try {
|
|
888
|
+
process.kill(-child.pid, signal);
|
|
889
|
+
return;
|
|
890
|
+
}
|
|
891
|
+
catch { /* fall through */ }
|
|
892
|
+
}
|
|
893
|
+
try {
|
|
894
|
+
child.kill(signal);
|
|
895
|
+
}
|
|
896
|
+
catch { /* already dead */ }
|
|
897
|
+
};
|
|
875
898
|
// Setup timeout
|
|
876
899
|
const timeoutHandle = setTimeout(() => {
|
|
877
900
|
if (this.processPool.has(options.executionId)) {
|
|
878
|
-
|
|
901
|
+
killTree('SIGTERM');
|
|
879
902
|
// Give it a moment to terminate gracefully
|
|
880
903
|
setTimeout(() => {
|
|
881
904
|
if (!child.killed) {
|
|
882
|
-
|
|
905
|
+
killTree('SIGKILL');
|
|
883
906
|
}
|
|
884
907
|
}, 5000);
|
|
885
908
|
}
|
|
@@ -947,7 +970,7 @@ Analyze the above codebase context and provide your response following the forma
|
|
|
947
970
|
if (!this.processPool.has(options.executionId))
|
|
948
971
|
return;
|
|
949
972
|
resolved = true;
|
|
950
|
-
|
|
973
|
+
killTree('SIGTERM');
|
|
951
974
|
cleanup();
|
|
952
975
|
resolve({
|
|
953
976
|
success: false,
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.7.0-alpha.
|
|
3
|
+
"version": "3.7.0-alpha.77",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Ruflo CLI - Enterprise AI agent orchestration with 60+ specialized agents, swarm coordination, MCP server, self-learning hooks, and vector memory for Claude Code",
|
|
6
6
|
"main": "dist/src/index.js",
|