claude-flow 3.7.0-alpha.17 → 3.7.0-alpha.19
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/scheduled_tasks.lock +1 -1
- package/package.json +1 -1
- package/v3/@claude-flow/cli/bin/cli.js +14 -1
- package/v3/@claude-flow/cli/dist/src/commands/hooks.js +14 -14
- package/v3/@claude-flow/cli/dist/src/memory/sona-optimizer.js +3 -0
- package/v3/@claude-flow/cli/package.json +1 -1
- package/v3/@claude-flow/shared/dist/events/event-store.js +20 -9
- package/v3/@claude-flow/shared/dist/hooks/executor.js +7 -4
- package/v3/@claude-flow/shared/dist/hooks/verify-exports.test.js +6 -6
- package/v3/@claude-flow/shared/dist/mcp/server.js +3 -6
- package/v3/@claude-flow/shared/dist/mcp/types.d.ts +4 -6
- package/v3/@claude-flow/shared/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"sessionId":"
|
|
1
|
+
{"sessionId":"e8acbe6b-1513-4c00-ac30-2b486317c5b1","pid":7565,"procStart":"Sat May 9 13:35:07 2026","acquiredAt":1778338395740}
|
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.19",
|
|
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",
|
|
@@ -39,9 +39,22 @@ console.log = (...args) => {
|
|
|
39
39
|
// Conditions:
|
|
40
40
|
// 1. stdin is being piped AND no CLI arguments provided (auto-detect)
|
|
41
41
|
// 2. stdin is being piped AND args are "mcp start" (explicit, e.g. npx claude-flow@alpha mcp start)
|
|
42
|
+
// 3. EXCEPT — if the user explicitly passed --transport <non-stdio>
|
|
43
|
+
// (e.g. -t http), defer to the parser. Without this, every smoke
|
|
44
|
+
// test or non-TTY caller of `mcp start -t http` got force-routed
|
|
45
|
+
// into stdio mode and never hit the HTTP server (#1874 follow-up).
|
|
42
46
|
const cliArgs = process.argv.slice(2);
|
|
43
47
|
const isExplicitMCP = cliArgs.length >= 1 && cliArgs[0] === 'mcp' && (cliArgs.length === 1 || cliArgs[1] === 'start');
|
|
44
|
-
const
|
|
48
|
+
const explicitNonStdioTransport = cliArgs.some((a, i) => {
|
|
49
|
+
// -t <value> | --transport <value>
|
|
50
|
+
if ((a === '-t' || a === '--transport') && cliArgs[i + 1] && cliArgs[i + 1] !== 'stdio') return true;
|
|
51
|
+
// --transport=<value>
|
|
52
|
+
if (/^--transport=/.test(a) && !/^--transport=stdio$/.test(a)) return true;
|
|
53
|
+
return false;
|
|
54
|
+
});
|
|
55
|
+
const isMCPMode = !process.stdin.isTTY
|
|
56
|
+
&& !explicitNonStdioTransport
|
|
57
|
+
&& (process.argv.length === 2 || isExplicitMCP);
|
|
45
58
|
|
|
46
59
|
if (isMCPMode) {
|
|
47
60
|
// Run MCP server mode
|
|
@@ -270,7 +270,7 @@ const preEditCommand = {
|
|
|
270
270
|
],
|
|
271
271
|
action: async (ctx) => {
|
|
272
272
|
// Default file to 'unknown' for backward compatibility (env var may be empty)
|
|
273
|
-
const filePath = ctx.
|
|
273
|
+
const filePath = ctx.flags.file || ctx.args[0] || 'unknown';
|
|
274
274
|
const operation = ctx.flags.operation || 'update';
|
|
275
275
|
output.printInfo(`Analyzing context for: ${output.highlight(filePath)}`);
|
|
276
276
|
try {
|
|
@@ -375,7 +375,7 @@ const postEditCommand = {
|
|
|
375
375
|
],
|
|
376
376
|
action: async (ctx) => {
|
|
377
377
|
// Default file to 'unknown' for backward compatibility (env var may be empty)
|
|
378
|
-
const filePath = ctx.
|
|
378
|
+
const filePath = ctx.flags.file || ctx.args[0] || 'unknown';
|
|
379
379
|
// Default success to true for backward compatibility (PostToolUse = success, PostToolUseFailure = failure)
|
|
380
380
|
const success = ctx.flags.success !== undefined ? ctx.flags.success : true;
|
|
381
381
|
output.printInfo(`Recording outcome for: ${output.highlight(filePath)}`);
|
|
@@ -458,7 +458,7 @@ const preCommandCommand = {
|
|
|
458
458
|
{ command: 'claude-flow hooks pre-command -c "npm install lodash"', description: 'Check package install' }
|
|
459
459
|
],
|
|
460
460
|
action: async (ctx) => {
|
|
461
|
-
const command = ctx.
|
|
461
|
+
const command = ctx.flags.command || ctx.args[0];
|
|
462
462
|
if (!command) {
|
|
463
463
|
output.printError('Command is required. Use --command or -c flag.');
|
|
464
464
|
return { success: false, exitCode: 1 };
|
|
@@ -567,7 +567,7 @@ const postCommandCommand = {
|
|
|
567
567
|
{ command: 'claude-flow hooks post-command -c "npm build" --success false -e 1', description: 'Record failed build' }
|
|
568
568
|
],
|
|
569
569
|
action: async (ctx) => {
|
|
570
|
-
const command = ctx.
|
|
570
|
+
const command = ctx.flags.command || ctx.args[0];
|
|
571
571
|
// Default success to true for backward compatibility
|
|
572
572
|
const success = ctx.flags.success !== undefined ? ctx.flags.success : true;
|
|
573
573
|
if (!command) {
|
|
@@ -639,7 +639,7 @@ const routeCommand = {
|
|
|
639
639
|
{ command: 'claude-flow hooks route -t "Optimize database queries" -K 5', description: 'Get top 5 suggestions' }
|
|
640
640
|
],
|
|
641
641
|
action: async (ctx) => {
|
|
642
|
-
const task = ctx.
|
|
642
|
+
const task = ctx.flags.task || ctx.args[0];
|
|
643
643
|
const topK = ctx.flags.topK || 3;
|
|
644
644
|
if (!task) {
|
|
645
645
|
output.printError('Task description is required. Use --task or -t flag.');
|
|
@@ -751,7 +751,7 @@ const explainCommand = {
|
|
|
751
751
|
{ command: 'claude-flow hooks explain -t "Optimize queries" -a coder --verbose', description: 'Verbose explanation for specific agent' }
|
|
752
752
|
],
|
|
753
753
|
action: async (ctx) => {
|
|
754
|
-
const task = ctx.
|
|
754
|
+
const task = ctx.flags.task || ctx.args[0];
|
|
755
755
|
if (!task) {
|
|
756
756
|
output.printError('Task description is required. Use --task or -t flag.');
|
|
757
757
|
return { success: false, exitCode: 1 };
|
|
@@ -1224,7 +1224,7 @@ const transferFromProjectCommand = {
|
|
|
1224
1224
|
{ command: 'claude-flow hooks transfer from-project -s ../prod --filter security -m 0.9', description: 'Transfer high-confidence security patterns' }
|
|
1225
1225
|
],
|
|
1226
1226
|
action: async (ctx) => {
|
|
1227
|
-
const sourcePath = ctx.
|
|
1227
|
+
const sourcePath = ctx.flags.source || ctx.args[0];
|
|
1228
1228
|
const minConfidence = ctx.flags.minConfidence || 0.7;
|
|
1229
1229
|
if (!sourcePath) {
|
|
1230
1230
|
output.printError('Source project path is required. Use --source or -s flag.');
|
|
@@ -1422,7 +1422,7 @@ const preTaskCommand = {
|
|
|
1422
1422
|
],
|
|
1423
1423
|
action: async (ctx) => {
|
|
1424
1424
|
const taskId = ctx.flags.taskId || `task-${Date.now().toString(36)}`;
|
|
1425
|
-
const description = ctx.
|
|
1425
|
+
const description = ctx.flags.description || ctx.args[0];
|
|
1426
1426
|
if (!description) {
|
|
1427
1427
|
output.printError('Description is required: --description "your task"');
|
|
1428
1428
|
return { success: false, exitCode: 1 };
|
|
@@ -1707,7 +1707,7 @@ const sessionRestoreCommand = {
|
|
|
1707
1707
|
{ command: 'claude-flow hooks session-restore -i session-12345', description: 'Restore specific session' }
|
|
1708
1708
|
],
|
|
1709
1709
|
action: async (ctx) => {
|
|
1710
|
-
const sessionId = ctx.
|
|
1710
|
+
const sessionId = ctx.flags.sessionId || ctx.args[0] || 'latest';
|
|
1711
1711
|
output.printInfo(`Restoring session: ${output.highlight(sessionId)}`);
|
|
1712
1712
|
try {
|
|
1713
1713
|
const result = await callMCPTool('hooks_session-restore', {
|
|
@@ -2519,7 +2519,7 @@ const coverageRouteCommand = {
|
|
|
2519
2519
|
{ command: 'claude-flow hooks coverage-route -t "add tests" --threshold 90', description: 'Route with custom threshold' }
|
|
2520
2520
|
],
|
|
2521
2521
|
action: async (ctx) => {
|
|
2522
|
-
const task = ctx.
|
|
2522
|
+
const task = ctx.flags.task || ctx.args[0];
|
|
2523
2523
|
const threshold = ctx.flags.threshold || 80;
|
|
2524
2524
|
const useRuvector = !ctx.flags['no-ruvector'];
|
|
2525
2525
|
if (!task) {
|
|
@@ -2739,7 +2739,7 @@ const coverageSuggestCommand = {
|
|
|
2739
2739
|
{ command: 'claude-flow hooks coverage-suggest -p src/services --threshold 90', description: 'Stricter threshold' }
|
|
2740
2740
|
],
|
|
2741
2741
|
action: async (ctx) => {
|
|
2742
|
-
const targetPath = ctx.
|
|
2742
|
+
const targetPath = ctx.flags.path || ctx.args[0];
|
|
2743
2743
|
const threshold = ctx.flags.threshold || 80;
|
|
2744
2744
|
const limit = ctx.flags.limit || 20;
|
|
2745
2745
|
if (!targetPath) {
|
|
@@ -3977,7 +3977,7 @@ const modelRouteCommand = {
|
|
|
3977
3977
|
{ command: 'claude-flow hooks model-route -t "architect auth system"', description: 'Route complex task (likely opus)' },
|
|
3978
3978
|
],
|
|
3979
3979
|
action: async (ctx) => {
|
|
3980
|
-
const task = ctx.
|
|
3980
|
+
const task = ctx.flags.task || ctx.args[0];
|
|
3981
3981
|
if (!task) {
|
|
3982
3982
|
output.printError('Task description required. Use --task or -t flag.');
|
|
3983
3983
|
return { success: false, exitCode: 1 };
|
|
@@ -4285,7 +4285,7 @@ const taskCompletedCommand = {
|
|
|
4285
4285
|
{ command: 'claude-flow hooks task-completed -i task-456 --notify-lead --quality 0.95', description: 'Complete with quality score' }
|
|
4286
4286
|
],
|
|
4287
4287
|
action: async (ctx) => {
|
|
4288
|
-
const taskId = ctx.
|
|
4288
|
+
const taskId = ctx.flags.taskId || ctx.args[0];
|
|
4289
4289
|
const trainPatterns = ctx.flags.trainPatterns !== false;
|
|
4290
4290
|
const notifyLead = ctx.flags.notifyLead !== false;
|
|
4291
4291
|
const success = ctx.flags.success !== false;
|
|
@@ -4363,7 +4363,7 @@ const notifyCommand = {
|
|
|
4363
4363
|
{ command: 'claude-flow hooks notify -m "Test failed" -l error', description: 'Send error notification' },
|
|
4364
4364
|
],
|
|
4365
4365
|
action: async (ctx) => {
|
|
4366
|
-
const message = ctx.
|
|
4366
|
+
const message = ctx.flags.message || ctx.args[0];
|
|
4367
4367
|
const level = ctx.flags.level || 'info';
|
|
4368
4368
|
if (!message) {
|
|
4369
4369
|
output.printError('Message is required: --message "your message"');
|
|
@@ -137,6 +137,9 @@ export class SONAOptimizer {
|
|
|
137
137
|
if (this.sonaEngine !== undefined)
|
|
138
138
|
return; // already attempted
|
|
139
139
|
try {
|
|
140
|
+
// @ts-ignore — @ruvector/sona is in optionalDependencies and ships
|
|
141
|
+
// no .d.ts. Runtime is gated by try/catch; TS errors here on hosts
|
|
142
|
+
// without the module resolved (e.g. CI before postinstall).
|
|
140
143
|
const sona = await import('@ruvector/sona');
|
|
141
144
|
const EngineCtor = sona.SonaEngine || sona.default?.SonaEngine;
|
|
142
145
|
if (EngineCtor) {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@claude-flow/cli",
|
|
3
|
-
"version": "3.7.0-alpha.
|
|
3
|
+
"version": "3.7.0-alpha.19",
|
|
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",
|
|
@@ -16,6 +16,7 @@
|
|
|
16
16
|
*/
|
|
17
17
|
import { EventEmitter } from 'node:events';
|
|
18
18
|
import { existsSync, readFileSync, writeFileSync } from 'node:fs';
|
|
19
|
+
import { createRequire } from 'node:module';
|
|
19
20
|
import initSqlJs from 'sql.js';
|
|
20
21
|
const DEFAULT_CONFIG = {
|
|
21
22
|
databasePath: ':memory:',
|
|
@@ -45,11 +46,21 @@ export class EventStore extends EventEmitter {
|
|
|
45
46
|
if (this.initialized)
|
|
46
47
|
return;
|
|
47
48
|
// Load sql.js WASM
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
49
|
+
let wasmLocator;
|
|
50
|
+
if (this.config.wasmPath) {
|
|
51
|
+
wasmLocator = () => this.config.wasmPath;
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
try {
|
|
55
|
+
const req = createRequire(import.meta.url);
|
|
56
|
+
const sqlJsPath = req.resolve('sql.js/dist/sql-wasm.wasm');
|
|
57
|
+
wasmLocator = () => sqlJsPath;
|
|
58
|
+
}
|
|
59
|
+
catch {
|
|
60
|
+
wasmLocator = (file) => `https://sql.js.org/dist/${file}`;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
this.SQL = await initSqlJs({ locateFile: wasmLocator });
|
|
53
64
|
// Load existing database if exists
|
|
54
65
|
if (this.config.databasePath !== ':memory:' && existsSync(this.config.databasePath)) {
|
|
55
66
|
const buffer = readFileSync(this.config.databasePath);
|
|
@@ -237,7 +248,7 @@ export class EventStore extends EventEmitter {
|
|
|
237
248
|
*/
|
|
238
249
|
async *replay(fromVersion = 0) {
|
|
239
250
|
this.ensureInitialized();
|
|
240
|
-
const stmt = this.db.prepare('SELECT * FROM events WHERE
|
|
251
|
+
const stmt = this.db.prepare('SELECT * FROM events WHERE rowid >= ? ORDER BY rowid ASC');
|
|
241
252
|
stmt.bind([fromVersion]);
|
|
242
253
|
while (stmt.step()) {
|
|
243
254
|
const row = stmt.getAsObject();
|
|
@@ -290,7 +301,7 @@ export class EventStore extends EventEmitter {
|
|
|
290
301
|
this.ensureInitialized();
|
|
291
302
|
// Total events
|
|
292
303
|
const totalStmt = this.db.prepare('SELECT COUNT(*) as count FROM events');
|
|
293
|
-
const totalRow = totalStmt.getAsObject();
|
|
304
|
+
const totalRow = totalStmt.getAsObject([]);
|
|
294
305
|
totalStmt.free();
|
|
295
306
|
const totalEvents = totalRow.count || 0;
|
|
296
307
|
// Events by type
|
|
@@ -311,11 +322,11 @@ export class EventStore extends EventEmitter {
|
|
|
311
322
|
aggStmt.free();
|
|
312
323
|
// Timestamp range
|
|
313
324
|
const rangeStmt = this.db.prepare('SELECT MIN(timestamp) as oldest, MAX(timestamp) as newest FROM events');
|
|
314
|
-
const rangeRow = rangeStmt.getAsObject();
|
|
325
|
+
const rangeRow = rangeStmt.getAsObject([]);
|
|
315
326
|
rangeStmt.free();
|
|
316
327
|
// Snapshot count
|
|
317
328
|
const snapshotStmt = this.db.prepare('SELECT COUNT(*) as count FROM snapshots');
|
|
318
|
-
const snapshotRow = snapshotStmt.getAsObject();
|
|
329
|
+
const snapshotRow = snapshotStmt.getAsObject([]);
|
|
319
330
|
snapshotStmt.free();
|
|
320
331
|
return {
|
|
321
332
|
totalEvents,
|
|
@@ -205,6 +205,8 @@ export class HookExecutor {
|
|
|
205
205
|
const results = [];
|
|
206
206
|
let currentContext = { ...initialContext };
|
|
207
207
|
let totalExecutionTime = 0;
|
|
208
|
+
let totalHooksExecuted = 0;
|
|
209
|
+
let totalHooksFailed = 0;
|
|
208
210
|
let aborted = false;
|
|
209
211
|
for (const event of events) {
|
|
210
212
|
if (aborted) {
|
|
@@ -213,6 +215,8 @@ export class HookExecutor {
|
|
|
213
215
|
const result = await this.execute(event, currentContext, options);
|
|
214
216
|
results.push(...result.results);
|
|
215
217
|
totalExecutionTime += result.totalExecutionTime;
|
|
218
|
+
totalHooksExecuted += result.hooksExecuted;
|
|
219
|
+
totalHooksFailed += result.hooksFailed;
|
|
216
220
|
// Merge context for next event
|
|
217
221
|
if (result.finalContext) {
|
|
218
222
|
currentContext = { ...currentContext, ...result.finalContext };
|
|
@@ -222,13 +226,12 @@ export class HookExecutor {
|
|
|
222
226
|
break;
|
|
223
227
|
}
|
|
224
228
|
}
|
|
225
|
-
const hooksFailed = results.filter(r => !r.success).length;
|
|
226
229
|
return {
|
|
227
|
-
success:
|
|
230
|
+
success: totalHooksFailed === 0 && !aborted,
|
|
228
231
|
results: options.collectResults ? results : [],
|
|
229
232
|
totalExecutionTime,
|
|
230
|
-
hooksExecuted:
|
|
231
|
-
hooksFailed,
|
|
233
|
+
hooksExecuted: totalHooksExecuted,
|
|
234
|
+
hooksFailed: totalHooksFailed,
|
|
232
235
|
aborted,
|
|
233
236
|
finalContext: currentContext,
|
|
234
237
|
};
|
|
@@ -22,8 +22,8 @@ describe('Hooks Module Exports', () => {
|
|
|
22
22
|
it('should export types (type-only imports)', () => {
|
|
23
23
|
expect(true).toBe(true);
|
|
24
24
|
});
|
|
25
|
-
it('should create instances from exported factories', () => {
|
|
26
|
-
const { createHookRegistry, createHookExecutor } =
|
|
25
|
+
it('should create instances from exported factories', async () => {
|
|
26
|
+
const { createHookRegistry, createHookExecutor } = await import('./index.js');
|
|
27
27
|
const registry = createHookRegistry();
|
|
28
28
|
expect(registry).toBeDefined();
|
|
29
29
|
expect(typeof registry.register).toBe('function');
|
|
@@ -32,8 +32,8 @@ describe('Hooks Module Exports', () => {
|
|
|
32
32
|
expect(executor).toBeDefined();
|
|
33
33
|
expect(typeof executor.execute).toBe('function');
|
|
34
34
|
});
|
|
35
|
-
it('should have all 26 hook events defined', () => {
|
|
36
|
-
const { HookEvent } =
|
|
35
|
+
it('should have all 26 hook events defined', async () => {
|
|
36
|
+
const { HookEvent } = await import('./index.js');
|
|
37
37
|
const expectedEvents = [
|
|
38
38
|
'PreToolUse',
|
|
39
39
|
'PostToolUse',
|
|
@@ -68,8 +68,8 @@ describe('Hooks Module Exports', () => {
|
|
|
68
68
|
expect(HookEvent[event]).toBeDefined();
|
|
69
69
|
}
|
|
70
70
|
});
|
|
71
|
-
it('should have all 5 priority levels defined', () => {
|
|
72
|
-
const { HookPriority } =
|
|
71
|
+
it('should have all 5 priority levels defined', async () => {
|
|
72
|
+
const { HookPriority } = await import('./index.js');
|
|
73
73
|
expect(HookPriority.Critical).toBe(1000);
|
|
74
74
|
expect(HookPriority.High).toBe(500);
|
|
75
75
|
expect(HookPriority.Normal).toBe(0);
|
|
@@ -59,12 +59,9 @@ export class MCPServer extends EventEmitter {
|
|
|
59
59
|
name: 'Claude-Flow MCP Server V3',
|
|
60
60
|
version: '3.0.0',
|
|
61
61
|
};
|
|
62
|
-
//
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
minor: 11,
|
|
66
|
-
patch: 5,
|
|
67
|
-
};
|
|
62
|
+
// MCP protocol version — spec-required YYYY-MM-DD date string (#1874).
|
|
63
|
+
// Claude Code's Zod validator rejects any other shape.
|
|
64
|
+
protocolVersion = '2024-11-05';
|
|
68
65
|
// Server capabilities
|
|
69
66
|
capabilities = {
|
|
70
67
|
logging: { level: 'info' },
|
|
@@ -17,13 +17,11 @@
|
|
|
17
17
|
*/
|
|
18
18
|
export type JsonRpcVersion = '2.0';
|
|
19
19
|
/**
|
|
20
|
-
* MCP Protocol Version
|
|
20
|
+
* MCP Protocol Version. Per the [MCP spec](https://spec.modelcontextprotocol.io/specification/basic/lifecycle/#initialization)
|
|
21
|
+
* this must be a `YYYY-MM-DD` date string (e.g. `'2024-11-05'`, `'2025-06-18'`).
|
|
22
|
+
* Claude Code's Zod validator rejects any other shape (#1874).
|
|
21
23
|
*/
|
|
22
|
-
export
|
|
23
|
-
major: number;
|
|
24
|
-
minor: number;
|
|
25
|
-
patch: number;
|
|
26
|
-
}
|
|
24
|
+
export type MCPProtocolVersion = string;
|
|
27
25
|
/**
|
|
28
26
|
* MCP Request ID (can be string, number, or null)
|
|
29
27
|
*/
|