claude-flow 3.5.21 → 3.5.23

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.
Files changed (25) hide show
  1. package/.claude/helpers/hook-handler.cjs +4 -2
  2. package/README.md +9 -7
  3. package/package.json +1 -1
  4. package/v3/@claude-flow/cli/README.md +9 -7
  5. package/v3/@claude-flow/cli/dist/src/commands/hooks.js +698 -55
  6. package/v3/@claude-flow/cli/dist/src/commands/init.js +3 -1
  7. package/v3/@claude-flow/cli/dist/src/commands/neural.js +11 -5
  8. package/v3/@claude-flow/cli/dist/src/index.d.ts +1 -1
  9. package/v3/@claude-flow/cli/dist/src/index.js +2 -0
  10. package/v3/@claude-flow/cli/dist/src/mcp-tools/coordination-tools.js +191 -12
  11. package/v3/@claude-flow/cli/dist/src/mcp-tools/hive-mind-tools.js +224 -23
  12. package/v3/@claude-flow/cli/dist/src/mcp-tools/memory-tools.js +1 -0
  13. package/v3/@claude-flow/cli/dist/src/memory/ewc-consolidation.d.ts +24 -0
  14. package/v3/@claude-flow/cli/dist/src/memory/ewc-consolidation.js +59 -0
  15. package/v3/@claude-flow/cli/dist/src/memory/intelligence.d.ts +53 -0
  16. package/v3/@claude-flow/cli/dist/src/memory/intelligence.js +225 -0
  17. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.d.ts +7 -0
  18. package/v3/@claude-flow/cli/dist/src/memory/memory-initializer.js +27 -1
  19. package/v3/@claude-flow/cli/dist/src/ruvector/index.d.ts +4 -0
  20. package/v3/@claude-flow/cli/dist/src/ruvector/index.js +12 -0
  21. package/v3/@claude-flow/cli/dist/src/services/ruvector-training.d.ts +9 -1
  22. package/v3/@claude-flow/cli/dist/src/services/ruvector-training.js +223 -39
  23. package/v3/@claude-flow/cli/dist/src/services/worker-daemon.d.ts +4 -0
  24. package/v3/@claude-flow/cli/dist/src/services/worker-daemon.js +33 -5
  25. package/v3/@claude-flow/cli/package.json +1 -1
