claude-flow 3.7.0-alpha.67 → 3.7.0-alpha.69
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/.claude/agents/github/code-review-swarm.md +1 -1
- package/package.json +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/benchmark-cosign.d.ts +29 -0
- package/v3/@claude-flow/cli/dist/src/commands/benchmark-cosign.js +222 -0
- package/v3/@claude-flow/cli/dist/src/commands/benchmark.js +3 -0
- package/v3/@claude-flow/cli/dist/src/init/claudemd-generator.js +53 -28
- package/v3/@claude-flow/cli/package.json +1 -1
- package/.claude/scheduled_tasks.lock +0 -1
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: code-review-swarm
|
|
3
3
|
description: |
|
|
4
4
|
Deploy specialized AI agents to perform comprehensive, intelligent code reviews that go beyond traditional static analysis
|
|
5
|
-
tools: mcp__claude-flow__swarm_init, mcp__claude-flow__agent_spawn, mcp__claude-flow__task_orchestrate, Bash, Read, Write, TodoWrite
|
|
5
|
+
tools: mcp__claude-flow__swarm_init, mcp__claude-flow__agent_spawn, mcp__claude-flow__task_orchestrate, mcp__claude-flow__memory_search, mcp__claude-flow__memory_store, mcp__claude-flow__memory_retrieve, mcp__claude-flow__hooks_pre-task, mcp__claude-flow__hooks_post-task, mcp__claude-flow__hooks_route, Bash, Read, Write, TodoWrite
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# Code Review Swarm - Automated Code Review with AI Agents
|
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.69",
|
|
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",
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-121 Phase 26 — `ruflo benchmark cosign` CLI subcommand.
|
|
3
|
+
*
|
|
4
|
+
* Phase 24 shipped the M-of-N cryptographic primitive (`coSign()`).
|
|
5
|
+
* Phase 25 shipped the consumer-facing verify command. This phase
|
|
6
|
+
* closes the loop with the **third-party-verifier workflow**:
|
|
7
|
+
*
|
|
8
|
+
* # vendor publishes ledger.json + a benchmark claim
|
|
9
|
+
* # third party reviews + co-signs
|
|
10
|
+
* npx ruflo benchmark cosign vendor-ledger.json \
|
|
11
|
+
* --entry 11 \
|
|
12
|
+
* --label "independent-auditor" \
|
|
13
|
+
* --out audited-ledger.json
|
|
14
|
+
*
|
|
15
|
+
* # downstream consumers check the audited ledger requires
|
|
16
|
+
* # two signatures per entry
|
|
17
|
+
* npx ruflo benchmark verify audited-ledger.json --threshold 2
|
|
18
|
+
*
|
|
19
|
+
* Auto-generates an ephemeral Ed25519 keypair (writes the public
|
|
20
|
+
* key alongside the cosignature in the output ledger; private key
|
|
21
|
+
* not persisted by default). Pass `--key <path>` to persist the
|
|
22
|
+
* keypair (or read from a previously-persisted file) so the same
|
|
23
|
+
* signer can attest multiple entries / multiple ledgers with a
|
|
24
|
+
* stable identity.
|
|
25
|
+
*/
|
|
26
|
+
import type { Command } from '../types.js';
|
|
27
|
+
export declare const benchmarkCosignCommand: Command;
|
|
28
|
+
export default benchmarkCosignCommand;
|
|
29
|
+
//# sourceMappingURL=benchmark-cosign.d.ts.map
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ADR-121 Phase 26 — `ruflo benchmark cosign` CLI subcommand.
|
|
3
|
+
*
|
|
4
|
+
* Phase 24 shipped the M-of-N cryptographic primitive (`coSign()`).
|
|
5
|
+
* Phase 25 shipped the consumer-facing verify command. This phase
|
|
6
|
+
* closes the loop with the **third-party-verifier workflow**:
|
|
7
|
+
*
|
|
8
|
+
* # vendor publishes ledger.json + a benchmark claim
|
|
9
|
+
* # third party reviews + co-signs
|
|
10
|
+
* npx ruflo benchmark cosign vendor-ledger.json \
|
|
11
|
+
* --entry 11 \
|
|
12
|
+
* --label "independent-auditor" \
|
|
13
|
+
* --out audited-ledger.json
|
|
14
|
+
*
|
|
15
|
+
* # downstream consumers check the audited ledger requires
|
|
16
|
+
* # two signatures per entry
|
|
17
|
+
* npx ruflo benchmark verify audited-ledger.json --threshold 2
|
|
18
|
+
*
|
|
19
|
+
* Auto-generates an ephemeral Ed25519 keypair (writes the public
|
|
20
|
+
* key alongside the cosignature in the output ledger; private key
|
|
21
|
+
* not persisted by default). Pass `--key <path>` to persist the
|
|
22
|
+
* keypair (or read from a previously-persisted file) so the same
|
|
23
|
+
* signer can attest multiple entries / multiple ledgers with a
|
|
24
|
+
* stable identity.
|
|
25
|
+
*/
|
|
26
|
+
import { promises as fs } from 'node:fs';
|
|
27
|
+
import { resolve } from 'node:path';
|
|
28
|
+
import { generateKeyPairSync, createPrivateKey, createPublicKey } from 'node:crypto';
|
|
29
|
+
import { output } from '../output.js';
|
|
30
|
+
async function loadOrGenerateKeypair(keyPath) {
|
|
31
|
+
if (keyPath) {
|
|
32
|
+
const abs = resolve(process.cwd(), keyPath);
|
|
33
|
+
try {
|
|
34
|
+
const raw = await fs.readFile(abs, 'utf8');
|
|
35
|
+
const parsed = JSON.parse(raw);
|
|
36
|
+
const privateKey = createPrivateKey({ key: Buffer.from(parsed.privateKey, 'hex'), format: 'der', type: 'pkcs8' });
|
|
37
|
+
const publicKey = createPublicKey({ key: Buffer.from(parsed.publicKey, 'hex'), format: 'der', type: 'spki' });
|
|
38
|
+
return { keypair: { privateKey, publicKey }, source: 'loaded' };
|
|
39
|
+
}
|
|
40
|
+
catch (err) {
|
|
41
|
+
// File doesn't exist yet — generate a fresh keypair and persist it.
|
|
42
|
+
const kp = generateKeyPairSync('ed25519');
|
|
43
|
+
const pkcs8 = kp.privateKey.export({ type: 'pkcs8', format: 'der' }).toString('hex');
|
|
44
|
+
const spki = kp.publicKey.export({ type: 'spki', format: 'der' }).toString('hex');
|
|
45
|
+
await fs.writeFile(abs, JSON.stringify({ privateKey: pkcs8, publicKey: spki }, null, 2));
|
|
46
|
+
return { keypair: kp, source: 'persisted' };
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
return { keypair: generateKeyPairSync('ed25519'), source: 'generated' };
|
|
50
|
+
}
|
|
51
|
+
export const benchmarkCosignCommand = {
|
|
52
|
+
name: 'cosign',
|
|
53
|
+
description: 'Add a third-party co-signature to an entry in a benchmark ledger (Phase 24 M-of-N attestation)',
|
|
54
|
+
options: [
|
|
55
|
+
{
|
|
56
|
+
name: 'entry',
|
|
57
|
+
short: 'e',
|
|
58
|
+
type: 'number',
|
|
59
|
+
description: 'Entry sequence number to co-sign (1-based). Default: last entry.',
|
|
60
|
+
},
|
|
61
|
+
{
|
|
62
|
+
name: 'label',
|
|
63
|
+
short: 'l',
|
|
64
|
+
type: 'string',
|
|
65
|
+
description: 'Human-readable label for this signer (e.g. "third-party-verifier")',
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
name: 'out',
|
|
69
|
+
short: 'o',
|
|
70
|
+
type: 'string',
|
|
71
|
+
description: 'Output path for the updated ledger. Default: overwrite the input.',
|
|
72
|
+
},
|
|
73
|
+
{
|
|
74
|
+
name: 'key',
|
|
75
|
+
short: 'k',
|
|
76
|
+
type: 'string',
|
|
77
|
+
description: 'Path to a JSON keypair file (pkcs8 + spki hex). If missing, a fresh ephemeral key is generated; if path doesn\'t exist, a new key is generated and persisted there.',
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
name: 'all',
|
|
81
|
+
type: 'boolean',
|
|
82
|
+
description: 'Co-sign EVERY entry in the ledger (useful for batch attestation by a single signer).',
|
|
83
|
+
default: 'false',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
name: 'json',
|
|
87
|
+
type: 'boolean',
|
|
88
|
+
description: 'Output JSON instead of human-readable',
|
|
89
|
+
default: 'false',
|
|
90
|
+
},
|
|
91
|
+
],
|
|
92
|
+
examples: [
|
|
93
|
+
{ command: 'ruflo benchmark cosign ledger.json --entry 11 --label "auditor-A"', description: 'Co-sign entry 11 with an ephemeral key' },
|
|
94
|
+
{ command: 'ruflo benchmark cosign ledger.json --all --label "release-gate" --key ./auditor.key.json', description: 'Co-sign every entry with a persisted key' },
|
|
95
|
+
{ command: 'ruflo benchmark cosign ledger.json -e 11 -o audited.json', description: 'Write the cosigned ledger to a new file' },
|
|
96
|
+
],
|
|
97
|
+
action: async (ctx) => {
|
|
98
|
+
const pathArg = ctx.args[0];
|
|
99
|
+
const asJson = ctx.flags.json === true || ctx.flags.json === 'true';
|
|
100
|
+
const all = ctx.flags.all === true || ctx.flags.all === 'true';
|
|
101
|
+
const entryFlag = ctx.flags.entry !== undefined ? Number(ctx.flags.entry) : undefined;
|
|
102
|
+
const label = ctx.flags.label;
|
|
103
|
+
const outPath = ctx.flags.out;
|
|
104
|
+
const keyPath = ctx.flags.key;
|
|
105
|
+
if (!pathArg || typeof pathArg !== 'string') {
|
|
106
|
+
const err = 'usage: ruflo benchmark cosign <path-to-ledger.json> [--entry N | --all] [--label "name"] [--out path] [--key path] [--json]';
|
|
107
|
+
if (asJson)
|
|
108
|
+
output.printJson({ ok: false, error: err });
|
|
109
|
+
else
|
|
110
|
+
output.printError(err);
|
|
111
|
+
return { success: false, exitCode: 1 };
|
|
112
|
+
}
|
|
113
|
+
if (!all && entryFlag !== undefined && (!Number.isFinite(entryFlag) || entryFlag < 1)) {
|
|
114
|
+
const err = `--entry must be a positive integer, got: ${ctx.flags.entry}`;
|
|
115
|
+
if (asJson)
|
|
116
|
+
output.printJson({ ok: false, error: err });
|
|
117
|
+
else
|
|
118
|
+
output.printError(err);
|
|
119
|
+
return { success: false, exitCode: 1 };
|
|
120
|
+
}
|
|
121
|
+
const inPath = resolve(process.cwd(), pathArg);
|
|
122
|
+
let raw;
|
|
123
|
+
try {
|
|
124
|
+
raw = await fs.readFile(inPath, 'utf8');
|
|
125
|
+
}
|
|
126
|
+
catch (err) {
|
|
127
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
128
|
+
if (asJson)
|
|
129
|
+
output.printJson({ ok: false, error: `cannot read ${inPath}: ${msg}` });
|
|
130
|
+
else
|
|
131
|
+
output.printError(`Cannot read ${inPath}: ${msg}`);
|
|
132
|
+
return { success: false, exitCode: 1 };
|
|
133
|
+
}
|
|
134
|
+
let ledger;
|
|
135
|
+
try {
|
|
136
|
+
ledger = JSON.parse(raw);
|
|
137
|
+
}
|
|
138
|
+
catch (err) {
|
|
139
|
+
const msg = err instanceof Error ? err.message : String(err);
|
|
140
|
+
if (asJson)
|
|
141
|
+
output.printJson({ ok: false, error: `not valid JSON: ${msg}` });
|
|
142
|
+
else
|
|
143
|
+
output.printError(`Not valid JSON: ${msg}`);
|
|
144
|
+
return { success: false, exitCode: 1 };
|
|
145
|
+
}
|
|
146
|
+
if (typeof ledger.version !== 'number' || !Array.isArray(ledger.entries) || ledger.entries.length === 0) {
|
|
147
|
+
const err = `not a benchmark ledger — expected { version: number, entries: [non-empty] }`;
|
|
148
|
+
if (asJson)
|
|
149
|
+
output.printJson({ ok: false, error: err });
|
|
150
|
+
else
|
|
151
|
+
output.printError(err);
|
|
152
|
+
return { success: false, exitCode: 1 };
|
|
153
|
+
}
|
|
154
|
+
// Load or generate the signing keypair.
|
|
155
|
+
const { keypair, source: keypairSource } = await loadOrGenerateKeypair(keyPath);
|
|
156
|
+
// Determine which entries to co-sign.
|
|
157
|
+
let targetIndices;
|
|
158
|
+
if (all) {
|
|
159
|
+
targetIndices = ledger.entries.map((_, i) => i);
|
|
160
|
+
}
|
|
161
|
+
else {
|
|
162
|
+
const seq = entryFlag ?? ledger.entries[ledger.entries.length - 1].sequence;
|
|
163
|
+
const idx = ledger.entries.findIndex(e => e.sequence === seq);
|
|
164
|
+
if (idx === -1) {
|
|
165
|
+
const err = `entry sequence ${seq} not found in ledger (chain has ${ledger.entries.length} entries with sequences 1..${ledger.entries.length})`;
|
|
166
|
+
if (asJson)
|
|
167
|
+
output.printJson({ ok: false, error: err });
|
|
168
|
+
else
|
|
169
|
+
output.printError(err);
|
|
170
|
+
return { success: false, exitCode: 1 };
|
|
171
|
+
}
|
|
172
|
+
targetIndices = [idx];
|
|
173
|
+
}
|
|
174
|
+
// Lazy-load the cosign primitive from the published embeddings package.
|
|
175
|
+
const { coSign } = await import('@claude-flow/embeddings/witness-ledger');
|
|
176
|
+
// Mutate a copy of the ledger.
|
|
177
|
+
const newEntries = ledger.entries.map((e, i) => targetIndices.includes(i)
|
|
178
|
+
? coSign(e, keypair, label ? { signerLabel: label } : {})
|
|
179
|
+
: e);
|
|
180
|
+
const newLedger = { ...ledger, entries: newEntries };
|
|
181
|
+
// Write output.
|
|
182
|
+
const writePath = resolve(process.cwd(), outPath ?? pathArg);
|
|
183
|
+
await fs.writeFile(writePath, JSON.stringify(newLedger, null, 2));
|
|
184
|
+
const publicKeyHex = keypair.publicKey.export({ type: 'spki', format: 'der' }).toString('hex');
|
|
185
|
+
if (asJson) {
|
|
186
|
+
output.printJson({
|
|
187
|
+
ok: true,
|
|
188
|
+
inPath,
|
|
189
|
+
outPath: writePath,
|
|
190
|
+
entriesCosigned: targetIndices.length,
|
|
191
|
+
targetSequences: targetIndices.map(i => ledger.entries[i].sequence),
|
|
192
|
+
signerLabel: label ?? null,
|
|
193
|
+
publicKey: publicKeyHex,
|
|
194
|
+
keypairSource,
|
|
195
|
+
});
|
|
196
|
+
return { success: true, exitCode: 0 };
|
|
197
|
+
}
|
|
198
|
+
output.writeln();
|
|
199
|
+
output.writeln(output.bold(`Co-signed ${targetIndices.length} entr${targetIndices.length === 1 ? 'y' : 'ies'}`));
|
|
200
|
+
output.writeln(output.dim('─'.repeat(60)));
|
|
201
|
+
output.writeln(` input: ${inPath}`);
|
|
202
|
+
output.writeln(` output: ${writePath}`);
|
|
203
|
+
output.writeln(` signer label: ${label ?? '(unlabeled)'}`);
|
|
204
|
+
output.writeln(` signer pubkey: ${publicKeyHex.slice(0, 32)}...`);
|
|
205
|
+
output.writeln(` keypair: ${keypairSource}${keyPath ? ` → ${keyPath}` : ''}`);
|
|
206
|
+
output.writeln();
|
|
207
|
+
output.writeln(' entries:');
|
|
208
|
+
for (const i of targetIndices) {
|
|
209
|
+
const e = newEntries[i];
|
|
210
|
+
const cosigCount = Array.isArray(e.cosignatures) ? e.cosignatures.length : 0;
|
|
211
|
+
const hashShort = e.contentHash.slice(0, 12) + '…';
|
|
212
|
+
output.writeln(` [${String(e.sequence).padStart(2)}] ${e.benchmark.padEnd(28)} now ${1 + cosigCount} sigs (${hashShort})`);
|
|
213
|
+
}
|
|
214
|
+
output.writeln();
|
|
215
|
+
output.writeln(`Next: verify the cosigned ledger with the new threshold:`);
|
|
216
|
+
output.writeln(output.dim(` npx ruflo benchmark verify ${writePath} --threshold 2`));
|
|
217
|
+
output.writeln();
|
|
218
|
+
return { success: true, exitCode: 0 };
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
export default benchmarkCosignCommand;
|
|
222
|
+
//# sourceMappingURL=benchmark-cosign.js.map
|
|
@@ -425,6 +425,8 @@ const allCommand = {
|
|
|
425
425
|
// ============================================================================
|
|
426
426
|
// ADR-121 Phase 25 — `benchmark verify` for the chained witness ledger.
|
|
427
427
|
import { benchmarkVerifyCommand } from './benchmark-verify.js';
|
|
428
|
+
// ADR-121 Phase 26 — `benchmark cosign` for M-of-N third-party attestation.
|
|
429
|
+
import { benchmarkCosignCommand } from './benchmark-cosign.js';
|
|
428
430
|
export const benchmarkCommand = {
|
|
429
431
|
name: 'benchmark',
|
|
430
432
|
description: 'Performance benchmarking for self-learning and neural systems',
|
|
@@ -434,6 +436,7 @@ export const benchmarkCommand = {
|
|
|
434
436
|
memoryCommand,
|
|
435
437
|
allCommand,
|
|
436
438
|
benchmarkVerifyCommand,
|
|
439
|
+
benchmarkCosignCommand,
|
|
437
440
|
],
|
|
438
441
|
examples: [
|
|
439
442
|
{ command: 'claude-flow benchmark pretrain', description: 'Benchmark pre-training system' },
|
|
@@ -19,49 +19,74 @@ function behavioralRules() {
|
|
|
19
19
|
- Validate input at system boundaries`;
|
|
20
20
|
}
|
|
21
21
|
function agentComms() {
|
|
22
|
-
return `## Agent Comms
|
|
22
|
+
return `## Agent Comms — Reality-Based Coordination
|
|
23
23
|
|
|
24
|
-
|
|
24
|
+
**Tool-availability asymmetry:** \`SendMessage\` works **lead↔subagent** and lead↔lead, but **NOT subagent↔subagent**. Subagents spawned via the \`Agent\` tool are stateless one-shot workers — they have no inbox, cannot wait for events, and \`SendMessage\`/\`TaskUpdate\` are typically not in their tool allowlists. The \`hive-mind_*\` MCP tools provide coordination **metadata** (registry, consensus state) but do NOT grant subagents communication channels. Patterns that assume peer messaging will silently fail — agents either abort cleanly or run open-loop with stale assumptions. (See ruvnet/ruflo#2028 for the diagnosis.)
|
|
25
|
+
|
|
26
|
+
### Canonical pattern: memory-as-bus, lead-orchestrated phases
|
|
25
27
|
|
|
26
28
|
\`\`\`
|
|
27
|
-
Lead (
|
|
28
|
-
|
|
29
|
+
Lead (the orchestrator)
|
|
30
|
+
│
|
|
31
|
+
├─ spawns agent → agent reads inputs from memory keys → writes outputs to memory keys → completes
|
|
32
|
+
│
|
|
33
|
+
├─ verifies outputs in memory
|
|
34
|
+
│
|
|
35
|
+
└─ spawns next agent with explicit input-key list in its brief
|
|
29
36
|
\`\`\`
|
|
30
37
|
|
|
31
|
-
|
|
38
|
+
All inter-agent state lives in a shared memory namespace (\`memory_store\` / \`memory_search\`). Lead-to-subagent \`SendMessage\` is fine when needed; subagent-to-subagent \`SendMessage\` is not.
|
|
39
|
+
|
|
40
|
+
### Spawning rules
|
|
41
|
+
|
|
42
|
+
- **Parallelize ONLY when work is genuinely independent** (no upstream dependency between siblings).
|
|
43
|
+
- **Spawn dependent agents only after the lead confirms upstream outputs are in memory.** Do NOT tell a downstream agent to "WAIT for SendMessage from X" — it has no mechanism to wait; it will abort.
|
|
44
|
+
- **Every subagent brief MUST include a degraded-mode paragraph** at the top: *"If your expected coordination tools (SendMessage, TaskUpdate, hive-mind_*) are missing, do NOT abort. Read these specific source files directly, write outputs to these specific memory keys, and complete your phase."*
|
|
45
|
+
- **Name agents** — \`name: "role"\` makes them addressable by the lead even though they cannot address each other.
|
|
46
|
+
- **After spawning**: STOP, tell user what's running, wait for completion notifications. No polling.
|
|
47
|
+
|
|
48
|
+
### Spawning example (memory-as-bus)
|
|
32
49
|
|
|
33
50
|
\`\`\`javascript
|
|
34
|
-
//
|
|
35
|
-
Agent({
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
Agent({
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
// Kick off the pipeline
|
|
47
|
-
SendMessage({ to: "researcher", summary: "Start", message: "[task context]" })
|
|
51
|
+
// Phase 1 — independent parallel work
|
|
52
|
+
Agent({
|
|
53
|
+
prompt: "Read docs at <paths>. Write inventory JSON to memory key phase1/researcher/inventory in namespace <ns>. Degraded mode: if memory tools missing, return inventory in your final message.",
|
|
54
|
+
subagent_type: "researcher", name: "researcher", run_in_background: true
|
|
55
|
+
})
|
|
56
|
+
Agent({
|
|
57
|
+
prompt: "Walk the source tree. Write capability matrix to memory key phase1/coder/capability-matrix. Degraded mode: ...",
|
|
58
|
+
subagent_type: "coder", name: "source-reader", run_in_background: true
|
|
59
|
+
})
|
|
60
|
+
|
|
61
|
+
// AFTER both Phase 1 agents complete (lead verifies via memory_search), THEN spawn Phase 2.
|
|
62
|
+
// Each Phase 2 agent's brief explicitly lists the Phase 1 memory keys it should read.
|
|
48
63
|
\`\`\`
|
|
49
64
|
|
|
50
65
|
### Patterns
|
|
51
66
|
|
|
52
67
|
| Pattern | Flow | Use When |
|
|
53
68
|
|---------|------|----------|
|
|
54
|
-
| **
|
|
55
|
-
| **Fan-out** | Lead → A, B, C → Lead | Independent parallel work (research) |
|
|
56
|
-
| **
|
|
69
|
+
| **Sequential pipeline** | Lead → A → (verify in memory) → B → (verify) → C | Phase dependencies (audit, complex refactor) |
|
|
70
|
+
| **Fan-out** | Lead → A, B, C (parallel) → Lead aggregates from memory | Independent parallel work (research, multi-lens critique) |
|
|
71
|
+
| **Lead-as-bus** | Subagents → Lead → reroute by spawning next | Workaround when supervisor↔workers coordination needed |
|
|
72
|
+
|
|
73
|
+
### Anti-patterns (will silently fail)
|
|
57
74
|
|
|
58
|
-
|
|
75
|
+
- "WAIT for SendMessage from X" in a subagent prompt — no mechanism to wait
|
|
76
|
+
- "SendMessage findings to architect" in a subagent prompt — architect can't receive
|
|
77
|
+
- Spawning N dependent agents in one batch expecting them to chain via messages — they won't
|
|
78
|
+
- Relying on \`hive-mind_consensus\` to gather subagent votes — subagents aren't registered hive workers
|
|
59
79
|
|
|
60
|
-
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
80
|
+
### Lead-only SendMessage (still works)
|
|
81
|
+
|
|
82
|
+
\`SendMessage\` is still useful for **lead → subagent** redirects and priority changes:
|
|
83
|
+
|
|
84
|
+
\`\`\`javascript
|
|
85
|
+
// Lead → subagent: redirect or update priority mid-flight
|
|
86
|
+
SendMessage({ to: "developer", summary: "Prioritize auth", message: "Auth is blocking tester, do that first." })
|
|
87
|
+
// Lead → subagent: graceful shutdown
|
|
88
|
+
SendMessage({ to: "developer", message: { type: "shutdown_request" } })
|
|
89
|
+
\`\`\``;
|
|
65
90
|
}
|
|
66
91
|
function swarmConfig(options) {
|
|
67
92
|
return `## Swarm & Routing
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.7.0-alpha.
|
|
3
|
+
"version": "3.7.0-alpha.69",
|
|
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",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"sessionId":"1fc1a1cc-9310-4991-8a7d-832dbca9ebad","pid":8051,"procStart":"Sun May 17 12:50:14 2026","acquiredAt":1779051467717}
|