claude-flow-novice 2.0.3 → 2.0.4
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/dist/src/cli/commands/guidance.js +487 -668
- package/dist/src/cli/commands/index-validate.js +18 -29
- package/dist/src/cli/commands/mcp-troubleshoot.js +230 -282
- package/dist/src/cli/commands/neural-goal-init.js +92 -125
- package/dist/src/cli/commands/swarm-exec.js +317 -393
- package/dist/src/cli/commands/swarm.js +1 -1
- package/dist/src/cli/commands/validate-framework.js +983 -1100
- package/dist/src/cli/commands/validate.js +144 -223
- package/dist/src/cli/simple-commands/__tests__/agent.test.js +265 -277
- package/dist/src/cli/simple-commands/__tests__/memory.test.js +6 -7
- package/dist/src/cli/simple-commands/__tests__/swarm.test.js +373 -356
- package/dist/src/cli/simple-commands/__tests__/task.test.js +6 -7
- package/dist/src/cli/simple-commands/agent.js +157 -193
- package/dist/src/cli/simple-commands/analysis.js +336 -446
- package/dist/src/cli/simple-commands/automation-executor.js +1095 -1339
- package/dist/src/cli/simple-commands/automation.js +481 -469
- package/dist/src/cli/simple-commands/batch-manager.js +261 -313
- package/dist/src/cli/simple-commands/claude-telemetry.js +241 -267
- package/dist/src/cli/simple-commands/claude-track.js +68 -90
- package/dist/src/cli/simple-commands/concurrent-display.js +266 -320
- package/dist/src/cli/simple-commands/config.js +245 -290
- package/dist/src/cli/simple-commands/coordination.js +182 -234
- package/dist/src/cli/simple-commands/enhanced-ui-views.js +812 -615
- package/dist/src/cli/simple-commands/enhanced-webui-complete.js +922 -981
- package/dist/src/cli/simple-commands/fix-hook-variables.js +274 -294
- package/dist/src/cli/simple-commands/github/gh-coordinator.js +378 -457
- package/dist/src/cli/simple-commands/github/github-api.js +535 -574
- package/dist/src/cli/simple-commands/github/init.js +276 -303
- package/dist/src/cli/simple-commands/github.js +222 -247
- package/dist/src/cli/simple-commands/goal.js +51 -63
- package/dist/src/cli/simple-commands/hive-mind/auto-save-middleware.js +208 -278
- package/dist/src/cli/simple-commands/hive-mind/communication.js +601 -696
- package/dist/src/cli/simple-commands/hive-mind/core.js +907 -979
- package/dist/src/cli/simple-commands/hive-mind/db-optimizer.js +406 -655
- package/dist/src/cli/simple-commands/hive-mind/mcp-wrapper.js +1125 -1245
- package/dist/src/cli/simple-commands/hive-mind/memory.js +854 -1090
- package/dist/src/cli/simple-commands/hive-mind/performance-optimizer.js +459 -574
- package/dist/src/cli/simple-commands/hive-mind/performance-test.js +263 -347
- package/dist/src/cli/simple-commands/hive-mind/queen.js +727 -768
- package/dist/src/cli/simple-commands/hive-mind/session-manager.js +745 -1049
- package/dist/src/cli/simple-commands/hive-mind-optimize.js +227 -283
- package/dist/src/cli/simple-commands/hive-mind-wizard.js +174 -217
- package/dist/src/cli/simple-commands/hive-mind.js +1842 -2283
- package/dist/src/cli/simple-commands/hive.js +90 -79
- package/dist/src/cli/simple-commands/hook-safety.js +431 -521
- package/dist/src/cli/simple-commands/hooks/session-start-soul.js +203 -254
- package/dist/src/cli/simple-commands/hooks.js +1064 -1204
- package/dist/src/cli/simple-commands/init/agent-copier.js +294 -319
- package/dist/src/cli/simple-commands/init/batch-init.js +496 -562
- package/dist/src/cli/simple-commands/init/claude-commands/claude-flow-commands.js +13 -19
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-claude-flow-commands.js +13 -19
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-slash-commands.js +61 -88
- package/dist/src/cli/simple-commands/init/claude-commands/optimized-sparc-commands.js +125 -150
- package/dist/src/cli/simple-commands/init/claude-commands/slash-commands.js +42 -49
- package/dist/src/cli/simple-commands/init/claude-commands/sparc-commands.js +43 -61
- package/dist/src/cli/simple-commands/init/copy-revised-templates.js +141 -147
- package/dist/src/cli/simple-commands/init/executable-wrapper.js +31 -44
- package/dist/src/cli/simple-commands/init/gitignore-updater.js +64 -90
- package/dist/src/cli/simple-commands/init/help.js +104 -107
- package/dist/src/cli/simple-commands/init/hive-mind-init.js +509 -528
- package/dist/src/cli/simple-commands/init/index.js +1510 -1759
- package/dist/src/cli/simple-commands/init/performance-monitor.js +234 -317
- package/dist/src/cli/simple-commands/init/rollback/backup-manager.js +441 -504
- package/dist/src/cli/simple-commands/init/rollback/index.js +289 -364
- package/dist/src/cli/simple-commands/init/rollback/recovery-manager.js +652 -728
- package/dist/src/cli/simple-commands/init/rollback/rollback-executor.js +416 -481
- package/dist/src/cli/simple-commands/init/rollback/state-tracker.js +369 -448
- package/dist/src/cli/simple-commands/init/sparc/roo-readme.js +1 -2
- package/dist/src/cli/simple-commands/init/sparc/roomodes-config.js +122 -99
- package/dist/src/cli/simple-commands/init/sparc/workflows.js +32 -37
- package/dist/src/cli/simple-commands/init/sparc-structure.js +55 -62
- package/dist/src/cli/simple-commands/init/template-copier.js +421 -533
- package/dist/src/cli/simple-commands/init/templates/coordination-md.js +3 -6
- package/dist/src/cli/simple-commands/init/templates/enhanced-templates.js +344 -318
- package/dist/src/cli/simple-commands/init/templates/github-safe-enhanced.js +173 -218
- package/dist/src/cli/simple-commands/init/templates/github-safe.js +65 -75
- package/dist/src/cli/simple-commands/init/templates/memory-bank-md.js +3 -6
- package/dist/src/cli/simple-commands/init/templates/readme-files.js +2 -4
- package/dist/src/cli/simple-commands/init/templates/safe-hook-patterns.js +187 -230
- package/dist/src/cli/simple-commands/init/templates/sparc-modes.js +53 -80
- package/dist/src/cli/simple-commands/init/templates/verification-claude-md.js +101 -85
- package/dist/src/cli/simple-commands/init/validation/config-validator.js +283 -330
- package/dist/src/cli/simple-commands/init/validation/health-checker.js +495 -561
- package/dist/src/cli/simple-commands/init/validation/index.js +302 -358
- package/dist/src/cli/simple-commands/init/validation/mode-validator.js +308 -359
- package/dist/src/cli/simple-commands/init/validation/post-init-validator.js +389 -366
- package/dist/src/cli/simple-commands/init/validation/pre-init-validator.js +270 -268
- package/dist/src/cli/simple-commands/init/validation/test-runner.js +427 -447
- package/dist/src/cli/simple-commands/init.js +1 -2
- package/dist/src/cli/simple-commands/mcp-health.js +131 -158
- package/dist/src/cli/simple-commands/mcp-integration-layer.js +533 -634
- package/dist/src/cli/simple-commands/mcp.js +345 -400
- package/dist/src/cli/simple-commands/memory-consolidation.js +426 -537
- package/dist/src/cli/simple-commands/memory.js +247 -311
- package/dist/src/cli/simple-commands/migrate-hooks.js +39 -46
- package/dist/src/cli/simple-commands/monitor.js +294 -363
- package/dist/src/cli/simple-commands/neural.js +51 -65
- package/dist/src/cli/simple-commands/pair-autofix-only.js +538 -662
- package/dist/src/cli/simple-commands/pair-basic.js +528 -656
- package/dist/src/cli/simple-commands/pair-old.js +430 -543
- package/dist/src/cli/simple-commands/pair-working.js +615 -751
- package/dist/src/cli/simple-commands/pair.js +615 -751
- package/dist/src/cli/simple-commands/performance-hooks.js +83 -111
- package/dist/src/cli/simple-commands/performance-metrics.js +348 -433
- package/dist/src/cli/simple-commands/process-ui-enhanced.js +708 -787
- package/dist/src/cli/simple-commands/process-ui.js +230 -254
- package/dist/src/cli/simple-commands/realtime-update-system.js +525 -611
- package/dist/src/cli/simple-commands/sparc/architecture.js +1704 -1530
- package/dist/src/cli/simple-commands/sparc/commands.js +438 -516
- package/dist/src/cli/simple-commands/sparc/completion.js +1224 -1481
- package/dist/src/cli/simple-commands/sparc/coordinator.js +913 -978
- package/dist/src/cli/simple-commands/sparc/index.js +241 -298
- package/dist/src/cli/simple-commands/sparc/phase-base.js +314 -390
- package/dist/src/cli/simple-commands/sparc/pseudocode.js +965 -869
- package/dist/src/cli/simple-commands/sparc/refinement.js +980 -1273
- package/dist/src/cli/simple-commands/sparc/specification.js +559 -645
- package/dist/src/cli/simple-commands/sparc-modes/architect.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/ask.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/code.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/debug.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/devops.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/docs-writer.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/generic.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/index.js +47 -55
- package/dist/src/cli/simple-commands/sparc-modes/integration.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/mcp.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/monitoring.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/optimization.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/security-review.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/sparc-orchestrator.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/spec-pseudocode.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/supabase-admin.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/swarm.js +101 -87
- package/dist/src/cli/simple-commands/sparc-modes/tdd.js +1 -1
- package/dist/src/cli/simple-commands/sparc-modes/tutorial.js +1 -1
- package/dist/src/cli/simple-commands/sparc.js +465 -493
- package/dist/src/cli/simple-commands/start-ui.js +108 -132
- package/dist/src/cli/simple-commands/start-wrapper.js +240 -268
- package/dist/src/cli/simple-commands/start.js +1 -1
- package/dist/src/cli/simple-commands/status.js +254 -275
- package/dist/src/cli/simple-commands/stream-chain-clean.js +128 -171
- package/dist/src/cli/simple-commands/stream-chain-fixed.js +61 -82
- package/dist/src/cli/simple-commands/stream-chain-real.js +267 -331
- package/dist/src/cli/simple-commands/stream-chain-working.js +211 -263
- package/dist/src/cli/simple-commands/stream-chain.js +260 -318
- package/dist/src/cli/simple-commands/stream-processor.js +290 -315
- package/dist/src/cli/simple-commands/swarm-executor.js +189 -222
- package/dist/src/cli/simple-commands/swarm-metrics-integration.js +208 -300
- package/dist/src/cli/simple-commands/swarm-ui.js +623 -703
- package/dist/src/cli/simple-commands/swarm-webui-integration.js +258 -286
- package/dist/src/cli/simple-commands/swarm.js +887 -1082
- package/dist/src/cli/simple-commands/task.js +161 -206
- package/dist/src/cli/simple-commands/timestamp-fix.js +59 -89
- package/dist/src/cli/simple-commands/token-tracker.js +258 -316
- package/dist/src/cli/simple-commands/tool-execution-framework.js +433 -519
- package/dist/src/cli/simple-commands/train-and-stream.js +275 -331
- package/dist/src/cli/simple-commands/training-pipeline.js +619 -725
- package/dist/src/cli/simple-commands/training.js +170 -227
- package/dist/src/cli/simple-commands/verification-hooks.js +261 -284
- package/dist/src/cli/simple-commands/verification-integration.js +389 -417
- package/dist/src/cli/simple-commands/verification-training-integration.js +486 -606
- package/dist/src/cli/simple-commands/verification.js +493 -513
- package/dist/src/cli/simple-commands/web-server.js +766 -836
- package/dist/src/cli/simple-commands/webui-validator.js +106 -124
- package/dist/src/coordination/event-bus/demo-wasm-integration.js +212 -251
- package/dist/src/coordination/event-bus/qe-event-bus.js +608 -748
- package/dist/src/coordination/event-bus/qe-event-bus.test.js +379 -454
- package/dist/src/coordination/iteration-tracker.js +363 -454
- package/dist/src/enterprise/analytics-manager.js +1135 -0
- package/dist/src/enterprise/audit-manager.js +1115 -0
- package/dist/src/enterprise/cloud-manager.js +891 -0
- package/dist/src/enterprise/deployment-manager.js +966 -0
- package/dist/src/enterprise/index.js +6 -0
- package/dist/src/enterprise/project-manager.js +584 -0
- package/dist/src/enterprise/security-manager.js +991 -0
- package/dist/src/index.js +1 -1
- package/dist/src/mcp/DEPRECATED.js +46 -60
- package/dist/src/mcp/fixes/mcp-error-fixes.js +115 -134
- package/dist/src/mcp/implementations/agent-tracker.js +114 -128
- package/dist/src/mcp/implementations/daa-tools.js +292 -350
- package/dist/src/mcp/implementations/workflow-tools.js +329 -361
- package/dist/src/mcp/mcp-config-manager.js +1183 -1331
- package/dist/src/mcp/mcp-server-novice-simplified.js +11 -17
- package/dist/src/mcp/mcp-server-novice.js +11 -17
- package/dist/src/mcp/mcp-server-sdk.js +11 -17
- package/dist/src/mcp/mcp-server.js +1620 -1484
- package/dist/src/mcp/ruv-swarm-wrapper.js +209 -239
- package/dist/src/memory/advanced-serializer.js +609 -589
- package/dist/src/memory/enhanced-examples.js +220 -305
- package/dist/src/memory/enhanced-memory.js +295 -336
- package/dist/src/memory/enhanced-session-serializer.js +408 -492
- package/dist/src/memory/fallback-memory-system.js +900 -1021
- package/dist/src/memory/fallback-store.js +93 -131
- package/dist/src/memory/high-performance-serialization.js +592 -730
- package/dist/src/memory/in-memory-store.js +161 -213
- package/dist/src/memory/index.js +123 -157
- package/dist/src/memory/lock-free-structures.js +578 -764
- package/dist/src/memory/memory-mapped-persistence.js +585 -766
- package/dist/src/memory/memory-pressure-manager.js +569 -707
- package/dist/src/memory/migration.js +358 -445
- package/dist/src/memory/shared-memory.js +641 -768
- package/dist/src/memory/sqlite-store.js +245 -325
- package/dist/src/memory/sqlite-wrapper.js +122 -151
- package/dist/src/memory/swarm-memory.js +470 -603
- package/dist/src/memory/test-example.js +126 -134
- package/dist/src/memory/ultra-fast-memory-store.js +622 -821
- package/dist/src/memory/unified-memory-manager.js +356 -437
- package/dist/src/migration/index.js +92 -0
- package/dist/src/migration/logger.js +121 -0
- package/dist/src/migration/migration-analyzer.js +268 -0
- package/dist/src/migration/migration-runner.js +522 -0
- package/dist/src/migration/migration-validator.js +285 -0
- package/dist/src/migration/progress-reporter.js +150 -0
- package/dist/src/migration/rollback-manager.js +321 -0
- package/dist/src/migration/tests/migration-system.test.js +7 -0
- package/dist/src/migration/types.js +3 -0
- package/dist/src/swarm/CodeRefactoringSwarm.js +777 -952
- package/dist/src/swarm/__tests__/integration.test.js +227 -0
- package/dist/src/swarm/__tests__/prompt-copier.test.js +344 -0
- package/dist/src/swarm/advanced-orchestrator.js +1095 -0
- package/dist/src/swarm/claude-code-interface.js +961 -0
- package/dist/src/swarm/claude-flow-executor.js +229 -0
- package/dist/src/swarm/consensus-coordinator.js +475 -0
- package/dist/src/swarm/coordinator.js +2993 -0
- package/dist/src/swarm/direct-executor.js +1180 -0
- package/dist/src/swarm/error-recovery/advanced-error-detection.js +691 -0
- package/dist/src/swarm/error-recovery/automated-recovery-workflows.js +998 -0
- package/dist/src/swarm/error-recovery/error-recovery-coordinator.js +1197 -0
- package/dist/src/swarm/error-recovery/recovery-monitoring.js +772 -0
- package/dist/src/swarm/error-recovery/resilience-architecture.js +714 -0
- package/dist/src/swarm/error-recovery/self-healing-mechanisms.js +1319 -0
- package/dist/src/swarm/error-recovery/test-error-recovery-effectiveness.js +808 -0
- package/dist/src/swarm/executor-v2.js +322 -0
- package/dist/src/swarm/executor.js +815 -0
- package/dist/src/swarm/hive-mind-integration.js +703 -0
- package/dist/src/swarm/index.js +41 -0
- package/dist/src/swarm/json-output-aggregator.js +267 -0
- package/dist/src/swarm/large-scale-coordinator.js +542 -0
- package/dist/src/swarm/mcp-integration-wrapper.js +628 -0
- package/dist/src/swarm/memory.js +1117 -0
- package/dist/src/swarm/optimizations/__tests__/optimization.test.js +348 -0
- package/dist/src/swarm/optimizations/async-file-manager.js +285 -0
- package/dist/src/swarm/optimizations/circular-buffer.js +162 -0
- package/dist/src/swarm/optimizations/connection-pool.js +244 -0
- package/dist/src/swarm/optimizations/index.js +28 -0
- package/dist/src/swarm/optimizations/optimized-executor.js +320 -0
- package/dist/src/swarm/optimizations/ttl-map.js +234 -0
- package/dist/src/swarm/prompt-cli.js +200 -0
- package/dist/src/swarm/prompt-copier-enhanced.js +202 -0
- package/dist/src/swarm/prompt-copier.js +381 -0
- package/dist/src/swarm/prompt-manager.js +295 -0
- package/dist/src/swarm/prompt-utils.js +310 -0
- package/dist/src/swarm/result-aggregator.js +718 -0
- package/dist/src/swarm/sparc-executor.js +1568 -0
- package/dist/src/swarm/strategies/auto.js +758 -0
- package/dist/src/swarm/strategies/base.js +128 -0
- package/dist/src/swarm/strategies/research.js +914 -0
- package/dist/src/swarm/strategies/strategy-metrics-patch.js +2 -0
- package/dist/src/swarm/types.js +52 -0
- package/dist/src/swarm/workers/copy-worker.js +56 -0
- package/dist/src/utils/__tests__/github-cli-safety-wrapper.test.js +332 -400
- package/dist/src/utils/github-cli-safe.js +56 -64
- package/dist/src/utils/github-cli-safety-wrapper.js +451 -546
- package/dist/src/utils/npx-isolated-cache.js +104 -119
- package/dist/src/utils/preference-manager.js +622 -652
- package/dist/src/utils/timezone-utils.js +86 -105
- package/dist/src/validators/epic-config-schema.js +214 -0
- package/dist/src/validators/index.js +10 -0
- package/dist/src/validators/swarm-init-validator.js +259 -0
- package/dist/src/validators/todowrite-batching-validator.js +215 -0
- package/dist/src/validators/todowrite-integration.js +187 -0
- package/package.json +2 -2
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Claude Flow SPARC Executor
|
|
3
|
+
* Executes tasks using the full claude-flow-novice SPARC system in non-interactive mode
|
|
4
|
+
*/ function _define_property(obj, key, value) {
|
|
5
|
+
if (key in obj) {
|
|
6
|
+
Object.defineProperty(obj, key, {
|
|
7
|
+
value: value,
|
|
8
|
+
enumerable: true,
|
|
9
|
+
configurable: true,
|
|
10
|
+
writable: true
|
|
11
|
+
});
|
|
12
|
+
} else {
|
|
13
|
+
obj[key] = value;
|
|
14
|
+
}
|
|
15
|
+
return obj;
|
|
16
|
+
}
|
|
17
|
+
import { Logger } from "../core/logger.js";
|
|
18
|
+
import { spawn } from "node:child_process";
|
|
19
|
+
import { getClaudeFlowBin } from "../utils/paths.js";
|
|
20
|
+
export class ClaudeFlowExecutor {
|
|
21
|
+
async executeTask(task, agent, targetDir) {
|
|
22
|
+
this.logger.info('Executing task with Claude Flow SPARC', {
|
|
23
|
+
taskId: task.id.id,
|
|
24
|
+
taskName: task.name,
|
|
25
|
+
agentType: agent.type,
|
|
26
|
+
targetDir
|
|
27
|
+
});
|
|
28
|
+
const startTime = Date.now();
|
|
29
|
+
try {
|
|
30
|
+
// Determine the SPARC mode based on task type and agent type
|
|
31
|
+
const sparcMode = this.determineSparcMode(task, agent);
|
|
32
|
+
// Build the command
|
|
33
|
+
const command = this.buildSparcCommand(task, sparcMode, targetDir);
|
|
34
|
+
this.logger.info('Executing SPARC command', {
|
|
35
|
+
mode: sparcMode,
|
|
36
|
+
command: command.join(' ')
|
|
37
|
+
});
|
|
38
|
+
// Execute the command
|
|
39
|
+
const result = await this.executeCommand(command);
|
|
40
|
+
const endTime = Date.now();
|
|
41
|
+
const executionTime = endTime - startTime;
|
|
42
|
+
return {
|
|
43
|
+
output: result.output,
|
|
44
|
+
artifacts: result.artifacts || {},
|
|
45
|
+
metadata: {
|
|
46
|
+
executionTime,
|
|
47
|
+
sparcMode,
|
|
48
|
+
command: command.join(' '),
|
|
49
|
+
exitCode: result.exitCode,
|
|
50
|
+
quality: 0.95,
|
|
51
|
+
completeness: 0.9
|
|
52
|
+
},
|
|
53
|
+
error: result.error
|
|
54
|
+
};
|
|
55
|
+
} catch (error) {
|
|
56
|
+
this.logger.error('Failed to execute Claude Flow SPARC command', {
|
|
57
|
+
error: error instanceof Error ? error.message : String(error),
|
|
58
|
+
taskId: task.id.id
|
|
59
|
+
});
|
|
60
|
+
return {
|
|
61
|
+
output: '',
|
|
62
|
+
artifacts: {},
|
|
63
|
+
metadata: {
|
|
64
|
+
executionTime: Date.now() - startTime,
|
|
65
|
+
quality: 0,
|
|
66
|
+
completeness: 0
|
|
67
|
+
},
|
|
68
|
+
error: error instanceof Error ? error.message : String(error)
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
determineSparcMode(task, agent) {
|
|
73
|
+
// Map task types and agent types to SPARC modes
|
|
74
|
+
const modeMap = {
|
|
75
|
+
// Task type mappings
|
|
76
|
+
coding: 'code',
|
|
77
|
+
testing: 'tdd',
|
|
78
|
+
analysis: 'spec-pseudocode',
|
|
79
|
+
documentation: 'docs-writer',
|
|
80
|
+
research: 'spec-pseudocode',
|
|
81
|
+
review: 'refinement-optimization-mode',
|
|
82
|
+
deployment: 'devops',
|
|
83
|
+
optimization: 'refinement-optimization-mode',
|
|
84
|
+
integration: 'integration',
|
|
85
|
+
// Agent type overrides
|
|
86
|
+
coder: 'code',
|
|
87
|
+
tester: 'tdd',
|
|
88
|
+
analyst: 'spec-pseudocode',
|
|
89
|
+
documenter: 'docs-writer',
|
|
90
|
+
reviewer: 'refinement-optimization-mode',
|
|
91
|
+
researcher: 'spec-pseudocode',
|
|
92
|
+
coordinator: 'architect'
|
|
93
|
+
};
|
|
94
|
+
// Check for specific keywords in task description
|
|
95
|
+
const description = task.description.toLowerCase();
|
|
96
|
+
if (description.includes('architecture') || description.includes('design')) {
|
|
97
|
+
return 'architect';
|
|
98
|
+
}
|
|
99
|
+
if (description.includes('security')) {
|
|
100
|
+
return 'security-review';
|
|
101
|
+
}
|
|
102
|
+
if (description.includes('debug')) {
|
|
103
|
+
return 'debug';
|
|
104
|
+
}
|
|
105
|
+
if (description.includes('test')) {
|
|
106
|
+
return 'tdd';
|
|
107
|
+
}
|
|
108
|
+
if (description.includes('document')) {
|
|
109
|
+
return 'docs-writer';
|
|
110
|
+
}
|
|
111
|
+
if (description.includes('integrate')) {
|
|
112
|
+
return 'integration';
|
|
113
|
+
}
|
|
114
|
+
// Use agent type first, then task type
|
|
115
|
+
return modeMap[agent.type] || modeMap[task.type] || 'code';
|
|
116
|
+
}
|
|
117
|
+
buildSparcCommand(task, mode, targetDir) {
|
|
118
|
+
const command = [
|
|
119
|
+
this.claudeFlowPath,
|
|
120
|
+
'sparc',
|
|
121
|
+
'run',
|
|
122
|
+
mode,
|
|
123
|
+
`"${this.formatTaskDescription(task)}"`
|
|
124
|
+
];
|
|
125
|
+
// Add options
|
|
126
|
+
if (targetDir) {
|
|
127
|
+
command.push('--target-dir', targetDir);
|
|
128
|
+
}
|
|
129
|
+
if (this.verbose) {
|
|
130
|
+
command.push('--verbose');
|
|
131
|
+
}
|
|
132
|
+
// Add non-interactive flag
|
|
133
|
+
command.push('--non-interactive');
|
|
134
|
+
// Add auto-confirm flag
|
|
135
|
+
command.push('--yes');
|
|
136
|
+
return command;
|
|
137
|
+
}
|
|
138
|
+
formatTaskDescription(task) {
|
|
139
|
+
// Format the task description for SPARC command
|
|
140
|
+
let description = task.description;
|
|
141
|
+
// If the task has specific instructions, include them
|
|
142
|
+
if (task.instructions && task.instructions !== task.description) {
|
|
143
|
+
description = `${task.description}. ${task.instructions}`;
|
|
144
|
+
}
|
|
145
|
+
// Add context if available
|
|
146
|
+
if (task.context?.targetDir) {
|
|
147
|
+
description += ` in ${task.context.targetDir}`;
|
|
148
|
+
}
|
|
149
|
+
return description.replace(/"/g, '\\"');
|
|
150
|
+
}
|
|
151
|
+
async executeCommand(command) {
|
|
152
|
+
return new Promise((resolve, reject)=>{
|
|
153
|
+
const [cmd, ...args] = command;
|
|
154
|
+
const proc = spawn(cmd, args, {
|
|
155
|
+
shell: true,
|
|
156
|
+
env: {
|
|
157
|
+
...process.env,
|
|
158
|
+
CLAUDE_FLOW_NON_INTERACTIVE: 'true',
|
|
159
|
+
CLAUDE_FLOW_AUTO_CONFIRM: 'true'
|
|
160
|
+
}
|
|
161
|
+
});
|
|
162
|
+
let stdout = '';
|
|
163
|
+
let stderr = '';
|
|
164
|
+
const artifacts = {};
|
|
165
|
+
proc.stdout.on('data', (data)=>{
|
|
166
|
+
const chunk = data.toString();
|
|
167
|
+
stdout += chunk;
|
|
168
|
+
// Parse artifacts from output
|
|
169
|
+
const artifactMatch = chunk.match(/Created file: (.+)/g);
|
|
170
|
+
if (artifactMatch) {
|
|
171
|
+
artifactMatch.forEach((match)=>{
|
|
172
|
+
const filePath = match.replace('Created file: ', '').trim();
|
|
173
|
+
artifacts[filePath] = true;
|
|
174
|
+
});
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
proc.stderr.on('data', (data)=>{
|
|
178
|
+
stderr += data.toString();
|
|
179
|
+
});
|
|
180
|
+
proc.on('close', (code)=>{
|
|
181
|
+
clearTimeout(timeoutId); // Clear timeout when process completes
|
|
182
|
+
if (code === 0) {
|
|
183
|
+
resolve({
|
|
184
|
+
output: stdout,
|
|
185
|
+
artifacts,
|
|
186
|
+
exitCode: code,
|
|
187
|
+
error: null
|
|
188
|
+
});
|
|
189
|
+
} else {
|
|
190
|
+
resolve({
|
|
191
|
+
output: stdout,
|
|
192
|
+
artifacts,
|
|
193
|
+
exitCode: code,
|
|
194
|
+
error: stderr || `Command exited with code ${code}`
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
proc.on('error', (err)=>{
|
|
199
|
+
reject(err);
|
|
200
|
+
});
|
|
201
|
+
// Handle timeout - configurable for SPARC operations
|
|
202
|
+
const timeoutMs = this.timeoutMinutes * 60 * 1000;
|
|
203
|
+
const timeoutId = setTimeout(()=>{
|
|
204
|
+
proc.kill('SIGTERM');
|
|
205
|
+
reject(new Error('Command execution timeout'));
|
|
206
|
+
}, timeoutMs);
|
|
207
|
+
});
|
|
208
|
+
}
|
|
209
|
+
constructor(config = {}){
|
|
210
|
+
_define_property(this, "logger", void 0);
|
|
211
|
+
_define_property(this, "claudeFlowPath", void 0);
|
|
212
|
+
_define_property(this, "enableSparc", void 0);
|
|
213
|
+
_define_property(this, "verbose", void 0);
|
|
214
|
+
_define_property(this, "timeoutMinutes", void 0);
|
|
215
|
+
this.logger = config.logger || new Logger({
|
|
216
|
+
level: 'info',
|
|
217
|
+
format: 'text',
|
|
218
|
+
destination: 'console'
|
|
219
|
+
}, {
|
|
220
|
+
component: 'ClaudeFlowExecutor'
|
|
221
|
+
});
|
|
222
|
+
this.claudeFlowPath = config.claudeFlowPath || getClaudeFlowBin();
|
|
223
|
+
this.enableSparc = config.enableSparc ?? true;
|
|
224
|
+
this.verbose = config.verbose ?? false;
|
|
225
|
+
this.timeoutMinutes = config.timeoutMinutes ?? 59;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
// Export for use in swarm coordinator
|
|
229
|
+
export default ClaudeFlowExecutor;
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Consensus Coordinator
|
|
3
|
+
* Implements distributed consensus protocols for agent coordination decisions
|
|
4
|
+
*
|
|
5
|
+
* Supported Protocols:
|
|
6
|
+
* - Raft: Leader-based consensus for coordination decisions
|
|
7
|
+
* - PBFT: Byzantine fault tolerance for untrusted agents
|
|
8
|
+
* - Quorum: Simple majority voting for basic decisions
|
|
9
|
+
*
|
|
10
|
+
* Performance Target: <10ms consensus latency for 100+ agents
|
|
11
|
+
*/ function _define_property(obj, key, value) {
|
|
12
|
+
if (key in obj) {
|
|
13
|
+
Object.defineProperty(obj, key, {
|
|
14
|
+
value: value,
|
|
15
|
+
enumerable: true,
|
|
16
|
+
configurable: true,
|
|
17
|
+
writable: true
|
|
18
|
+
});
|
|
19
|
+
} else {
|
|
20
|
+
obj[key] = value;
|
|
21
|
+
}
|
|
22
|
+
return obj;
|
|
23
|
+
}
|
|
24
|
+
import { EventEmitter } from "node:events";
|
|
25
|
+
import { performance } from "perf_hooks";
|
|
26
|
+
import { Logger } from "../core/logger.js";
|
|
27
|
+
export class ConsensusCoordinator extends EventEmitter {
|
|
28
|
+
initialize() {
|
|
29
|
+
// Start background processes based on protocol
|
|
30
|
+
if (this.config.protocol === 'raft') {
|
|
31
|
+
this.startRaftProtocol();
|
|
32
|
+
}
|
|
33
|
+
this.logger.info('Consensus coordinator initialized', {
|
|
34
|
+
protocol: this.config.protocol,
|
|
35
|
+
timeout: this.config.timeout
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Register an agent in the consensus group
|
|
40
|
+
*/ registerAgent(agentId) {
|
|
41
|
+
this.agents.add(agentId);
|
|
42
|
+
this.agentStates.set(agentId, 'active');
|
|
43
|
+
// Update quorum size if not explicitly set
|
|
44
|
+
if (!this.config.quorumSize) {
|
|
45
|
+
this.config.quorumSize = this.calculateQuorumSize();
|
|
46
|
+
}
|
|
47
|
+
this.logger.debug('Agent registered for consensus', {
|
|
48
|
+
agentId,
|
|
49
|
+
totalAgents: this.agents.size,
|
|
50
|
+
quorumSize: this.config.quorumSize
|
|
51
|
+
});
|
|
52
|
+
this.emit('agent:registered', agentId);
|
|
53
|
+
}
|
|
54
|
+
/**
|
|
55
|
+
* Unregister an agent from the consensus group
|
|
56
|
+
*/ unregisterAgent(agentId) {
|
|
57
|
+
this.agents.delete(agentId);
|
|
58
|
+
this.agentStates.delete(agentId);
|
|
59
|
+
// Update quorum size
|
|
60
|
+
this.config.quorumSize = this.calculateQuorumSize();
|
|
61
|
+
this.logger.debug('Agent unregistered from consensus', {
|
|
62
|
+
agentId,
|
|
63
|
+
totalAgents: this.agents.size,
|
|
64
|
+
quorumSize: this.config.quorumSize
|
|
65
|
+
});
|
|
66
|
+
this.emit('agent:unregistered', agentId);
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Propose a decision for consensus
|
|
70
|
+
*/ async propose(proposal) {
|
|
71
|
+
const consensusStart = performance.now();
|
|
72
|
+
this.logger.info('Consensus proposal initiated', {
|
|
73
|
+
proposalId: proposal.id,
|
|
74
|
+
type: proposal.type,
|
|
75
|
+
protocol: this.config.protocol
|
|
76
|
+
});
|
|
77
|
+
try {
|
|
78
|
+
let result;
|
|
79
|
+
switch(this.config.protocol){
|
|
80
|
+
case 'raft':
|
|
81
|
+
result = await this.raftConsensus(proposal);
|
|
82
|
+
break;
|
|
83
|
+
case 'pbft':
|
|
84
|
+
result = await this.pbftConsensus(proposal);
|
|
85
|
+
break;
|
|
86
|
+
case 'quorum':
|
|
87
|
+
result = await this.quorumConsensus(proposal);
|
|
88
|
+
break;
|
|
89
|
+
case 'fast-paxos':
|
|
90
|
+
result = await this.fastPaxosConsensus(proposal);
|
|
91
|
+
break;
|
|
92
|
+
default:
|
|
93
|
+
throw new Error(`Unsupported consensus protocol: ${this.config.protocol}`);
|
|
94
|
+
}
|
|
95
|
+
// Record metrics
|
|
96
|
+
const consensusTime = performance.now() - consensusStart;
|
|
97
|
+
this.recordConsensusMetrics(result, consensusTime);
|
|
98
|
+
this.logger.info('Consensus reached', {
|
|
99
|
+
proposalId: proposal.id,
|
|
100
|
+
decision: result.decision,
|
|
101
|
+
consensusTime: `${consensusTime.toFixed(2)}ms`,
|
|
102
|
+
participationRate: `${(result.participationRate * 100).toFixed(1)}%`
|
|
103
|
+
});
|
|
104
|
+
this.emit('consensus:reached', result);
|
|
105
|
+
return result;
|
|
106
|
+
} catch (error) {
|
|
107
|
+
this.logger.error('Consensus failed', {
|
|
108
|
+
proposalId: proposal.id,
|
|
109
|
+
error: error instanceof Error ? error.message : String(error)
|
|
110
|
+
});
|
|
111
|
+
throw error;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Raft consensus implementation
|
|
116
|
+
*/ async raftConsensus(proposal) {
|
|
117
|
+
// Only leader can propose in Raft
|
|
118
|
+
if (this.raftState.role !== 'leader') {
|
|
119
|
+
if (this.raftState.leaderId) {
|
|
120
|
+
// Forward to leader
|
|
121
|
+
this.logger.debug('Forwarding proposal to leader', {
|
|
122
|
+
leaderId: this.raftState.leaderId
|
|
123
|
+
});
|
|
124
|
+
} else {
|
|
125
|
+
// No leader, trigger election
|
|
126
|
+
await this.startLeaderElection();
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
// Append to log
|
|
130
|
+
const logEntry = {
|
|
131
|
+
term: this.raftState.currentTerm,
|
|
132
|
+
command: proposal
|
|
133
|
+
};
|
|
134
|
+
this.raftState.log.push(logEntry);
|
|
135
|
+
// Replicate to followers
|
|
136
|
+
const votes = await this.replicateToFollowers(logEntry);
|
|
137
|
+
// Check if majority acknowledged
|
|
138
|
+
const quorum = Math.floor(this.agents.size / 2) + 1;
|
|
139
|
+
const approvals = votes.filter((v)=>v.decision === 'approve').length;
|
|
140
|
+
const decision = approvals >= quorum ? 'approved' : 'rejected';
|
|
141
|
+
const consensusTime = performance.now();
|
|
142
|
+
return {
|
|
143
|
+
proposalId: proposal.id,
|
|
144
|
+
decision,
|
|
145
|
+
votes,
|
|
146
|
+
consensusTime,
|
|
147
|
+
participationRate: votes.length / this.agents.size
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
/**
|
|
151
|
+
* PBFT (Practical Byzantine Fault Tolerance) consensus
|
|
152
|
+
*/ async pbftConsensus(proposal) {
|
|
153
|
+
const startTime = performance.now();
|
|
154
|
+
const deadline = Date.now() + this.config.timeout;
|
|
155
|
+
// Phase 1: Pre-prepare (leader broadcasts proposal)
|
|
156
|
+
this.logger.debug('PBFT Pre-prepare phase', {
|
|
157
|
+
proposalId: proposal.id
|
|
158
|
+
});
|
|
159
|
+
// Phase 2: Prepare (agents exchange prepare messages)
|
|
160
|
+
const prepareVotes = await this.collectVotes(proposal, 'prepare', deadline);
|
|
161
|
+
// Check if we have enough prepare votes (2f + 1 where f is max faulty)
|
|
162
|
+
const f = this.config.byzantineTolerance || 1;
|
|
163
|
+
const minVotes = 2 * f + 1;
|
|
164
|
+
if (prepareVotes.length < minVotes) {
|
|
165
|
+
return {
|
|
166
|
+
proposalId: proposal.id,
|
|
167
|
+
decision: 'timeout',
|
|
168
|
+
votes: prepareVotes,
|
|
169
|
+
consensusTime: performance.now() - startTime,
|
|
170
|
+
participationRate: prepareVotes.length / this.agents.size
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
// Phase 3: Commit (agents exchange commit messages)
|
|
174
|
+
const commitVotes = await this.collectVotes(proposal, 'commit', deadline);
|
|
175
|
+
const approvals = commitVotes.filter((v)=>v.decision === 'approve').length;
|
|
176
|
+
const decision = approvals >= minVotes ? 'approved' : 'rejected';
|
|
177
|
+
return {
|
|
178
|
+
proposalId: proposal.id,
|
|
179
|
+
decision,
|
|
180
|
+
votes: commitVotes,
|
|
181
|
+
consensusTime: performance.now() - startTime,
|
|
182
|
+
participationRate: commitVotes.length / this.agents.size
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
/**
|
|
186
|
+
* Simple quorum-based consensus
|
|
187
|
+
*/ async quorumConsensus(proposal) {
|
|
188
|
+
const startTime = performance.now();
|
|
189
|
+
const deadline = Date.now() + this.config.timeout;
|
|
190
|
+
// Broadcast proposal to all agents
|
|
191
|
+
const votes = await this.collectVotes(proposal, 'vote', deadline);
|
|
192
|
+
// Count votes
|
|
193
|
+
const approvals = votes.filter((v)=>v.decision === 'approve').length;
|
|
194
|
+
const rejections = votes.filter((v)=>v.decision === 'reject').length;
|
|
195
|
+
const quorumSize = this.config.quorumSize || Math.floor(this.agents.size / 2) + 1;
|
|
196
|
+
let decision;
|
|
197
|
+
if (approvals >= quorumSize) {
|
|
198
|
+
decision = 'approved';
|
|
199
|
+
} else if (rejections >= quorumSize) {
|
|
200
|
+
decision = 'rejected';
|
|
201
|
+
} else {
|
|
202
|
+
decision = 'timeout';
|
|
203
|
+
}
|
|
204
|
+
return {
|
|
205
|
+
proposalId: proposal.id,
|
|
206
|
+
decision,
|
|
207
|
+
votes,
|
|
208
|
+
consensusTime: performance.now() - startTime,
|
|
209
|
+
participationRate: votes.length / this.agents.size
|
|
210
|
+
};
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Fast Paxos consensus (optimized for low latency)
|
|
214
|
+
*/ async fastPaxosConsensus(proposal) {
|
|
215
|
+
const startTime = performance.now();
|
|
216
|
+
const deadline = Date.now() + this.config.timeout;
|
|
217
|
+
// Fast path: Try to reach consensus in one round
|
|
218
|
+
const votes = await this.collectVotes(proposal, 'fast-vote', deadline);
|
|
219
|
+
const quorumSize = Math.floor(this.agents.size * 0.75); // 3/4 majority for fast path
|
|
220
|
+
const approvals = votes.filter((v)=>v.decision === 'approve').length;
|
|
221
|
+
if (approvals >= quorumSize) {
|
|
222
|
+
// Fast path succeeded
|
|
223
|
+
return {
|
|
224
|
+
proposalId: proposal.id,
|
|
225
|
+
decision: 'approved',
|
|
226
|
+
votes,
|
|
227
|
+
consensusTime: performance.now() - startTime,
|
|
228
|
+
participationRate: votes.length / this.agents.size
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
// Fall back to classic Paxos (two-phase)
|
|
232
|
+
this.logger.debug('Fast path failed, falling back to classic Paxos', {
|
|
233
|
+
proposalId: proposal.id
|
|
234
|
+
});
|
|
235
|
+
// Prepare phase
|
|
236
|
+
const prepareVotes = await this.collectVotes(proposal, 'prepare', deadline);
|
|
237
|
+
// Accept phase
|
|
238
|
+
const acceptVotes = await this.collectVotes(proposal, 'accept', deadline);
|
|
239
|
+
const majoritySize = Math.floor(this.agents.size / 2) + 1;
|
|
240
|
+
const finalApprovals = acceptVotes.filter((v)=>v.decision === 'approve').length;
|
|
241
|
+
return {
|
|
242
|
+
proposalId: proposal.id,
|
|
243
|
+
decision: finalApprovals >= majoritySize ? 'approved' : 'rejected',
|
|
244
|
+
votes: acceptVotes,
|
|
245
|
+
consensusTime: performance.now() - startTime,
|
|
246
|
+
participationRate: acceptVotes.length / this.agents.size
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Collect votes from agents
|
|
251
|
+
*/ async collectVotes(proposal, phase, deadline) {
|
|
252
|
+
const votes = [];
|
|
253
|
+
const proposalData = {
|
|
254
|
+
proposal,
|
|
255
|
+
votes: new Map(),
|
|
256
|
+
deadline,
|
|
257
|
+
startTime: Date.now()
|
|
258
|
+
};
|
|
259
|
+
this.activeProposals.set(proposal.id, proposalData);
|
|
260
|
+
// In production, this would send messages to actual agents
|
|
261
|
+
// For now, simulate voting behavior
|
|
262
|
+
const activeAgents = Array.from(this.agents).filter((agentId)=>this.agentStates.get(agentId) === 'active');
|
|
263
|
+
await Promise.all(activeAgents.map(async (agentId)=>{
|
|
264
|
+
// Simulate network latency (0-5ms)
|
|
265
|
+
await new Promise((resolve)=>setTimeout(resolve, Math.random() * 5));
|
|
266
|
+
if (Date.now() > deadline) {
|
|
267
|
+
return; // Timeout
|
|
268
|
+
}
|
|
269
|
+
// Simulate voting (in production, agents would make actual decisions)
|
|
270
|
+
const vote = {
|
|
271
|
+
proposalId: proposal.id,
|
|
272
|
+
voter: agentId,
|
|
273
|
+
decision: Math.random() > 0.1 ? 'approve' : 'reject',
|
|
274
|
+
timestamp: Date.now()
|
|
275
|
+
};
|
|
276
|
+
votes.push(vote);
|
|
277
|
+
proposalData.votes.set(agentId, vote);
|
|
278
|
+
}));
|
|
279
|
+
this.activeProposals.delete(proposal.id);
|
|
280
|
+
return votes;
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Start Raft leader election
|
|
284
|
+
*/ async startLeaderElection() {
|
|
285
|
+
this.raftState.currentTerm++;
|
|
286
|
+
this.raftState.role = 'candidate';
|
|
287
|
+
this.raftState.votedFor = 'self'; // Vote for self
|
|
288
|
+
this.logger.info('Starting leader election', {
|
|
289
|
+
term: this.raftState.currentTerm
|
|
290
|
+
});
|
|
291
|
+
// Request votes from other agents
|
|
292
|
+
const votes = await this.requestVotes();
|
|
293
|
+
const majority = Math.floor(this.agents.size / 2) + 1;
|
|
294
|
+
const approvals = votes.filter((v)=>v.decision === 'approve').length + 1; // +1 for self vote
|
|
295
|
+
if (approvals >= majority) {
|
|
296
|
+
// Won election
|
|
297
|
+
this.raftState.role = 'leader';
|
|
298
|
+
this.raftState.leaderId = 'self';
|
|
299
|
+
this.logger.info('Elected as leader', {
|
|
300
|
+
term: this.raftState.currentTerm,
|
|
301
|
+
votes: approvals
|
|
302
|
+
});
|
|
303
|
+
this.emit('leader:elected', {
|
|
304
|
+
term: this.raftState.currentTerm
|
|
305
|
+
});
|
|
306
|
+
} else {
|
|
307
|
+
// Lost election
|
|
308
|
+
this.raftState.role = 'follower';
|
|
309
|
+
this.logger.debug('Leader election failed', {
|
|
310
|
+
term: this.raftState.currentTerm,
|
|
311
|
+
votes: approvals
|
|
312
|
+
});
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
/**
|
|
316
|
+
* Request votes from agents (Raft)
|
|
317
|
+
*/ async requestVotes() {
|
|
318
|
+
const votes = [];
|
|
319
|
+
// In production, send RequestVote RPCs
|
|
320
|
+
// For now, simulate responses
|
|
321
|
+
for (const agentId of this.agents){
|
|
322
|
+
const vote = {
|
|
323
|
+
proposalId: `election-${this.raftState.currentTerm}`,
|
|
324
|
+
voter: agentId,
|
|
325
|
+
decision: Math.random() > 0.3 ? 'approve' : 'reject',
|
|
326
|
+
timestamp: Date.now()
|
|
327
|
+
};
|
|
328
|
+
votes.push(vote);
|
|
329
|
+
}
|
|
330
|
+
return votes;
|
|
331
|
+
}
|
|
332
|
+
/**
|
|
333
|
+
* Replicate log entries to followers (Raft)
|
|
334
|
+
*/ async replicateToFollowers(logEntry) {
|
|
335
|
+
const votes = [];
|
|
336
|
+
// In production, send AppendEntries RPCs
|
|
337
|
+
// For now, simulate responses
|
|
338
|
+
for (const agentId of this.agents){
|
|
339
|
+
const vote = {
|
|
340
|
+
proposalId: `replication-${this.raftState.currentTerm}`,
|
|
341
|
+
voter: agentId,
|
|
342
|
+
decision: 'approve',
|
|
343
|
+
timestamp: Date.now()
|
|
344
|
+
};
|
|
345
|
+
votes.push(vote);
|
|
346
|
+
}
|
|
347
|
+
return votes;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Calculate required quorum size
|
|
351
|
+
*/ calculateQuorumSize() {
|
|
352
|
+
switch(this.config.protocol){
|
|
353
|
+
case 'pbft':
|
|
354
|
+
// PBFT requires 2f + 1 where f is max faulty
|
|
355
|
+
const f = this.config.byzantineTolerance || 1;
|
|
356
|
+
return 2 * f + 1;
|
|
357
|
+
case 'raft':
|
|
358
|
+
case 'quorum':
|
|
359
|
+
case 'fast-paxos':
|
|
360
|
+
default:
|
|
361
|
+
// Simple majority
|
|
362
|
+
return Math.floor(this.agents.size / 2) + 1;
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
/**
|
|
366
|
+
* Record consensus metrics
|
|
367
|
+
*/ recordConsensusMetrics(result, consensusTime) {
|
|
368
|
+
this.metrics.totalProposals++;
|
|
369
|
+
if (result.decision === 'approved') {
|
|
370
|
+
this.metrics.approvedProposals++;
|
|
371
|
+
} else if (result.decision === 'rejected') {
|
|
372
|
+
this.metrics.rejectedProposals++;
|
|
373
|
+
} else {
|
|
374
|
+
this.metrics.timedOutProposals++;
|
|
375
|
+
}
|
|
376
|
+
this.metrics.consensusTimes.push(consensusTime);
|
|
377
|
+
if (this.metrics.consensusTimes.length > 1000) {
|
|
378
|
+
this.metrics.consensusTimes = this.metrics.consensusTimes.slice(-1000);
|
|
379
|
+
}
|
|
380
|
+
this.metrics.avgConsensusTime = this.metrics.consensusTimes.reduce((a, b)=>a + b, 0) / this.metrics.consensusTimes.length;
|
|
381
|
+
this.metrics.avgParticipationRate = (this.metrics.avgParticipationRate * (this.metrics.totalProposals - 1) + result.participationRate) / this.metrics.totalProposals;
|
|
382
|
+
}
|
|
383
|
+
/**
|
|
384
|
+
* Get consensus metrics
|
|
385
|
+
*/ getMetrics() {
|
|
386
|
+
return {
|
|
387
|
+
...this.metrics,
|
|
388
|
+
activeAgents: Array.from(this.agentStates.values()).filter((s)=>s === 'active').length,
|
|
389
|
+
totalAgents: this.agents.size,
|
|
390
|
+
quorumSize: this.config.quorumSize,
|
|
391
|
+
protocol: this.config.protocol,
|
|
392
|
+
raftState: this.config.protocol === 'raft' ? {
|
|
393
|
+
term: this.raftState.currentTerm,
|
|
394
|
+
role: this.raftState.role,
|
|
395
|
+
leaderId: this.raftState.leaderId
|
|
396
|
+
} : undefined
|
|
397
|
+
};
|
|
398
|
+
}
|
|
399
|
+
/**
|
|
400
|
+
* Start Raft protocol background processes
|
|
401
|
+
*/ startRaftProtocol() {
|
|
402
|
+
// Heartbeat mechanism for leader
|
|
403
|
+
setInterval(()=>{
|
|
404
|
+
if (this.raftState.role === 'leader') {
|
|
405
|
+
this.sendHeartbeats();
|
|
406
|
+
}
|
|
407
|
+
}, 1000); // Send heartbeats every 1s
|
|
408
|
+
// Election timeout for followers
|
|
409
|
+
setInterval(()=>{
|
|
410
|
+
if (this.raftState.role === 'follower' && !this.raftState.leaderId) {
|
|
411
|
+
// No heartbeat from leader, start election
|
|
412
|
+
this.startLeaderElection();
|
|
413
|
+
}
|
|
414
|
+
}, 5000); // Check every 5s
|
|
415
|
+
}
|
|
416
|
+
/**
|
|
417
|
+
* Send heartbeats to followers (Raft)
|
|
418
|
+
*/ sendHeartbeats() {
|
|
419
|
+
// In production, send AppendEntries RPCs with no entries
|
|
420
|
+
this.emit('heartbeat:sent', {
|
|
421
|
+
term: this.raftState.currentTerm
|
|
422
|
+
});
|
|
423
|
+
}
|
|
424
|
+
/**
|
|
425
|
+
* Shutdown consensus coordinator
|
|
426
|
+
*/ shutdown() {
|
|
427
|
+
this.agents.clear();
|
|
428
|
+
this.agentStates.clear();
|
|
429
|
+
this.activeProposals.clear();
|
|
430
|
+
this.logger.info('Consensus coordinator shut down');
|
|
431
|
+
}
|
|
432
|
+
constructor(config = {}){
|
|
433
|
+
super(), _define_property(this, "logger", void 0), _define_property(this, "config", void 0), // Agent registry
|
|
434
|
+
_define_property(this, "agents", new Set()), _define_property(this, "agentStates", new Map()), // Raft state (for raft protocol)
|
|
435
|
+
_define_property(this, "raftState", {
|
|
436
|
+
currentTerm: 0,
|
|
437
|
+
votedFor: null,
|
|
438
|
+
role: 'follower',
|
|
439
|
+
leaderId: null,
|
|
440
|
+
log: [],
|
|
441
|
+
commitIndex: 0,
|
|
442
|
+
lastApplied: 0
|
|
443
|
+
}), // Consensus tracking
|
|
444
|
+
_define_property(this, "activeProposals", new Map()), // Performance metrics
|
|
445
|
+
_define_property(this, "metrics", {
|
|
446
|
+
totalProposals: 0,
|
|
447
|
+
approvedProposals: 0,
|
|
448
|
+
rejectedProposals: 0,
|
|
449
|
+
timedOutProposals: 0,
|
|
450
|
+
avgConsensusTime: 0,
|
|
451
|
+
consensusTimes: [],
|
|
452
|
+
avgParticipationRate: 0
|
|
453
|
+
});
|
|
454
|
+
this.config = {
|
|
455
|
+
protocol: config.protocol || 'quorum',
|
|
456
|
+
quorumSize: config.quorumSize,
|
|
457
|
+
timeout: config.timeout || 5000,
|
|
458
|
+
maxRetries: config.maxRetries || 3,
|
|
459
|
+
byzantineTolerance: config.byzantineTolerance || 1
|
|
460
|
+
};
|
|
461
|
+
const loggerConfig = process.env.CLAUDE_FLOW_ENV === 'test' ? {
|
|
462
|
+
level: 'error',
|
|
463
|
+
format: 'json',
|
|
464
|
+
destination: 'console'
|
|
465
|
+
} : {
|
|
466
|
+
level: 'info',
|
|
467
|
+
format: 'json',
|
|
468
|
+
destination: 'console'
|
|
469
|
+
};
|
|
470
|
+
this.logger = new Logger(loggerConfig, {
|
|
471
|
+
component: 'ConsensusCoordinator'
|
|
472
|
+
});
|
|
473
|
+
this.initialize();
|
|
474
|
+
}
|
|
475
|
+
}
|