claude-flow 3.10.40 → 3.10.41
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/helpers/statusline.cjs +693 -644
- package/package.json +1 -1
- package/v3/@claude-flow/cli/dist/src/commands/hive-mind.js +14 -1
- package/v3/@claude-flow/cli/dist/src/commands/hooks.js +16 -0
- package/v3/@claude-flow/cli/dist/src/init/statusline-generator.js +53 -4
- package/v3/@claude-flow/cli/dist/src/mcp-tools/hooks-tools.js +22 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.d.ts +2 -0
- package/v3/@claude-flow/cli/dist/src/memory/memory-bridge.js +2 -0
- 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.10.
|
|
3
|
+
"version": "3.10.41",
|
|
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",
|
|
@@ -306,7 +306,20 @@ async function spawnClaudeCodeInstance(swarmId, swarmName, objective, workers, f
|
|
|
306
306
|
output.printSuccess('Claude Code launched with Hive Mind coordination');
|
|
307
307
|
output.printInfo('The Queen coordinator will orchestrate all worker agents');
|
|
308
308
|
output.writeln(output.dim(`Prompt file saved at: ${promptFile}`));
|
|
309
|
-
|
|
309
|
+
// #2297: await child exit before returning. Without this, the CLI
|
|
310
|
+
// process resolves immediately, finishes, and the still-initializing
|
|
311
|
+
// `claude` child loses its controlling terminal and is killed mid-launch
|
|
312
|
+
// — visible as a stray XTVERSION reply leaking onto the next shell
|
|
313
|
+
// prompt (the terminal queried for capabilities, but the child died
|
|
314
|
+
// before reading the answer). Awaiting also makes the existing
|
|
315
|
+
// claudeProcess.on('exit', ...) log lines actually print, and lets the
|
|
316
|
+
// non-interactive (-p / --non-interactive) path complete only after
|
|
317
|
+
// Claude Code finishes.
|
|
318
|
+
const claudeExitCode = await new Promise((resolve) => {
|
|
319
|
+
claudeProcess.on('exit', (c) => resolve(c ?? 0));
|
|
320
|
+
claudeProcess.on('error', () => resolve(1));
|
|
321
|
+
});
|
|
322
|
+
return { success: claudeExitCode === 0, promptFile };
|
|
310
323
|
}
|
|
311
324
|
else if (dryRun) {
|
|
312
325
|
output.writeln();
|
|
@@ -1560,6 +1560,19 @@ const postTaskCommand = {
|
|
|
1560
1560
|
short: 'a',
|
|
1561
1561
|
description: 'Agent that executed the task',
|
|
1562
1562
|
type: 'string'
|
|
1563
|
+
},
|
|
1564
|
+
{
|
|
1565
|
+
// ADR-147 P2: nested-subagent spawn-tree capture
|
|
1566
|
+
name: 'parent-agent-id',
|
|
1567
|
+
description: 'ID of the parent agent (from Claude Code\'s parent_agent_id OTel span tag). Omit for top-level work.',
|
|
1568
|
+
type: 'string',
|
|
1569
|
+
required: false
|
|
1570
|
+
},
|
|
1571
|
+
{
|
|
1572
|
+
name: 'depth',
|
|
1573
|
+
description: 'Chain depth from root lead session (0 = lead, 1+ = subagent). Used by ADR-147 P3 depth-aware guardrail.',
|
|
1574
|
+
type: 'number',
|
|
1575
|
+
required: false
|
|
1563
1576
|
}
|
|
1564
1577
|
],
|
|
1565
1578
|
examples: [
|
|
@@ -1579,6 +1592,9 @@ const postTaskCommand = {
|
|
|
1579
1592
|
quality: ctx.flags.quality,
|
|
1580
1593
|
agent: ctx.flags.agent,
|
|
1581
1594
|
timestamp: Date.now(),
|
|
1595
|
+
// ADR-147 P2: forward spawn-tree lineage if caller supplied it
|
|
1596
|
+
parentAgentId: ctx.flags.parentAgentId,
|
|
1597
|
+
depth: ctx.flags.depth,
|
|
1582
1598
|
});
|
|
1583
1599
|
if (ctx.flags.format === 'json') {
|
|
1584
1600
|
output.printJson(result);
|
|
@@ -65,10 +65,51 @@ const CONFIG = {
|
|
|
65
65
|
const CWD = process.cwd();
|
|
66
66
|
|
|
67
67
|
// ─── Delegation cache ───────────────────────────────────────────
|
|
68
|
-
// Cache the CLI JSON result for
|
|
69
|
-
// (
|
|
68
|
+
// Cache the CLI JSON result for 60s so rapid prompt re-renders
|
|
69
|
+
// (Claude Code refreshes the statusline several times a second while
|
|
70
|
+
// streaming) don't re-invoke the CLI each time. #2337: bumped 10s→60s
|
|
71
|
+
// because 10s was far too short for how often Claude Code re-renders.
|
|
70
72
|
const CACHE_FILE = path.join(os.tmpdir(), 'ruflo-statusline-cache-' + require('crypto').createHash('md5').update(CWD).digest('hex').slice(0, 8) + '.json');
|
|
71
|
-
const CACHE_TTL_MS =
|
|
73
|
+
const CACHE_TTL_MS = 60000;
|
|
74
|
+
|
|
75
|
+
// #2337: resolve an already-installed @claude-flow/cli (or ruflo) bin so we
|
|
76
|
+
// can invoke it directly via \`node\`. The previous version called
|
|
77
|
+
// \`npx --yes @claude-flow/cli@latest\` on every uncached render, which forces
|
|
78
|
+
// a registry resolution + cold-start of the entire CLI per render. With
|
|
79
|
+
// multiple concurrent Claude Code sessions this storms the host (reporter
|
|
80
|
+
// saw load average 40-65 on a 12-core box).
|
|
81
|
+
//
|
|
82
|
+
// Returns the absolute path to bin/cli.js or null. Mirrors getPkgVersion()'s
|
|
83
|
+
// path probing (project, monorepo, plugin marketplace, global node_modules
|
|
84
|
+
// including custom-prefix layouts like ~/.npm-global).
|
|
85
|
+
function resolveCliBin() {
|
|
86
|
+
try {
|
|
87
|
+
const home = os.homedir();
|
|
88
|
+
const candidates = [
|
|
89
|
+
path.join(home, '.claude', 'plugins', 'marketplaces', 'ruflo', 'bin', 'cli.js'),
|
|
90
|
+
path.join(CWD, 'node_modules', '@claude-flow', 'cli', 'bin', 'cli.js'),
|
|
91
|
+
path.join(CWD, 'node_modules', 'ruflo', 'bin', 'cli.js'),
|
|
92
|
+
path.join(CWD, 'v3', '@claude-flow', 'cli', 'bin', 'cli.js'),
|
|
93
|
+
];
|
|
94
|
+
try {
|
|
95
|
+
const binDir = path.dirname(process.execPath);
|
|
96
|
+
const globalModuleDirs = [path.join(binDir, '..', 'lib', 'node_modules'), path.join(binDir, 'node_modules')];
|
|
97
|
+
for (const prefix of [process.env.npm_config_prefix, process.env.PREFIX, path.join(home, '.npm-global')]) {
|
|
98
|
+
if (prefix) globalModuleDirs.push(path.join(prefix, 'lib', 'node_modules'));
|
|
99
|
+
}
|
|
100
|
+
for (const gm of globalModuleDirs) {
|
|
101
|
+
candidates.push(
|
|
102
|
+
path.join(gm, 'ruflo', 'bin', 'cli.js'),
|
|
103
|
+
path.join(gm, '@claude-flow', 'cli', 'bin', 'cli.js'),
|
|
104
|
+
);
|
|
105
|
+
}
|
|
106
|
+
} catch { /* ignore */ }
|
|
107
|
+
for (const p of candidates) {
|
|
108
|
+
if (fs.existsSync(p)) return p;
|
|
109
|
+
}
|
|
110
|
+
} catch { /* ignore */ }
|
|
111
|
+
return null;
|
|
112
|
+
}
|
|
72
113
|
|
|
73
114
|
function readCache() {
|
|
74
115
|
try {
|
|
@@ -99,8 +140,16 @@ function getStatuslineData() {
|
|
|
99
140
|
if (cached) return cached;
|
|
100
141
|
|
|
101
142
|
try {
|
|
143
|
+
// #2337: prefer an already-installed CLI bin via direct \`node\` invocation
|
|
144
|
+
// — no npx, no registry round-trip, no @latest re-resolve per render.
|
|
145
|
+
// Fall back to \`npx --prefer-offline @claude-flow/cli\` (no @latest) only
|
|
146
|
+
// when nothing is installed locally, so a cold environment still works.
|
|
147
|
+
const cliBin = resolveCliBin();
|
|
148
|
+
const cmd = cliBin
|
|
149
|
+
? '"' + process.execPath + '" "' + cliBin + '" hooks statusline --json 2>/dev/null'
|
|
150
|
+
: 'npx --prefer-offline @claude-flow/cli hooks statusline --json 2>/dev/null';
|
|
102
151
|
const raw = execSync(
|
|
103
|
-
|
|
152
|
+
cmd,
|
|
104
153
|
{ encoding: 'utf-8', timeout: 8000, stdio: ['pipe', 'pipe', 'pipe'], cwd: CWD }
|
|
105
154
|
).trim();
|
|
106
155
|
// The CLI may emit preamble lines before the JSON — find the first '{'.
|
|
@@ -1239,6 +1239,9 @@ export const hooksPostTask = {
|
|
|
1239
1239
|
quality: { type: 'number', description: 'Quality score (0-1)' },
|
|
1240
1240
|
task: { type: 'string', description: 'Task description text (used for learning keyword extraction)' },
|
|
1241
1241
|
storeDecisions: { type: 'boolean', description: 'Also store routing decision in memory DB' },
|
|
1242
|
+
// ADR-147 P2: nested-subagent spawn-tree capture
|
|
1243
|
+
parentAgentId: { type: 'string', description: 'ID of the parent agent (from Claude Code\'s parent_agent_id OTel span tag / x-claude-code-parent-agent-id header). Omit for top-level work.' },
|
|
1244
|
+
depth: { type: 'number', description: 'Chain depth from root lead session (0 = lead, 1+ = subagent). Used by ADR-147 P3 depth-aware guardrail.' },
|
|
1242
1245
|
},
|
|
1243
1246
|
required: ['taskId'],
|
|
1244
1247
|
},
|
|
@@ -1258,6 +1261,22 @@ export const hooksPostTask = {
|
|
|
1258
1261
|
if (!v.valid)
|
|
1259
1262
|
return { success: false, error: v.error };
|
|
1260
1263
|
}
|
|
1264
|
+
// ADR-147 P2: validate spawn-tree lineage if provided
|
|
1265
|
+
const parentAgentId = params.parentAgentId;
|
|
1266
|
+
if (parentAgentId !== undefined) {
|
|
1267
|
+
const v = validateIdentifier(parentAgentId, 'parentAgentId');
|
|
1268
|
+
if (!v.valid)
|
|
1269
|
+
return { success: false, error: v.error };
|
|
1270
|
+
}
|
|
1271
|
+
const depthRaw = params.depth;
|
|
1272
|
+
let depth;
|
|
1273
|
+
if (depthRaw !== undefined && depthRaw !== null) {
|
|
1274
|
+
const n = Number(depthRaw);
|
|
1275
|
+
if (!Number.isInteger(n) || n < 0 || n > 32) {
|
|
1276
|
+
return { success: false, error: 'depth must be a non-negative integer ≤ 32' };
|
|
1277
|
+
}
|
|
1278
|
+
depth = n;
|
|
1279
|
+
}
|
|
1261
1280
|
// Phase 3: Wire recordFeedback through bridge → LearningSystem + ReasoningBank
|
|
1262
1281
|
let feedbackResult = null;
|
|
1263
1282
|
try {
|
|
@@ -1269,6 +1288,9 @@ export const hooksPostTask = {
|
|
|
1269
1288
|
agent,
|
|
1270
1289
|
duration: params.duration || undefined,
|
|
1271
1290
|
patterns: params.patterns || undefined,
|
|
1291
|
+
// ADR-147 P2: forward spawn-tree lineage so it lands in feedback + memory
|
|
1292
|
+
parentAgentId,
|
|
1293
|
+
depth,
|
|
1272
1294
|
});
|
|
1273
1295
|
}
|
|
1274
1296
|
catch {
|
|
@@ -1422,6 +1422,8 @@ export async function bridgeRecordFeedback(options) {
|
|
|
1422
1422
|
await learningSystem.recordFeedback({
|
|
1423
1423
|
taskId: options.taskId, success: options.success, quality: options.quality,
|
|
1424
1424
|
agent: options.agent, duration: options.duration, timestamp: Date.now(),
|
|
1425
|
+
// ADR-147 P2: forward spawn-tree lineage if present
|
|
1426
|
+
parentAgentId: options.parentAgentId, depth: options.depth,
|
|
1425
1427
|
});
|
|
1426
1428
|
controller = 'learningSystem';
|
|
1427
1429
|
updated++;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.10.
|
|
3
|
+
"version": "3.10.41",
|
|
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",
|