@@ -21,9 +21,11 @@ async function initCodexAction(ctx, options) {
21
21
  // Dynamic import of the Codex initializer with lazy loading fallback
22
22
  let CodexInitializer;
23
23
  // Try multiple resolution strategies for the @claude-flow/codex package
24
+ // Use a variable to prevent TypeScript from statically resolving the optional module
25
+ const codexModuleId = '@claude-flow/codex';
24
26
  const resolutionStrategies = [
25
27
  // Strategy 1: Direct import (works if installed as CLI dependency)
26
- async () => (await import('@claude-flow/codex')).CodexInitializer,
28
+ async () => (await import(codexModuleId)).CodexInitializer,
27
29
  // Strategy 2: Project node_modules (works if installed in user's project)
28
30
  async () => {
29
31
  const projectPath = path.join(ctx.cwd, 'node_modules', '@claude-flow', 'codex', 'dist', 'index.js');
@@ -68,7 +68,8 @@ const trainCommand = {
68
68
  });
69
69
  if (initResult.success) {
70
70
  wasmFeatures = initResult.features;
71
- spinner.setText(`RuVector initialized: ${wasmFeatures.join(', ')}`);
71
+ const backendLabel = initResult.backend === 'wasm' ? 'WASM' : 'JS fallback';
72
+ spinner.setText(`RuVector initialized [${backendLabel}]: ${wasmFeatures.join(', ')}`);
72
73
  }
73
74
  else {
74
75
  output.writeln(output.warning(`WASM init failed: ${initResult.error} - falling back`));
@@ -274,7 +275,8 @@ const trainCommand = {
274
275
  ];
275
276
  // Add WASM-specific metrics
276
277
  if (useWasm && wasmFeatures.length > 0) {
277
- tableData.push({ metric: 'WASM Features', value: wasmFeatures.slice(0, 3).join(', ') }, { metric: 'LoRA Adaptations', value: String(adaptations) }, { metric: 'Avg Loss', value: (totalLoss / Math.max(1, epochs)).toFixed(4) });
278
+ const backendUsed = ruvectorStats?.backend || 'unknown';
279
+ tableData.push({ metric: 'Backend', value: backendUsed === 'wasm' ? 'WASM (native)' : 'JS (fallback)' }, { metric: 'WASM Features', value: wasmFeatures.slice(0, 3).join(', ') }, { metric: 'LoRA Adaptations', value: String(adaptations) }, { metric: 'Avg Loss', value: (totalLoss / Math.max(1, epochs)).toFixed(4) });
278
280
  if (ruvectorStats?.microLoraStats) {
279
281
  tableData.push({ metric: 'MicroLoRA Delta Norm', value: ruvectorStats.microLoraStats.deltaNorm.toFixed(6) });
280
282
  }
@@ -299,7 +301,11 @@ const trainCommand = {
299
301
  output.writeln();
300
302
  output.writeln(output.success(`✓ ${patternsRecorded} patterns saved to ${persistence.patternsFile}`));
301
303
  if (useWasm && wasmFeatures.length > 0) {
302
- output.writeln(output.highlight(`✓ RuVector WASM: ${wasmFeatures.join(', ')}`));
304
+ const backendUsed = ruvectorStats?.backend || 'unknown';
305
+ const backendMsg = backendUsed === 'wasm'
306
+ ? `RuVector WASM backend: ${wasmFeatures.join(', ')}`
307
+ : `RuVector JS fallback (install @ruvector/learning-wasm for native speed): ${wasmFeatures.join(', ')}`;
308
+ output.writeln(output.highlight(`✓ ${backendMsg}`));
303
309
  }
304
310
  return {
305
311
  success: true,
@@ -375,10 +381,10 @@ const statusCommand = {
375
381
  : 'Not initialized',
376
382
  },
377
383
  {
378
- component: 'RuVector WASM',
384
+ component: 'RuVector Training',
379
385
  status: ruvectorStats.initialized ? output.success('Active') : output.dim('Not loaded'),
380
386
  details: ruvectorStats.initialized
381
- ? `MicroLoRA: ${ruvectorStats.totalAdaptations} adapts`
387
+ ? `${ruvectorStats.backend === 'wasm' ? 'WASM' : 'JS fallback'} | MicroLoRA: ${ruvectorStats.totalAdaptations} adapts`
382
388
  : 'Call neural train to initialize',
383
389
  },
384
390
  {
@@ -59,7 +59,7 @@ export * from './prompt.js';
59
59
  export * from './commands/index.js';
60
60
  export { MCPServerManager, createMCPServerManager, getServerManager, startMCPServer, stopMCPServer, getMCPServerStatus, type MCPServerOptions, type MCPServerStatus, } from './mcp-server.js';
61
61
  export { initializeMemoryDatabase, generateEmbedding, generateBatchEmbeddings, storeEntry, searchEntries, getHNSWIndex, addToHNSWIndex, searchHNSWIndex, getHNSWStatus, clearHNSWIndex, quantizeInt8, dequantizeInt8, quantizedCosineSim, getQuantizationStats, batchCosineSim, softmaxAttention, topKIndices, flashAttentionSearch, type MemoryInitResult, } from './memory/memory-initializer.js';
62
- export { initializeIntelligence, recordStep, recordTrajectory, findSimilarPatterns, getIntelligenceStats, getSonaCoordinator, getReasoningBank, clearIntelligence, benchmarkAdaptation, getAllPatterns, getPatternsByType, flushPatterns, deletePattern, clearAllPatterns, getNeuralDataDir, getPersistenceStatus, type SonaConfig, type TrajectoryStep, type Pattern, type IntelligenceStats, } from './memory/intelligence.js';
62
+ export { initializeIntelligence, recordStep, recordTrajectory, findSimilarPatterns, getIntelligenceStats, getSonaCoordinator, getReasoningBank, clearIntelligence, benchmarkAdaptation, endTrajectoryWithVerdict, distillLearning, getAllPatterns, getPatternsByType, flushPatterns, deletePattern, clearAllPatterns, getNeuralDataDir, getPersistenceStatus, type SonaConfig, type TrajectoryStep, type Pattern, type IntelligenceStats, } from './memory/intelligence.js';
63
63
  export { EWCConsolidator, getEWCConsolidator, resetEWCConsolidator, consolidatePatterns, recordPatternOutcome, getEWCStats, type PatternWeights, type EWCConfig, type ConsolidationResult, type EWCStats, } from './memory/ewc-consolidation.js';
64
64
  export { SONAOptimizer, getSONAOptimizer, resetSONAOptimizer, processTrajectory, getSuggestion, getSONAStats, type TrajectoryOutcome, type LearnedPattern, type RoutingSuggestion, type SONAStats, } from './memory/sona-optimizer.js';
65
65
  export { ErrorHandler, withErrorHandling, } from './production/error-handler.js';
@@ -453,6 +453,8 @@ export { initializeMemoryDatabase, generateEmbedding, generateBatchEmbeddings, s
453
453
  // Flash Attention-style batch operations
454
454
  batchCosineSim, softmaxAttention, topKIndices, flashAttentionSearch, } from './memory/memory-initializer.js';
455
455
  export { initializeIntelligence, recordStep, recordTrajectory, findSimilarPatterns, getIntelligenceStats, getSonaCoordinator, getReasoningBank, clearIntelligence, benchmarkAdaptation,
456
+ // RL loop API
457
+ endTrajectoryWithVerdict, distillLearning,
456
458
  // Pattern persistence API
457
459
  getAllPatterns, getPatternsByType, flushPatterns, deletePattern, clearAllPatterns, getNeuralDataDir, getPersistenceStatus, } from './memory/intelligence.js';
458
460
  // EWC++ Consolidation (Prevents Catastrophic Forgetting)
@@ -350,55 +350,234 @@ export const coordinationTools = [
350
350
  },
351
351
  {
352
352
  name: 'coordination_consensus',
353
- description: 'Manage consensus protocol',
353
+ description: 'Manage consensus protocol with BFT, Raft, or Quorum strategies',
354
354
  category: 'coordination',
355
355
  inputSchema: {
356
356
  type: 'object',
357
357
  properties: {
358
358
  action: { type: 'string', enum: ['status', 'propose', 'vote', 'commit'], description: 'Action to perform' },
359
- proposal: { type: 'object', description: 'Proposal data' },
359
+ proposal: { type: 'object', description: 'Proposal data (for propose)' },
360
+ proposalId: { type: 'string', description: 'Proposal ID (for vote/commit/status)' },
360
361
  vote: { type: 'string', enum: ['accept', 'reject'], description: 'Vote' },
362
+ voterId: { type: 'string', description: 'Voter node ID' },
363
+ strategy: { type: 'string', enum: ['bft', 'raft', 'quorum'], description: 'Consensus strategy (default: raft)' },
364
+ quorumPreset: { type: 'string', enum: ['unanimous', 'majority', 'supermajority'], description: 'Quorum threshold preset (default: majority)' },
365
+ term: { type: 'number', description: 'Term number (for raft strategy)' },
361
366
  },
362
367
  },
363
368
  handler: async (input) => {
364
369
  const store = loadCoordStore();
365
370
  const action = input.action || 'status';
371
+ const strategy = input.strategy || 'raft';
372
+ const nodeCount = Object.keys(store.nodes).length || 1;
373
+ // Initialize consensus storage in the coordination store if missing
374
+ if (!store.consensus) {
375
+ store.consensus = { pending: [], history: [] };
376
+ }
377
+ const consensus = store.consensus;
378
+ function calcRequired(strat, total, preset) {
379
+ if (total <= 0)
380
+ return 1;
381
+ if (strat === 'bft')
382
+ return Math.floor((total * 2) / 3) + 1;
383
+ if (strat === 'quorum') {
384
+ if (preset === 'unanimous')
385
+ return total;
386
+ if (preset === 'supermajority')
387
+ return Math.floor((total * 2) / 3) + 1;
388
+ }
389
+ return Math.floor(total / 2) + 1;
390
+ }
366
391
  if (action === 'status') {
367
- const nodeCount = Object.keys(store.nodes).length;
368
- const quorum = Math.floor(nodeCount / 2) + 1;
392
+ if (input.proposalId) {
393
+ // Status for specific proposal
394
+ const p = consensus.pending.find(x => x.proposalId === input.proposalId);
395
+ if (p) {
396
+ const votesFor = Object.values(p.votes).filter(v => v).length;
397
+ const votesAgainst = Object.values(p.votes).filter(v => !v).length;
398
+ return {
399
+ success: true,
400
+ proposalId: p.proposalId,
401
+ strategy: p.strategy,
402
+ status: p.status,
403
+ votesFor,
404
+ votesAgainst,
405
+ required: calcRequired(p.strategy, nodeCount, p.quorumPreset),
406
+ totalNodes: nodeCount,
407
+ resolved: false,
408
+ };
409
+ }
410
+ const h = consensus.history.find(x => x.proposalId === input.proposalId);
411
+ if (h)
412
+ return { success: true, ...h, resolved: true, historical: true };
413
+ return { success: false, error: 'Proposal not found' };
414
+ }
415
+ const quorum = calcRequired(strategy, nodeCount);
369
416
  return {
370
417
  success: true,
371
418
  algorithm: store.topology.consensusAlgorithm,
419
+ strategy,
372
420
  nodes: nodeCount,
373
421
  quorum,
422
+ pendingProposals: consensus.pending.length,
423
+ resolvedProposals: consensus.history.length,
374
424
  status: nodeCount >= quorum ? 'operational' : 'degraded',
375
425
  };
376
426
  }
377
427
  if (action === 'propose') {
378
- const proposalId = `proposal-${Date.now()}`;
428
+ const proposalId = `proposal-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
429
+ const quorumPreset = input.quorumPreset || 'majority';
430
+ const term = input.term || 1;
431
+ const required = calcRequired(strategy, nodeCount, quorumPreset);
432
+ // Raft: one pending proposal per term
433
+ if (strategy === 'raft') {
434
+ const existing = consensus.pending.find(p => p.strategy === 'raft' && p.term === term);
435
+ if (existing) {
436
+ return {
437
+ success: false,
438
+ error: `Raft term ${term} already has pending proposal: ${existing.proposalId}`,
439
+ existingProposalId: existing.proposalId,
440
+ };
441
+ }
442
+ }
443
+ consensus.pending.push({
444
+ proposalId,
445
+ type: 'coordination',
446
+ proposal: input.proposal,
447
+ proposedBy: input.voterId || 'system',
448
+ proposedAt: new Date().toISOString(),
449
+ votes: {},
450
+ status: 'pending',
451
+ strategy,
452
+ term: strategy === 'raft' ? term : undefined,
453
+ quorumPreset: strategy === 'quorum' ? quorumPreset : undefined,
454
+ byzantineVoters: strategy === 'bft' ? [] : undefined,
455
+ });
456
+ saveCoordStore(store);
379
457
  return {
380
458
  success: true,
381
459
  action: 'proposed',
382
460
  proposalId,
383
461
  proposal: input.proposal,
462
+ strategy,
384
463
  status: 'pending',
385
- requiredVotes: Math.floor(Object.keys(store.nodes).length / 2) + 1,
464
+ required,
465
+ totalNodes: nodeCount,
466
+ term: strategy === 'raft' ? term : undefined,
386
467
  };
387
468
  }
388
469
  if (action === 'vote') {
470
+ const p = consensus.pending.find(x => x.proposalId === input.proposalId);
471
+ if (!p)
472
+ return { success: false, error: 'Proposal not found or already resolved' };
473
+ const voterId = input.voterId;
474
+ if (!voterId)
475
+ return { success: false, error: 'voterId is required' };
476
+ const voteValue = input.vote === 'accept';
477
+ const pStrategy = p.strategy || 'raft';
478
+ const required = calcRequired(pStrategy, nodeCount, p.quorumPreset);
479
+ // Double-vote prevention
480
+ if (voterId in p.votes) {
481
+ if (pStrategy === 'bft' && p.votes[voterId] !== voteValue) {
482
+ if (!p.byzantineVoters)
483
+ p.byzantineVoters = [];
484
+ if (!p.byzantineVoters.includes(voterId))
485
+ p.byzantineVoters.push(voterId);
486
+ delete p.votes[voterId];
487
+ saveCoordStore(store);
488
+ return {
489
+ success: false,
490
+ byzantineDetected: true,
491
+ message: `Byzantine behavior: voter ${voterId} attempted conflicting vote. Vote invalidated.`,
492
+ byzantineVoters: p.byzantineVoters,
493
+ };
494
+ }
495
+ return { success: false, error: `Voter ${voterId} has already voted on this proposal` };
496
+ }
497
+ // BFT cross-proposal conflict check
498
+ if (pStrategy === 'bft') {
499
+ for (const other of consensus.pending) {
500
+ if (other.proposalId === p.proposalId)
501
+ continue;
502
+ if (voterId in other.votes && other.votes[voterId] !== voteValue) {
503
+ if (!p.byzantineVoters)
504
+ p.byzantineVoters = [];
505
+ if (!p.byzantineVoters.includes(voterId))
506
+ p.byzantineVoters.push(voterId);
507
+ saveCoordStore(store);
508
+ return {
509
+ success: false,
510
+ byzantineDetected: true,
511
+ message: `Byzantine behavior: voter ${voterId} cast conflicting votes across proposals.`,
512
+ byzantineVoters: p.byzantineVoters,
513
+ };
514
+ }
515
+ }
516
+ }
517
+ p.votes[voterId] = voteValue;
518
+ const votesFor = Object.values(p.votes).filter(v => v).length;
519
+ const votesAgainst = Object.values(p.votes).filter(v => !v).length;
520
+ // Resolution check
521
+ let resolved = false;
522
+ let result;
523
+ if (votesFor >= required) {
524
+ resolved = true;
525
+ result = 'approved';
526
+ }
527
+ else if (votesAgainst >= required) {
528
+ resolved = true;
529
+ result = 'rejected';
530
+ }
531
+ else if (pStrategy === 'quorum' && p.quorumPreset === 'unanimous' && votesAgainst > 0) {
532
+ resolved = true;
533
+ result = 'rejected';
534
+ }
535
+ if (resolved && result) {
536
+ p.status = result;
537
+ consensus.history.push({
538
+ proposalId: p.proposalId,
539
+ result,
540
+ votes: { for: votesFor, against: votesAgainst },
541
+ decidedAt: new Date().toISOString(),
542
+ strategy: pStrategy,
543
+ term: p.term,
544
+ byzantineDetected: p.byzantineVoters?.length ? p.byzantineVoters : undefined,
545
+ });
546
+ consensus.pending = consensus.pending.filter(x => x.proposalId !== p.proposalId);
547
+ }
548
+ saveCoordStore(store);
389
549
  return {
390
550
  success: true,
391
551
  action: 'voted',
552
+ proposalId: p.proposalId,
553
+ voterId,
392
554
  vote: input.vote,
393
- timestamp: new Date().toISOString(),
555
+ strategy: pStrategy,
556
+ votesFor,
557
+ votesAgainst,
558
+ required,
559
+ totalNodes: nodeCount,
560
+ resolved,
561
+ result: resolved ? result : undefined,
562
+ status: p.status,
394
563
  };
395
564
  }
396
565
  if (action === 'commit') {
397
- return {
398
- success: true,
399
- action: 'committed',
400
- committedAt: new Date().toISOString(),
401
- };
566
+ // Commit is a no-op confirmation for already-resolved proposals
567
+ if (input.proposalId) {
568
+ const h = consensus.history.find(x => x.proposalId === input.proposalId);
569
+ if (h) {
570
+ return {
571
+ success: true,
572
+ action: 'committed',
573
+ proposalId: input.proposalId,
574
+ result: h.result,
575
+ committedAt: new Date().toISOString(),
576
+ };
577
+ }
578
+ return { success: false, error: 'Proposal not found in resolved history. Vote must reach quorum first.' };
579
+ }
580
+ return { success: false, error: 'proposalId is required for commit' };
402
581
  }
403
582
  return { success: false, error: 'Unknown action' };
404
583
  },