agentic-qe 2.7.4 → 2.8.0
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/CHANGELOG.md +104 -0
- package/README.md +67 -2
- package/dist/cli/commands/agent/spawn.d.ts +12 -1
- package/dist/cli/commands/agent/spawn.d.ts.map +1 -1
- package/dist/cli/commands/agent/spawn.js +95 -8
- package/dist/cli/commands/agent/spawn.js.map +1 -1
- package/dist/cli/index.js +91 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/core/memory/HNSWVectorMemory.js +1 -1
- package/dist/edge/adapters/BrowserHNSWAdapter.d.ts +134 -0
- package/dist/edge/adapters/BrowserHNSWAdapter.d.ts.map +1 -0
- package/dist/edge/adapters/BrowserHNSWAdapter.js +484 -0
- package/dist/edge/adapters/BrowserHNSWAdapter.js.map +1 -0
- package/dist/edge/adapters/IndexedDBStorage.d.ts +114 -0
- package/dist/edge/adapters/IndexedDBStorage.d.ts.map +1 -0
- package/dist/edge/adapters/IndexedDBStorage.js +478 -0
- package/dist/edge/adapters/IndexedDBStorage.js.map +1 -0
- package/dist/edge/adapters/index.d.ts +12 -0
- package/dist/edge/adapters/index.d.ts.map +1 -0
- package/dist/edge/adapters/index.js +22 -0
- package/dist/edge/adapters/index.js.map +1 -0
- package/dist/edge/browser/BrowserAgent.d.ts +241 -0
- package/dist/edge/browser/BrowserAgent.d.ts.map +1 -0
- package/dist/edge/browser/BrowserAgent.js +743 -0
- package/dist/edge/browser/BrowserAgent.js.map +1 -0
- package/dist/edge/index.d.ts +34 -0
- package/dist/edge/index.d.ts.map +1 -0
- package/dist/edge/index.js +114 -0
- package/dist/edge/index.js.map +1 -0
- package/dist/edge/p2p/coordination/CoordinationManager.d.ts +181 -0
- package/dist/edge/p2p/coordination/CoordinationManager.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/CoordinationManager.js +851 -0
- package/dist/edge/p2p/coordination/CoordinationManager.js.map +1 -0
- package/dist/edge/p2p/coordination/HealthMonitor.d.ts +143 -0
- package/dist/edge/p2p/coordination/HealthMonitor.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/HealthMonitor.js +432 -0
- package/dist/edge/p2p/coordination/HealthMonitor.js.map +1 -0
- package/dist/edge/p2p/coordination/SyncOrchestrator.d.ts +146 -0
- package/dist/edge/p2p/coordination/SyncOrchestrator.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/SyncOrchestrator.js +783 -0
- package/dist/edge/p2p/coordination/SyncOrchestrator.js.map +1 -0
- package/dist/edge/p2p/coordination/index.d.ts +70 -0
- package/dist/edge/p2p/coordination/index.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/index.js +107 -0
- package/dist/edge/p2p/coordination/index.js.map +1 -0
- package/dist/edge/p2p/coordination/types.d.ts +572 -0
- package/dist/edge/p2p/coordination/types.d.ts.map +1 -0
- package/dist/edge/p2p/coordination/types.js +366 -0
- package/dist/edge/p2p/coordination/types.js.map +1 -0
- package/dist/edge/p2p/crdt/CRDTStore.d.ts +324 -0
- package/dist/edge/p2p/crdt/CRDTStore.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/CRDTStore.js +839 -0
- package/dist/edge/p2p/crdt/CRDTStore.js.map +1 -0
- package/dist/edge/p2p/crdt/GCounter.d.ts +173 -0
- package/dist/edge/p2p/crdt/GCounter.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/GCounter.js +394 -0
- package/dist/edge/p2p/crdt/GCounter.js.map +1 -0
- package/dist/edge/p2p/crdt/LWWRegister.d.ts +200 -0
- package/dist/edge/p2p/crdt/LWWRegister.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/LWWRegister.js +456 -0
- package/dist/edge/p2p/crdt/LWWRegister.js.map +1 -0
- package/dist/edge/p2p/crdt/ORSet.d.ts +232 -0
- package/dist/edge/p2p/crdt/ORSet.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/ORSet.js +723 -0
- package/dist/edge/p2p/crdt/ORSet.js.map +1 -0
- package/dist/edge/p2p/crdt/PatternCRDT.d.ts +366 -0
- package/dist/edge/p2p/crdt/PatternCRDT.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/PatternCRDT.js +838 -0
- package/dist/edge/p2p/crdt/PatternCRDT.js.map +1 -0
- package/dist/edge/p2p/crdt/VectorClock.d.ts +274 -0
- package/dist/edge/p2p/crdt/VectorClock.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/VectorClock.js +499 -0
- package/dist/edge/p2p/crdt/VectorClock.js.map +1 -0
- package/dist/edge/p2p/crdt/index.d.ts +87 -0
- package/dist/edge/p2p/crdt/index.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/index.js +120 -0
- package/dist/edge/p2p/crdt/index.js.map +1 -0
- package/dist/edge/p2p/crdt/types.d.ts +667 -0
- package/dist/edge/p2p/crdt/types.d.ts.map +1 -0
- package/dist/edge/p2p/crdt/types.js +208 -0
- package/dist/edge/p2p/crdt/types.js.map +1 -0
- package/dist/edge/p2p/crypto/Identity.d.ts +139 -0
- package/dist/edge/p2p/crypto/Identity.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/Identity.js +449 -0
- package/dist/edge/p2p/crypto/Identity.js.map +1 -0
- package/dist/edge/p2p/crypto/KeyManager.d.ts +196 -0
- package/dist/edge/p2p/crypto/KeyManager.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/KeyManager.js +576 -0
- package/dist/edge/p2p/crypto/KeyManager.js.map +1 -0
- package/dist/edge/p2p/crypto/Signer.d.ts +164 -0
- package/dist/edge/p2p/crypto/Signer.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/Signer.js +357 -0
- package/dist/edge/p2p/crypto/Signer.js.map +1 -0
- package/dist/edge/p2p/crypto/index.d.ts +90 -0
- package/dist/edge/p2p/crypto/index.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/index.js +158 -0
- package/dist/edge/p2p/crypto/index.js.map +1 -0
- package/dist/edge/p2p/crypto/types.d.ts +217 -0
- package/dist/edge/p2p/crypto/types.d.ts.map +1 -0
- package/dist/edge/p2p/crypto/types.js +42 -0
- package/dist/edge/p2p/crypto/types.js.map +1 -0
- package/dist/edge/p2p/federated/FederatedCoordinator.d.ts +270 -0
- package/dist/edge/p2p/federated/FederatedCoordinator.d.ts.map +1 -0
- package/dist/edge/p2p/federated/FederatedCoordinator.js +824 -0
- package/dist/edge/p2p/federated/FederatedCoordinator.js.map +1 -0
- package/dist/edge/p2p/federated/FederatedRound.d.ts +295 -0
- package/dist/edge/p2p/federated/FederatedRound.d.ts.map +1 -0
- package/dist/edge/p2p/federated/FederatedRound.js +819 -0
- package/dist/edge/p2p/federated/FederatedRound.js.map +1 -0
- package/dist/edge/p2p/federated/GradientAggregator.d.ts +226 -0
- package/dist/edge/p2p/federated/GradientAggregator.d.ts.map +1 -0
- package/dist/edge/p2p/federated/GradientAggregator.js +826 -0
- package/dist/edge/p2p/federated/GradientAggregator.js.map +1 -0
- package/dist/edge/p2p/federated/ModelManager.d.ts +248 -0
- package/dist/edge/p2p/federated/ModelManager.d.ts.map +1 -0
- package/dist/edge/p2p/federated/ModelManager.js +724 -0
- package/dist/edge/p2p/federated/ModelManager.js.map +1 -0
- package/dist/edge/p2p/federated/index.d.ts +65 -0
- package/dist/edge/p2p/federated/index.d.ts.map +1 -0
- package/dist/edge/p2p/federated/index.js +110 -0
- package/dist/edge/p2p/federated/index.js.map +1 -0
- package/dist/edge/p2p/federated/types.d.ts +905 -0
- package/dist/edge/p2p/federated/types.d.ts.map +1 -0
- package/dist/edge/p2p/federated/types.js +339 -0
- package/dist/edge/p2p/federated/types.js.map +1 -0
- package/dist/edge/p2p/index.d.ts +156 -0
- package/dist/edge/p2p/index.d.ts.map +1 -0
- package/dist/edge/p2p/index.js +242 -0
- package/dist/edge/p2p/index.js.map +1 -0
- package/dist/edge/p2p/nat/ConnectivityTester.d.ts +128 -0
- package/dist/edge/p2p/nat/ConnectivityTester.d.ts.map +1 -0
- package/dist/edge/p2p/nat/ConnectivityTester.js +560 -0
- package/dist/edge/p2p/nat/ConnectivityTester.js.map +1 -0
- package/dist/edge/p2p/nat/HolePuncher.d.ts +159 -0
- package/dist/edge/p2p/nat/HolePuncher.d.ts.map +1 -0
- package/dist/edge/p2p/nat/HolePuncher.js +569 -0
- package/dist/edge/p2p/nat/HolePuncher.js.map +1 -0
- package/dist/edge/p2p/nat/NATDetector.d.ts +109 -0
- package/dist/edge/p2p/nat/NATDetector.d.ts.map +1 -0
- package/dist/edge/p2p/nat/NATDetector.js +472 -0
- package/dist/edge/p2p/nat/NATDetector.js.map +1 -0
- package/dist/edge/p2p/nat/TURNManager.d.ts +158 -0
- package/dist/edge/p2p/nat/TURNManager.d.ts.map +1 -0
- package/dist/edge/p2p/nat/TURNManager.js +547 -0
- package/dist/edge/p2p/nat/TURNManager.js.map +1 -0
- package/dist/edge/p2p/nat/index.d.ts +74 -0
- package/dist/edge/p2p/nat/index.d.ts.map +1 -0
- package/dist/edge/p2p/nat/index.js +104 -0
- package/dist/edge/p2p/nat/index.js.map +1 -0
- package/dist/edge/p2p/nat/types.d.ts +583 -0
- package/dist/edge/p2p/nat/types.d.ts.map +1 -0
- package/dist/edge/p2p/nat/types.js +267 -0
- package/dist/edge/p2p/nat/types.js.map +1 -0
- package/dist/edge/p2p/protocol/AgentChannel.d.ts +333 -0
- package/dist/edge/p2p/protocol/AgentChannel.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/AgentChannel.js +914 -0
- package/dist/edge/p2p/protocol/AgentChannel.js.map +1 -0
- package/dist/edge/p2p/protocol/MessageEncoder.d.ts +147 -0
- package/dist/edge/p2p/protocol/MessageEncoder.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/MessageEncoder.js +738 -0
- package/dist/edge/p2p/protocol/MessageEncoder.js.map +1 -0
- package/dist/edge/p2p/protocol/MessageRouter.d.ts +266 -0
- package/dist/edge/p2p/protocol/MessageRouter.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/MessageRouter.js +808 -0
- package/dist/edge/p2p/protocol/MessageRouter.js.map +1 -0
- package/dist/edge/p2p/protocol/ProtocolHandler.d.ts +309 -0
- package/dist/edge/p2p/protocol/ProtocolHandler.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/ProtocolHandler.js +930 -0
- package/dist/edge/p2p/protocol/ProtocolHandler.js.map +1 -0
- package/dist/edge/p2p/protocol/index.d.ts +114 -0
- package/dist/edge/p2p/protocol/index.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/index.js +206 -0
- package/dist/edge/p2p/protocol/index.js.map +1 -0
- package/dist/edge/p2p/protocol/types.d.ts +737 -0
- package/dist/edge/p2p/protocol/types.d.ts.map +1 -0
- package/dist/edge/p2p/protocol/types.js +490 -0
- package/dist/edge/p2p/protocol/types.js.map +1 -0
- package/dist/edge/p2p/sharing/PatternBroadcaster.d.ts +284 -0
- package/dist/edge/p2p/sharing/PatternBroadcaster.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/PatternBroadcaster.js +644 -0
- package/dist/edge/p2p/sharing/PatternBroadcaster.js.map +1 -0
- package/dist/edge/p2p/sharing/PatternIndex.d.ts +168 -0
- package/dist/edge/p2p/sharing/PatternIndex.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/PatternIndex.js +781 -0
- package/dist/edge/p2p/sharing/PatternIndex.js.map +1 -0
- package/dist/edge/p2p/sharing/PatternSerializer.d.ts +163 -0
- package/dist/edge/p2p/sharing/PatternSerializer.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/PatternSerializer.js +696 -0
- package/dist/edge/p2p/sharing/PatternSerializer.js.map +1 -0
- package/dist/edge/p2p/sharing/PatternSyncManager.d.ts +242 -0
- package/dist/edge/p2p/sharing/PatternSyncManager.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/PatternSyncManager.js +859 -0
- package/dist/edge/p2p/sharing/PatternSyncManager.js.map +1 -0
- package/dist/edge/p2p/sharing/index.d.ts +90 -0
- package/dist/edge/p2p/sharing/index.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/index.js +152 -0
- package/dist/edge/p2p/sharing/index.js.map +1 -0
- package/dist/edge/p2p/sharing/types.d.ts +796 -0
- package/dist/edge/p2p/sharing/types.d.ts.map +1 -0
- package/dist/edge/p2p/sharing/types.js +264 -0
- package/dist/edge/p2p/sharing/types.js.map +1 -0
- package/dist/edge/p2p/webrtc/ConnectionPool.d.ts +218 -0
- package/dist/edge/p2p/webrtc/ConnectionPool.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/ConnectionPool.js +562 -0
- package/dist/edge/p2p/webrtc/ConnectionPool.js.map +1 -0
- package/dist/edge/p2p/webrtc/ICEManager.d.ts +171 -0
- package/dist/edge/p2p/webrtc/ICEManager.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/ICEManager.js +490 -0
- package/dist/edge/p2p/webrtc/ICEManager.js.map +1 -0
- package/dist/edge/p2p/webrtc/PeerConnectionManager.d.ts +159 -0
- package/dist/edge/p2p/webrtc/PeerConnectionManager.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/PeerConnectionManager.js +735 -0
- package/dist/edge/p2p/webrtc/PeerConnectionManager.js.map +1 -0
- package/dist/edge/p2p/webrtc/SignalingClient.d.ts +191 -0
- package/dist/edge/p2p/webrtc/SignalingClient.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/SignalingClient.js +608 -0
- package/dist/edge/p2p/webrtc/SignalingClient.js.map +1 -0
- package/dist/edge/p2p/webrtc/index.d.ts +158 -0
- package/dist/edge/p2p/webrtc/index.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/index.js +164 -0
- package/dist/edge/p2p/webrtc/index.js.map +1 -0
- package/dist/edge/p2p/webrtc/types.d.ts +665 -0
- package/dist/edge/p2p/webrtc/types.d.ts.map +1 -0
- package/dist/edge/p2p/webrtc/types.js +245 -0
- package/dist/edge/p2p/webrtc/types.js.map +1 -0
- package/dist/edge/server/AgentSpawnAPI.d.ts +98 -0
- package/dist/edge/server/AgentSpawnAPI.d.ts.map +1 -0
- package/dist/edge/server/AgentSpawnAPI.js +264 -0
- package/dist/edge/server/AgentSpawnAPI.js.map +1 -0
- package/dist/edge/server/SignalingServer.d.ts +71 -0
- package/dist/edge/server/SignalingServer.d.ts.map +1 -0
- package/dist/edge/server/SignalingServer.js +429 -0
- package/dist/edge/server/SignalingServer.js.map +1 -0
- package/dist/edge/server/index.d.ts +64 -0
- package/dist/edge/server/index.d.ts.map +1 -0
- package/dist/edge/server/index.js +318 -0
- package/dist/edge/server/index.js.map +1 -0
- package/dist/edge/types/browser-agent.types.d.ts +455 -0
- package/dist/edge/types/browser-agent.types.d.ts.map +1 -0
- package/dist/edge/types/browser-agent.types.js +116 -0
- package/dist/edge/types/browser-agent.types.js.map +1 -0
- package/dist/edge/types/index.d.ts +11 -0
- package/dist/edge/types/index.d.ts.map +1 -0
- package/dist/edge/types/index.js +17 -0
- package/dist/edge/types/index.js.map +1 -0
- package/dist/edge/types/storage.types.d.ts +207 -0
- package/dist/edge/types/storage.types.d.ts.map +1 -0
- package/dist/edge/types/storage.types.js +47 -0
- package/dist/edge/types/storage.types.js.map +1 -0
- package/dist/edge/wasm/shims.d.ts +224 -0
- package/dist/edge/wasm/shims.d.ts.map +1 -0
- package/dist/edge/wasm/shims.js +667 -0
- package/dist/edge/wasm/shims.js.map +1 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.d.ts +33 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.d.ts.map +1 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.js +305 -0
- package/dist/mcp/handlers/NewDomainToolsHandler.js.map +1 -0
- package/dist/mcp/handlers/filtered/index.d.ts +15 -19
- package/dist/mcp/handlers/filtered/index.d.ts.map +1 -1
- package/dist/mcp/handlers/filtered/index.js +16 -27
- package/dist/mcp/handlers/filtered/index.js.map +1 -1
- package/dist/mcp/handlers/integration/index.d.ts +5 -4
- package/dist/mcp/handlers/integration/index.d.ts.map +1 -1
- package/dist/mcp/handlers/integration/index.js +7 -7
- package/dist/mcp/handlers/integration/index.js.map +1 -1
- package/dist/mcp/server-instructions.d.ts +1 -1
- package/dist/mcp/server-instructions.js +1 -1
- package/dist/mcp/server.d.ts.map +1 -1
- package/dist/mcp/server.js +14 -0
- package/dist/mcp/server.js.map +1 -1
- package/dist/mcp/tools.d.ts +8 -0
- package/dist/mcp/tools.d.ts.map +1 -1
- package/dist/mcp/tools.js +412 -1
- package/dist/mcp/tools.js.map +1 -1
- package/dist/planning/GOAPPlanner.d.ts +1 -0
- package/dist/planning/GOAPPlanner.d.ts.map +1 -1
- package/dist/planning/GOAPPlanner.js +12 -0
- package/dist/planning/GOAPPlanner.js.map +1 -1
- package/package.json +29 -8
- package/dist/alerting/AlertManager.d.ts +0 -120
- package/dist/alerting/AlertManager.d.ts.map +0 -1
- package/dist/alerting/AlertManager.js +0 -345
- package/dist/alerting/AlertManager.js.map +0 -1
- package/dist/alerting/FeedbackRouter.d.ts +0 -98
- package/dist/alerting/FeedbackRouter.d.ts.map +0 -1
- package/dist/alerting/FeedbackRouter.js +0 -331
- package/dist/alerting/FeedbackRouter.js.map +0 -1
- package/dist/alerting/StrategyApplicator.d.ts +0 -120
- package/dist/alerting/StrategyApplicator.d.ts.map +0 -1
- package/dist/alerting/StrategyApplicator.js +0 -299
- package/dist/alerting/StrategyApplicator.js.map +0 -1
- package/dist/alerting/index.d.ts +0 -68
- package/dist/alerting/index.d.ts.map +0 -1
- package/dist/alerting/index.js +0 -112
- package/dist/alerting/index.js.map +0 -1
- package/dist/alerting/types.d.ts +0 -118
- package/dist/alerting/types.d.ts.map +0 -1
- package/dist/alerting/types.js +0 -11
- package/dist/alerting/types.js.map +0 -1
- package/dist/cli/commands/fleet/backup.d.ts +0 -49
- package/dist/cli/commands/fleet/backup.d.ts.map +0 -1
- package/dist/cli/commands/fleet/backup.js +0 -88
- package/dist/cli/commands/fleet/backup.js.map +0 -1
- package/dist/cli/commands/fleet/health.d.ts +0 -154
- package/dist/cli/commands/fleet/health.d.ts.map +0 -1
- package/dist/cli/commands/fleet/health.js +0 -483
- package/dist/cli/commands/fleet/health.js.map +0 -1
- package/dist/cli/commands/fleet/init.d.ts +0 -11
- package/dist/cli/commands/fleet/init.d.ts.map +0 -1
- package/dist/cli/commands/fleet/init.js +0 -91
- package/dist/cli/commands/fleet/init.js.map +0 -1
- package/dist/cli/commands/fleet/logs.d.ts +0 -21
- package/dist/cli/commands/fleet/logs.d.ts.map +0 -1
- package/dist/cli/commands/fleet/logs.js +0 -267
- package/dist/cli/commands/fleet/logs.js.map +0 -1
- package/dist/cli/commands/fleet/metrics.d.ts +0 -27
- package/dist/cli/commands/fleet/metrics.d.ts.map +0 -1
- package/dist/cli/commands/fleet/metrics.js +0 -369
- package/dist/cli/commands/fleet/metrics.js.map +0 -1
- package/dist/cli/commands/fleet/monitor.d.ts +0 -18
- package/dist/cli/commands/fleet/monitor.d.ts.map +0 -1
- package/dist/cli/commands/fleet/monitor.js +0 -237
- package/dist/cli/commands/fleet/monitor.js.map +0 -1
- package/dist/cli/commands/fleet/optimize.d.ts +0 -42
- package/dist/cli/commands/fleet/optimize.d.ts.map +0 -1
- package/dist/cli/commands/fleet/optimize.js +0 -135
- package/dist/cli/commands/fleet/optimize.js.map +0 -1
- package/dist/cli/commands/fleet/recover.d.ts +0 -22
- package/dist/cli/commands/fleet/recover.d.ts.map +0 -1
- package/dist/cli/commands/fleet/recover.js +0 -99
- package/dist/cli/commands/fleet/recover.js.map +0 -1
- package/dist/cli/commands/fleet/restart.d.ts +0 -18
- package/dist/cli/commands/fleet/restart.d.ts.map +0 -1
- package/dist/cli/commands/fleet/restart.js +0 -290
- package/dist/cli/commands/fleet/restart.js.map +0 -1
- package/dist/cli/commands/fleet/scale.d.ts +0 -9
- package/dist/cli/commands/fleet/scale.d.ts.map +0 -1
- package/dist/cli/commands/fleet/scale.js +0 -77
- package/dist/cli/commands/fleet/scale.js.map +0 -1
- package/dist/cli/commands/fleet/shutdown.d.ts +0 -19
- package/dist/cli/commands/fleet/shutdown.d.ts.map +0 -1
- package/dist/cli/commands/fleet/shutdown.js +0 -307
- package/dist/cli/commands/fleet/shutdown.js.map +0 -1
- package/dist/cli/commands/fleet/status.d.ts +0 -10
- package/dist/cli/commands/fleet/status.d.ts.map +0 -1
- package/dist/cli/commands/fleet/status.js +0 -97
- package/dist/cli/commands/fleet/status.js.map +0 -1
- package/dist/cli/commands/fleet/topology.d.ts +0 -23
- package/dist/cli/commands/fleet/topology.d.ts.map +0 -1
- package/dist/cli/commands/fleet/topology.js +0 -376
- package/dist/cli/commands/fleet/topology.js.map +0 -1
- package/dist/cli/commands/monitor/alerts.d.ts +0 -45
- package/dist/cli/commands/monitor/alerts.d.ts.map +0 -1
- package/dist/cli/commands/monitor/alerts.js +0 -168
- package/dist/cli/commands/monitor/alerts.js.map +0 -1
- package/dist/cli/commands/monitor/analyze.d.ts +0 -49
- package/dist/cli/commands/monitor/analyze.d.ts.map +0 -1
- package/dist/cli/commands/monitor/analyze.js +0 -209
- package/dist/cli/commands/monitor/analyze.js.map +0 -1
- package/dist/cli/commands/monitor/compare.d.ts +0 -38
- package/dist/cli/commands/monitor/compare.d.ts.map +0 -1
- package/dist/cli/commands/monitor/compare.js +0 -177
- package/dist/cli/commands/monitor/compare.js.map +0 -1
- package/dist/cli/commands/monitor/dashboard.d.ts +0 -34
- package/dist/cli/commands/monitor/dashboard.d.ts.map +0 -1
- package/dist/cli/commands/monitor/dashboard.js +0 -157
- package/dist/cli/commands/monitor/dashboard.js.map +0 -1
- package/dist/cli/commands/monitor/export.d.ts +0 -36
- package/dist/cli/commands/monitor/export.d.ts.map +0 -1
- package/dist/cli/commands/monitor/export.js +0 -157
- package/dist/cli/commands/monitor/export.js.map +0 -1
- package/dist/cli/commands/monitor/index.d.ts +0 -11
- package/dist/cli/commands/monitor/index.d.ts.map +0 -1
- package/dist/cli/commands/monitor/index.js +0 -14
- package/dist/cli/commands/monitor/index.js.map +0 -1
- package/dist/cli/commands/quality/baseline.d.ts +0 -27
- package/dist/cli/commands/quality/baseline.d.ts.map +0 -1
- package/dist/cli/commands/quality/baseline.js +0 -124
- package/dist/cli/commands/quality/baseline.js.map +0 -1
- package/dist/cli/commands/quality/compare.d.ts +0 -36
- package/dist/cli/commands/quality/compare.d.ts.map +0 -1
- package/dist/cli/commands/quality/compare.js +0 -136
- package/dist/cli/commands/quality/compare.js.map +0 -1
- package/dist/cli/commands/quality/decision.d.ts +0 -81
- package/dist/cli/commands/quality/decision.d.ts.map +0 -1
- package/dist/cli/commands/quality/decision.js +0 -319
- package/dist/cli/commands/quality/decision.js.map +0 -1
- package/dist/cli/commands/quality/gate.d.ts +0 -47
- package/dist/cli/commands/quality/gate.d.ts.map +0 -1
- package/dist/cli/commands/quality/gate.js +0 -205
- package/dist/cli/commands/quality/gate.js.map +0 -1
- package/dist/cli/commands/quality/index.d.ts +0 -17
- package/dist/cli/commands/quality/index.d.ts.map +0 -1
- package/dist/cli/commands/quality/index.js +0 -41
- package/dist/cli/commands/quality/index.js.map +0 -1
- package/dist/cli/commands/quality/policy.d.ts +0 -57
- package/dist/cli/commands/quality/policy.d.ts.map +0 -1
- package/dist/cli/commands/quality/policy.js +0 -359
- package/dist/cli/commands/quality/policy.js.map +0 -1
- package/dist/cli/commands/quality/risk.d.ts +0 -41
- package/dist/cli/commands/quality/risk.d.ts.map +0 -1
- package/dist/cli/commands/quality/risk.js +0 -255
- package/dist/cli/commands/quality/risk.js.map +0 -1
- package/dist/cli/commands/quality/trends.d.ts +0 -40
- package/dist/cli/commands/quality/trends.d.ts.map +0 -1
- package/dist/cli/commands/quality/trends.js +0 -122
- package/dist/cli/commands/quality/trends.js.map +0 -1
- package/dist/cli/commands/quality/validate.d.ts +0 -44
- package/dist/cli/commands/quality/validate.d.ts.map +0 -1
- package/dist/cli/commands/quality/validate.js +0 -234
- package/dist/cli/commands/quality/validate.js.map +0 -1
- package/dist/cli/commands/test/analyze-failures.d.ts +0 -39
- package/dist/cli/commands/test/analyze-failures.d.ts.map +0 -1
- package/dist/cli/commands/test/analyze-failures.js +0 -113
- package/dist/cli/commands/test/analyze-failures.js.map +0 -1
- package/dist/cli/commands/test/clean.d.ts +0 -3
- package/dist/cli/commands/test/clean.d.ts.map +0 -1
- package/dist/cli/commands/test/clean.js +0 -148
- package/dist/cli/commands/test/clean.js.map +0 -1
- package/dist/cli/commands/test/debug.d.ts +0 -3
- package/dist/cli/commands/test/debug.d.ts.map +0 -1
- package/dist/cli/commands/test/debug.js +0 -167
- package/dist/cli/commands/test/debug.js.map +0 -1
- package/dist/cli/commands/test/diff.d.ts +0 -3
- package/dist/cli/commands/test/diff.d.ts.map +0 -1
- package/dist/cli/commands/test/diff.js +0 -195
- package/dist/cli/commands/test/diff.js.map +0 -1
- package/dist/cli/commands/test/flakiness.d.ts +0 -32
- package/dist/cli/commands/test/flakiness.d.ts.map +0 -1
- package/dist/cli/commands/test/flakiness.js +0 -121
- package/dist/cli/commands/test/flakiness.js.map +0 -1
- package/dist/cli/commands/test/index.d.ts +0 -17
- package/dist/cli/commands/test/index.d.ts.map +0 -1
- package/dist/cli/commands/test/index.js +0 -45
- package/dist/cli/commands/test/index.js.map +0 -1
- package/dist/cli/commands/test/mutate.d.ts +0 -29
- package/dist/cli/commands/test/mutate.d.ts.map +0 -1
- package/dist/cli/commands/test/mutate.js +0 -163
- package/dist/cli/commands/test/mutate.js.map +0 -1
- package/dist/cli/commands/test/parallel.d.ts +0 -3
- package/dist/cli/commands/test/parallel.d.ts.map +0 -1
- package/dist/cli/commands/test/parallel.js +0 -117
- package/dist/cli/commands/test/parallel.js.map +0 -1
- package/dist/cli/commands/test/profile.d.ts +0 -3
- package/dist/cli/commands/test/profile.d.ts.map +0 -1
- package/dist/cli/commands/test/profile.js +0 -156
- package/dist/cli/commands/test/profile.js.map +0 -1
- package/dist/cli/commands/test/queue.d.ts +0 -3
- package/dist/cli/commands/test/queue.d.ts.map +0 -1
- package/dist/cli/commands/test/queue.js +0 -140
- package/dist/cli/commands/test/queue.js.map +0 -1
- package/dist/cli/commands/test/retry.d.ts +0 -3
- package/dist/cli/commands/test/retry.d.ts.map +0 -1
- package/dist/cli/commands/test/retry.js +0 -105
- package/dist/cli/commands/test/retry.js.map +0 -1
- package/dist/cli/commands/test/snapshot.d.ts +0 -3
- package/dist/cli/commands/test/snapshot.d.ts.map +0 -1
- package/dist/cli/commands/test/snapshot.js +0 -176
- package/dist/cli/commands/test/snapshot.js.map +0 -1
- package/dist/cli/commands/test/trace.d.ts +0 -3
- package/dist/cli/commands/test/trace.d.ts.map +0 -1
- package/dist/cli/commands/test/trace.js +0 -137
- package/dist/cli/commands/test/trace.js.map +0 -1
- package/dist/cli/commands/test/watch.d.ts +0 -3
- package/dist/cli/commands/test/watch.d.ts.map +0 -1
- package/dist/cli/commands/test/watch.js +0 -130
- package/dist/cli/commands/test/watch.js.map +0 -1
- package/dist/cli/index-spec.d.ts +0 -3
- package/dist/cli/index-spec.d.ts.map +0 -1
- package/dist/cli/index-spec.js +0 -154
- package/dist/cli/index-spec.js.map +0 -1
- package/dist/cli/index-working.d.ts +0 -7
- package/dist/cli/index-working.d.ts.map +0 -1
- package/dist/cli/index-working.js +0 -617
- package/dist/cli/index-working.js.map +0 -1
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.d.ts +0 -83
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.d.ts.map +0 -1
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.js +0 -130
- package/dist/mcp/handlers/filtered/coverage-analyzer-filtered.js.map +0 -1
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.d.ts +0 -58
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.d.ts.map +0 -1
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.js +0 -84
- package/dist/mcp/handlers/filtered/flaky-detector-filtered.js.map +0 -1
- package/dist/mcp/handlers/filtered/security-scanner-filtered.d.ts +0 -54
- package/dist/mcp/handlers/filtered/security-scanner-filtered.d.ts.map +0 -1
- package/dist/mcp/handlers/filtered/security-scanner-filtered.js +0 -73
- package/dist/mcp/handlers/filtered/security-scanner-filtered.js.map +0 -1
- package/dist/mcp/handlers/integration/contract-validate.d.ts +0 -10
- package/dist/mcp/handlers/integration/contract-validate.d.ts.map +0 -1
- package/dist/mcp/handlers/integration/contract-validate.js +0 -348
- package/dist/mcp/handlers/integration/contract-validate.js.map +0 -1
- package/dist/reporting/ResultAggregator.d.ts +0 -107
- package/dist/reporting/ResultAggregator.d.ts.map +0 -1
- package/dist/reporting/ResultAggregator.js +0 -435
- package/dist/reporting/ResultAggregator.js.map +0 -1
- package/dist/reporting/index.d.ts +0 -48
- package/dist/reporting/index.d.ts.map +0 -1
- package/dist/reporting/index.js +0 -154
- package/dist/reporting/index.js.map +0 -1
- package/dist/reporting/reporters/ControlLoopReporter.d.ts +0 -128
- package/dist/reporting/reporters/ControlLoopReporter.d.ts.map +0 -1
- package/dist/reporting/reporters/ControlLoopReporter.js +0 -417
- package/dist/reporting/reporters/ControlLoopReporter.js.map +0 -1
- package/dist/reporting/reporters/HumanReadableReporter.d.ts +0 -140
- package/dist/reporting/reporters/HumanReadableReporter.d.ts.map +0 -1
- package/dist/reporting/reporters/HumanReadableReporter.js +0 -524
- package/dist/reporting/reporters/HumanReadableReporter.js.map +0 -1
- package/dist/reporting/reporters/JSONReporter.d.ts +0 -251
- package/dist/reporting/reporters/JSONReporter.d.ts.map +0 -1
- package/dist/reporting/reporters/JSONReporter.js +0 -325
- package/dist/reporting/reporters/JSONReporter.js.map +0 -1
- package/dist/reporting/reporters/index.d.ts +0 -14
- package/dist/reporting/reporters/index.d.ts.map +0 -1
- package/dist/reporting/reporters/index.js +0 -19
- package/dist/reporting/reporters/index.js.map +0 -1
- package/dist/reporting/types.d.ts +0 -427
- package/dist/reporting/types.d.ts.map +0 -1
- package/dist/reporting/types.js +0 -12
- package/dist/reporting/types.js.map +0 -1
|
@@ -0,0 +1,851 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Coordination Manager for Two-Machine Coordination
|
|
4
|
+
*
|
|
5
|
+
* Manages coordination between two or more peers in the P2P network.
|
|
6
|
+
* Handles connection establishment, authentication, pattern synchronization,
|
|
7
|
+
* and connection health monitoring.
|
|
8
|
+
*
|
|
9
|
+
* @module edge/p2p/coordination/CoordinationManager
|
|
10
|
+
* @version 1.0.0
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.CoordinationManager = void 0;
|
|
14
|
+
exports.createCoordinationManager = createCoordinationManager;
|
|
15
|
+
const types_1 = require("./types");
|
|
16
|
+
const HealthMonitor_1 = require("./HealthMonitor");
|
|
17
|
+
const SyncOrchestrator_1 = require("./SyncOrchestrator");
|
|
18
|
+
// ============================================
|
|
19
|
+
// Coordination Manager Class
|
|
20
|
+
// ============================================
|
|
21
|
+
/**
|
|
22
|
+
* CoordinationManager - Manages two-machine coordination
|
|
23
|
+
*
|
|
24
|
+
* @example
|
|
25
|
+
* ```typescript
|
|
26
|
+
* const manager = new CoordinationManager({
|
|
27
|
+
* localIdentity: myIdentity,
|
|
28
|
+
* localKeyPair: myKeyPair,
|
|
29
|
+
* autoReconnect: true,
|
|
30
|
+
* });
|
|
31
|
+
*
|
|
32
|
+
* // Set up message transport
|
|
33
|
+
* manager.setMessageSender(async (peerId, message) => {
|
|
34
|
+
* await dataChannel.send(peerId, JSON.stringify(message));
|
|
35
|
+
* });
|
|
36
|
+
*
|
|
37
|
+
* // Connect to peer
|
|
38
|
+
* await manager.connect('peer-123');
|
|
39
|
+
*
|
|
40
|
+
* // Start synchronization
|
|
41
|
+
* await manager.syncPatterns('peer-123');
|
|
42
|
+
*
|
|
43
|
+
* // Listen for events
|
|
44
|
+
* manager.on(CoordinationEventType.SYNC_COMPLETED, (event) => {
|
|
45
|
+
* console.log('Sync completed with', event.peerId);
|
|
46
|
+
* });
|
|
47
|
+
* ```
|
|
48
|
+
*/
|
|
49
|
+
class CoordinationManager {
|
|
50
|
+
/**
|
|
51
|
+
* Create a new CoordinationManager
|
|
52
|
+
*
|
|
53
|
+
* @param config - Coordination configuration
|
|
54
|
+
*/
|
|
55
|
+
constructor(config) {
|
|
56
|
+
this.peers = new Map();
|
|
57
|
+
this.eventHandlers = new Map();
|
|
58
|
+
this.isDestroyed = false;
|
|
59
|
+
this.config = {
|
|
60
|
+
...types_1.DEFAULT_COORDINATION_CONFIG,
|
|
61
|
+
...config,
|
|
62
|
+
syncConfig: {
|
|
63
|
+
...types_1.DEFAULT_COORDINATION_CONFIG.syncConfig,
|
|
64
|
+
...config.syncConfig,
|
|
65
|
+
},
|
|
66
|
+
};
|
|
67
|
+
this.localCapabilities = (0, types_1.createDefaultCapabilities)();
|
|
68
|
+
// Setup logging
|
|
69
|
+
this.setupLogging();
|
|
70
|
+
}
|
|
71
|
+
// ============================================
|
|
72
|
+
// Public API - Connection Management
|
|
73
|
+
// ============================================
|
|
74
|
+
/**
|
|
75
|
+
* Set the message sender callback for transport
|
|
76
|
+
*/
|
|
77
|
+
setMessageSender(sender) {
|
|
78
|
+
this.messageSender = sender;
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Connect to a peer
|
|
82
|
+
*
|
|
83
|
+
* @param peerId - Peer to connect to
|
|
84
|
+
* @param role - Role in the connection
|
|
85
|
+
* @returns Promise resolving when connected
|
|
86
|
+
*/
|
|
87
|
+
async connect(peerId, role) {
|
|
88
|
+
this.ensureNotDestroyed();
|
|
89
|
+
// Check if already connected
|
|
90
|
+
const existing = this.peers.get(peerId);
|
|
91
|
+
if (existing && existing.info.state === 'synchronized') {
|
|
92
|
+
return existing.info;
|
|
93
|
+
}
|
|
94
|
+
const connectionRole = role ?? this.config.defaultRole;
|
|
95
|
+
this.log(`Connecting to peer: ${peerId} with role: ${connectionRole}`);
|
|
96
|
+
// Create peer state
|
|
97
|
+
const peerState = this.createPeerState(peerId, connectionRole);
|
|
98
|
+
this.peers.set(peerId, peerState);
|
|
99
|
+
// Update state to connecting
|
|
100
|
+
this.updatePeerState(peerId, types_1.CoordinationState.CONNECTING);
|
|
101
|
+
try {
|
|
102
|
+
// If initiator, send auth challenge
|
|
103
|
+
if (connectionRole === 'initiator' || connectionRole === 'bidirectional') {
|
|
104
|
+
await this.sendAuthChallenge(peerId, peerState);
|
|
105
|
+
}
|
|
106
|
+
return peerState.info;
|
|
107
|
+
}
|
|
108
|
+
catch (error) {
|
|
109
|
+
this.updatePeerState(peerId, types_1.CoordinationState.ERROR);
|
|
110
|
+
throw error;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Disconnect from a peer
|
|
115
|
+
*
|
|
116
|
+
* @param peerId - Peer to disconnect from
|
|
117
|
+
* @param reason - Reason for disconnection
|
|
118
|
+
*/
|
|
119
|
+
async disconnect(peerId, reason) {
|
|
120
|
+
const peerState = this.peers.get(peerId);
|
|
121
|
+
if (!peerState) {
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
this.log(`Disconnecting from peer: ${peerId}, reason: ${reason ?? 'user requested'}`);
|
|
125
|
+
try {
|
|
126
|
+
// Send disconnect message
|
|
127
|
+
await this.sendMessage(peerId, {
|
|
128
|
+
type: types_1.CoordinationMessageType.DISCONNECT,
|
|
129
|
+
messageId: (0, types_1.generateMessageId)(),
|
|
130
|
+
senderId: this.config.localIdentity.agentId,
|
|
131
|
+
payload: { reason: reason ?? 'disconnect requested' },
|
|
132
|
+
timestamp: Date.now(),
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
catch {
|
|
136
|
+
// Ignore send errors during disconnect
|
|
137
|
+
}
|
|
138
|
+
// Cleanup peer state
|
|
139
|
+
this.cleanupPeer(peerId);
|
|
140
|
+
this.emit(types_1.CoordinationEventType.PEER_DISCONNECTED, peerId, { reason });
|
|
141
|
+
}
|
|
142
|
+
/**
|
|
143
|
+
* Handle incoming message from a peer
|
|
144
|
+
*
|
|
145
|
+
* @param peerId - Sender peer ID
|
|
146
|
+
* @param message - Received message
|
|
147
|
+
*/
|
|
148
|
+
async handleMessage(peerId, message) {
|
|
149
|
+
this.ensureNotDestroyed();
|
|
150
|
+
let peerState = this.peers.get(peerId);
|
|
151
|
+
// Create peer state if this is a new incoming connection
|
|
152
|
+
if (!peerState) {
|
|
153
|
+
peerState = this.createPeerState(peerId, types_1.CoordinationRole.RESPONDER);
|
|
154
|
+
this.peers.set(peerId, peerState);
|
|
155
|
+
}
|
|
156
|
+
// Update metrics
|
|
157
|
+
peerState.info.metrics.messagesReceived++;
|
|
158
|
+
peerState.info.lastSeenAt = Date.now();
|
|
159
|
+
this.logDebug(`Received message from ${peerId}: ${message.type}`);
|
|
160
|
+
try {
|
|
161
|
+
switch (message.type) {
|
|
162
|
+
case types_1.CoordinationMessageType.AUTH_CHALLENGE:
|
|
163
|
+
await this.handleAuthChallenge(peerId, peerState, message.payload, message.messageId);
|
|
164
|
+
break;
|
|
165
|
+
case types_1.CoordinationMessageType.AUTH_RESPONSE:
|
|
166
|
+
await this.handleAuthResponse(peerId, peerState, message.payload, message.correlationId);
|
|
167
|
+
break;
|
|
168
|
+
case types_1.CoordinationMessageType.AUTH_RESULT:
|
|
169
|
+
await this.handleAuthResult(peerId, peerState, message.payload);
|
|
170
|
+
break;
|
|
171
|
+
case types_1.CoordinationMessageType.CAPABILITIES:
|
|
172
|
+
await this.handleCapabilities(peerId, peerState, message.payload);
|
|
173
|
+
break;
|
|
174
|
+
case types_1.CoordinationMessageType.PING:
|
|
175
|
+
await this.handlePing(peerId, peerState, message.payload);
|
|
176
|
+
break;
|
|
177
|
+
case types_1.CoordinationMessageType.PONG:
|
|
178
|
+
await this.handlePong(peerId, peerState, message.payload);
|
|
179
|
+
break;
|
|
180
|
+
case types_1.CoordinationMessageType.SYNC_REQUEST:
|
|
181
|
+
case types_1.CoordinationMessageType.SYNC_RESPONSE:
|
|
182
|
+
case types_1.CoordinationMessageType.SYNC_COMPLETE:
|
|
183
|
+
case types_1.CoordinationMessageType.PATTERN_BATCH:
|
|
184
|
+
await peerState.syncOrchestrator.handleMessage(message);
|
|
185
|
+
break;
|
|
186
|
+
case types_1.CoordinationMessageType.CONFLICT:
|
|
187
|
+
await this.handleConflict(peerId, peerState, message.payload);
|
|
188
|
+
break;
|
|
189
|
+
case types_1.CoordinationMessageType.ERROR:
|
|
190
|
+
await this.handleError(peerId, peerState, message.payload);
|
|
191
|
+
break;
|
|
192
|
+
case types_1.CoordinationMessageType.DISCONNECT:
|
|
193
|
+
await this.handleDisconnect(peerId, peerState, message.payload);
|
|
194
|
+
break;
|
|
195
|
+
default:
|
|
196
|
+
this.logWarn(`Unknown message type: ${message.type}`);
|
|
197
|
+
}
|
|
198
|
+
// Resolve pending response if this is a response
|
|
199
|
+
if (message.correlationId) {
|
|
200
|
+
const pending = peerState.pendingResponses.get(message.correlationId);
|
|
201
|
+
if (pending) {
|
|
202
|
+
clearTimeout(pending.timeout);
|
|
203
|
+
pending.resolve(message.payload);
|
|
204
|
+
peerState.pendingResponses.delete(message.correlationId);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
catch (error) {
|
|
209
|
+
this.logError(`Error handling message from ${peerId}:`, error);
|
|
210
|
+
this.emit(types_1.CoordinationEventType.ERROR, peerId, { error, message });
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
// ============================================
|
|
214
|
+
// Public API - Synchronization
|
|
215
|
+
// ============================================
|
|
216
|
+
/**
|
|
217
|
+
* Start pattern synchronization with a peer
|
|
218
|
+
*
|
|
219
|
+
* @param peerId - Peer to sync with
|
|
220
|
+
* @param patterns - Local patterns to sync
|
|
221
|
+
* @returns Sync result
|
|
222
|
+
*/
|
|
223
|
+
async syncPatterns(peerId, patterns) {
|
|
224
|
+
const peerState = this.getPeerStateOrThrow(peerId);
|
|
225
|
+
if (!peerState.info.isAuthenticated) {
|
|
226
|
+
throw new types_1.CoordinationError('Peer not authenticated', types_1.CoordinationErrorCode.PEER_NOT_AUTHENTICATED, peerId);
|
|
227
|
+
}
|
|
228
|
+
this.log(`Starting pattern sync with peer: ${peerId}`);
|
|
229
|
+
this.updatePeerState(peerId, types_1.CoordinationState.SYNCING);
|
|
230
|
+
this.emit(types_1.CoordinationEventType.SYNC_STARTED, peerId, {
|
|
231
|
+
patternCount: patterns?.length ?? 0,
|
|
232
|
+
});
|
|
233
|
+
try {
|
|
234
|
+
const result = await peerState.syncOrchestrator.startSync(patterns);
|
|
235
|
+
if (result.state === 'completed') {
|
|
236
|
+
this.updatePeerState(peerId, types_1.CoordinationState.SYNCHRONIZED);
|
|
237
|
+
peerState.info.metrics.successfulSyncs++;
|
|
238
|
+
this.emit(types_1.CoordinationEventType.SYNC_COMPLETED, peerId, result);
|
|
239
|
+
}
|
|
240
|
+
else if (result.state === 'failed') {
|
|
241
|
+
peerState.info.metrics.failedSyncs++;
|
|
242
|
+
this.emit(types_1.CoordinationEventType.SYNC_FAILED, peerId, result);
|
|
243
|
+
}
|
|
244
|
+
return result;
|
|
245
|
+
}
|
|
246
|
+
catch (error) {
|
|
247
|
+
peerState.info.metrics.failedSyncs++;
|
|
248
|
+
this.emit(types_1.CoordinationEventType.SYNC_FAILED, peerId, { error });
|
|
249
|
+
throw error;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
/**
|
|
253
|
+
* Get sync status for a peer
|
|
254
|
+
*/
|
|
255
|
+
getSyncStatus(peerId) {
|
|
256
|
+
return this.peers.get(peerId)?.info.syncStatus;
|
|
257
|
+
}
|
|
258
|
+
// ============================================
|
|
259
|
+
// Public API - Health & Metrics
|
|
260
|
+
// ============================================
|
|
261
|
+
/**
|
|
262
|
+
* Get health status for a peer
|
|
263
|
+
*/
|
|
264
|
+
getHealthStatus(peerId) {
|
|
265
|
+
return this.peers.get(peerId)?.info.health;
|
|
266
|
+
}
|
|
267
|
+
/**
|
|
268
|
+
* Get coordination metrics for a peer
|
|
269
|
+
*/
|
|
270
|
+
getMetrics(peerId) {
|
|
271
|
+
return this.peers.get(peerId)?.info.metrics;
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Get peer information
|
|
275
|
+
*/
|
|
276
|
+
getPeerInfo(peerId) {
|
|
277
|
+
return this.peers.get(peerId)?.info;
|
|
278
|
+
}
|
|
279
|
+
/**
|
|
280
|
+
* Get all connected peers
|
|
281
|
+
*/
|
|
282
|
+
getConnectedPeers() {
|
|
283
|
+
return Array.from(this.peers.values())
|
|
284
|
+
.filter((state) => state.info.state !== types_1.CoordinationState.DISCONNECTED &&
|
|
285
|
+
state.info.state !== types_1.CoordinationState.ERROR)
|
|
286
|
+
.map((state) => state.info);
|
|
287
|
+
}
|
|
288
|
+
/**
|
|
289
|
+
* Get all authenticated peers
|
|
290
|
+
*/
|
|
291
|
+
getAuthenticatedPeers() {
|
|
292
|
+
return Array.from(this.peers.values())
|
|
293
|
+
.filter((state) => state.info.isAuthenticated)
|
|
294
|
+
.map((state) => state.info);
|
|
295
|
+
}
|
|
296
|
+
/**
|
|
297
|
+
* Get coordination state for a peer
|
|
298
|
+
*/
|
|
299
|
+
getState(peerId) {
|
|
300
|
+
return this.peers.get(peerId)?.info.state;
|
|
301
|
+
}
|
|
302
|
+
/**
|
|
303
|
+
* Get local identity
|
|
304
|
+
*/
|
|
305
|
+
getLocalIdentity() {
|
|
306
|
+
return this.config.localIdentity;
|
|
307
|
+
}
|
|
308
|
+
// ============================================
|
|
309
|
+
// Public API - Events
|
|
310
|
+
// ============================================
|
|
311
|
+
/**
|
|
312
|
+
* Register event handler
|
|
313
|
+
*
|
|
314
|
+
* @param event - Event type to handle
|
|
315
|
+
* @param handler - Event handler function
|
|
316
|
+
* @returns Unsubscribe function
|
|
317
|
+
*/
|
|
318
|
+
on(event, handler) {
|
|
319
|
+
if (!this.eventHandlers.has(event)) {
|
|
320
|
+
this.eventHandlers.set(event, new Set());
|
|
321
|
+
}
|
|
322
|
+
this.eventHandlers.get(event).add(handler);
|
|
323
|
+
return () => {
|
|
324
|
+
this.eventHandlers.get(event)?.delete(handler);
|
|
325
|
+
};
|
|
326
|
+
}
|
|
327
|
+
/**
|
|
328
|
+
* Remove event handler
|
|
329
|
+
*/
|
|
330
|
+
off(event, handler) {
|
|
331
|
+
this.eventHandlers.get(event)?.delete(handler);
|
|
332
|
+
}
|
|
333
|
+
// ============================================
|
|
334
|
+
// Public API - Lifecycle
|
|
335
|
+
// ============================================
|
|
336
|
+
/**
|
|
337
|
+
* Destroy the coordination manager
|
|
338
|
+
*/
|
|
339
|
+
async destroy() {
|
|
340
|
+
this.isDestroyed = true;
|
|
341
|
+
// Disconnect all peers
|
|
342
|
+
const disconnectPromises = Array.from(this.peers.keys()).map((peerId) => this.disconnect(peerId, 'manager destroyed'));
|
|
343
|
+
await Promise.all(disconnectPromises);
|
|
344
|
+
// Clear event handlers
|
|
345
|
+
this.eventHandlers.clear();
|
|
346
|
+
this.log('CoordinationManager destroyed');
|
|
347
|
+
}
|
|
348
|
+
// ============================================
|
|
349
|
+
// Private - Authentication
|
|
350
|
+
// ============================================
|
|
351
|
+
async sendAuthChallenge(peerId, peerState) {
|
|
352
|
+
const challenge = (0, types_1.generateChallenge)();
|
|
353
|
+
const timestamp = Date.now();
|
|
354
|
+
const expiresIn = this.config.authTimeout;
|
|
355
|
+
// Store pending challenge
|
|
356
|
+
peerState.pendingChallenge = {
|
|
357
|
+
challenge,
|
|
358
|
+
timestamp,
|
|
359
|
+
expiresAt: timestamp + expiresIn,
|
|
360
|
+
};
|
|
361
|
+
this.updatePeerState(peerId, types_1.CoordinationState.AUTHENTICATING);
|
|
362
|
+
const payload = {
|
|
363
|
+
challenge,
|
|
364
|
+
timestamp: new Date(timestamp).toISOString(),
|
|
365
|
+
expiresIn,
|
|
366
|
+
capabilities: this.localCapabilities,
|
|
367
|
+
};
|
|
368
|
+
await this.sendMessage(peerId, {
|
|
369
|
+
type: types_1.CoordinationMessageType.AUTH_CHALLENGE,
|
|
370
|
+
messageId: (0, types_1.generateMessageId)(),
|
|
371
|
+
senderId: this.config.localIdentity.agentId,
|
|
372
|
+
payload,
|
|
373
|
+
timestamp,
|
|
374
|
+
});
|
|
375
|
+
}
|
|
376
|
+
async handleAuthChallenge(peerId, peerState, payload, messageId) {
|
|
377
|
+
this.log(`Received auth challenge from ${peerId}`);
|
|
378
|
+
this.updatePeerState(peerId, types_1.CoordinationState.AUTHENTICATING);
|
|
379
|
+
// Update peer capabilities
|
|
380
|
+
peerState.info.capabilities = payload.capabilities;
|
|
381
|
+
// Create identity proof by signing the challenge
|
|
382
|
+
const identityProof = await this.createIdentityProof(payload.challenge, payload.expiresIn);
|
|
383
|
+
const response = {
|
|
384
|
+
identityProof,
|
|
385
|
+
capabilities: this.localCapabilities,
|
|
386
|
+
};
|
|
387
|
+
await this.sendMessage(peerId, {
|
|
388
|
+
type: types_1.CoordinationMessageType.AUTH_RESPONSE,
|
|
389
|
+
messageId: (0, types_1.generateMessageId)(),
|
|
390
|
+
correlationId: messageId,
|
|
391
|
+
senderId: this.config.localIdentity.agentId,
|
|
392
|
+
payload: response,
|
|
393
|
+
timestamp: Date.now(),
|
|
394
|
+
});
|
|
395
|
+
}
|
|
396
|
+
async handleAuthResponse(peerId, peerState, payload, correlationId) {
|
|
397
|
+
this.log(`Received auth response from ${peerId}`);
|
|
398
|
+
// Verify we have a pending challenge
|
|
399
|
+
if (!peerState.pendingChallenge) {
|
|
400
|
+
throw new types_1.CoordinationError('No pending challenge', types_1.CoordinationErrorCode.AUTH_FAILED, peerId);
|
|
401
|
+
}
|
|
402
|
+
// Check challenge hasn't expired
|
|
403
|
+
if (Date.now() > peerState.pendingChallenge.expiresAt) {
|
|
404
|
+
throw new types_1.CoordinationError('Challenge expired', types_1.CoordinationErrorCode.AUTH_TIMEOUT, peerId);
|
|
405
|
+
}
|
|
406
|
+
// Verify the identity proof
|
|
407
|
+
const isValid = await this.verifyIdentityProof(payload.identityProof, peerState.pendingChallenge.challenge);
|
|
408
|
+
// Clear pending challenge
|
|
409
|
+
peerState.pendingChallenge = undefined;
|
|
410
|
+
if (!isValid) {
|
|
411
|
+
peerState.info.isAuthenticated = false;
|
|
412
|
+
this.emit(types_1.CoordinationEventType.AUTH_FAILED, peerId, { reason: 'Invalid signature' });
|
|
413
|
+
await this.sendMessage(peerId, {
|
|
414
|
+
type: types_1.CoordinationMessageType.AUTH_RESULT,
|
|
415
|
+
messageId: (0, types_1.generateMessageId)(),
|
|
416
|
+
correlationId,
|
|
417
|
+
senderId: this.config.localIdentity.agentId,
|
|
418
|
+
payload: { success: false, error: 'Invalid signature' },
|
|
419
|
+
timestamp: Date.now(),
|
|
420
|
+
});
|
|
421
|
+
return;
|
|
422
|
+
}
|
|
423
|
+
// Check trust if callback provided
|
|
424
|
+
if (this.config.onVerifyTrust) {
|
|
425
|
+
const identity = {
|
|
426
|
+
agentId: payload.identityProof.agentId,
|
|
427
|
+
publicKey: payload.identityProof.publicKey,
|
|
428
|
+
createdAt: new Date().toISOString(),
|
|
429
|
+
};
|
|
430
|
+
const isTrusted = await this.config.onVerifyTrust(identity);
|
|
431
|
+
peerState.info.isTrusted = isTrusted;
|
|
432
|
+
}
|
|
433
|
+
// Update peer info
|
|
434
|
+
peerState.info.identity = {
|
|
435
|
+
agentId: payload.identityProof.agentId,
|
|
436
|
+
publicKey: payload.identityProof.publicKey,
|
|
437
|
+
createdAt: new Date().toISOString(),
|
|
438
|
+
};
|
|
439
|
+
peerState.info.publicKey = payload.identityProof.publicKey;
|
|
440
|
+
peerState.info.capabilities = payload.capabilities;
|
|
441
|
+
peerState.info.isAuthenticated = true;
|
|
442
|
+
// Generate session ID using cryptographically secure random
|
|
443
|
+
const randomBytes = new Uint8Array(4);
|
|
444
|
+
crypto.getRandomValues(randomBytes);
|
|
445
|
+
const randomPart = Array.from(randomBytes).map(b => b.toString(36)).join('').substring(0, 6);
|
|
446
|
+
const sessionId = `session-${Date.now().toString(36)}-${randomPart}`;
|
|
447
|
+
peerState.sessionId = sessionId;
|
|
448
|
+
// Send success result
|
|
449
|
+
await this.sendMessage(peerId, {
|
|
450
|
+
type: types_1.CoordinationMessageType.AUTH_RESULT,
|
|
451
|
+
messageId: (0, types_1.generateMessageId)(),
|
|
452
|
+
correlationId,
|
|
453
|
+
senderId: this.config.localIdentity.agentId,
|
|
454
|
+
payload: {
|
|
455
|
+
success: true,
|
|
456
|
+
sessionId,
|
|
457
|
+
capabilities: this.localCapabilities,
|
|
458
|
+
},
|
|
459
|
+
timestamp: Date.now(),
|
|
460
|
+
});
|
|
461
|
+
this.log(`Peer ${peerId} authenticated successfully`);
|
|
462
|
+
this.emit(types_1.CoordinationEventType.PEER_AUTHENTICATED, peerId, {
|
|
463
|
+
identity: peerState.info.identity,
|
|
464
|
+
sessionId,
|
|
465
|
+
});
|
|
466
|
+
// Update state based on sync config
|
|
467
|
+
if (this.config.syncConfig.autoSyncOnConnect) {
|
|
468
|
+
this.updatePeerState(peerId, types_1.CoordinationState.SYNCING);
|
|
469
|
+
}
|
|
470
|
+
else {
|
|
471
|
+
this.updatePeerState(peerId, types_1.CoordinationState.SYNCHRONIZED);
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
async handleAuthResult(peerId, peerState, payload) {
|
|
475
|
+
if (!payload.success) {
|
|
476
|
+
this.logError(`Authentication failed with ${peerId}: ${payload.error}`);
|
|
477
|
+
peerState.info.isAuthenticated = false;
|
|
478
|
+
this.updatePeerState(peerId, types_1.CoordinationState.ERROR);
|
|
479
|
+
this.emit(types_1.CoordinationEventType.AUTH_FAILED, peerId, { error: payload.error });
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
this.log(`Authentication successful with ${peerId}`);
|
|
483
|
+
peerState.info.isAuthenticated = true;
|
|
484
|
+
peerState.sessionId = payload.sessionId;
|
|
485
|
+
if (payload.capabilities) {
|
|
486
|
+
peerState.info.capabilities = payload.capabilities;
|
|
487
|
+
}
|
|
488
|
+
peerState.info.connectedAt = Date.now();
|
|
489
|
+
this.emit(types_1.CoordinationEventType.PEER_AUTHENTICATED, peerId, {
|
|
490
|
+
sessionId: payload.sessionId,
|
|
491
|
+
});
|
|
492
|
+
this.emit(types_1.CoordinationEventType.PEER_CONNECTED, peerId, {
|
|
493
|
+
capabilities: peerState.info.capabilities,
|
|
494
|
+
});
|
|
495
|
+
// Update state
|
|
496
|
+
if (this.config.syncConfig.autoSyncOnConnect) {
|
|
497
|
+
this.updatePeerState(peerId, types_1.CoordinationState.SYNCING);
|
|
498
|
+
}
|
|
499
|
+
else {
|
|
500
|
+
this.updatePeerState(peerId, types_1.CoordinationState.SYNCHRONIZED);
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
async createIdentityProof(challenge, expiresIn) {
|
|
504
|
+
// Sign the challenge with our private key
|
|
505
|
+
const encoder = new TextEncoder();
|
|
506
|
+
const data = encoder.encode(challenge);
|
|
507
|
+
// Import private key and sign
|
|
508
|
+
// In a real implementation, use proper Ed25519 signing via @noble/ed25519
|
|
509
|
+
// For browser compatibility, we use a simplified approach
|
|
510
|
+
const signature = await this.signData(data);
|
|
511
|
+
return {
|
|
512
|
+
agentId: this.config.localIdentity.agentId,
|
|
513
|
+
publicKey: this.config.localKeyPair.publicKey,
|
|
514
|
+
challenge,
|
|
515
|
+
signature: this.arrayToBase64(signature),
|
|
516
|
+
timestamp: new Date().toISOString(),
|
|
517
|
+
expiresIn,
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
async verifyIdentityProof(proof, expectedChallenge) {
|
|
521
|
+
// Verify challenge matches
|
|
522
|
+
if (proof.challenge !== expectedChallenge) {
|
|
523
|
+
return false;
|
|
524
|
+
}
|
|
525
|
+
// Check expiration
|
|
526
|
+
const proofTime = new Date(proof.timestamp).getTime();
|
|
527
|
+
if (Date.now() > proofTime + proof.expiresIn) {
|
|
528
|
+
return false;
|
|
529
|
+
}
|
|
530
|
+
// Verify signature
|
|
531
|
+
// In a real implementation, use proper Ed25519 verification
|
|
532
|
+
try {
|
|
533
|
+
const encoder = new TextEncoder();
|
|
534
|
+
const data = encoder.encode(proof.challenge);
|
|
535
|
+
const signature = this.base64ToArray(proof.signature);
|
|
536
|
+
const publicKey = this.base64ToArray(proof.publicKey);
|
|
537
|
+
return await this.verifySignature(data, signature, publicKey);
|
|
538
|
+
}
|
|
539
|
+
catch {
|
|
540
|
+
return false;
|
|
541
|
+
}
|
|
542
|
+
}
|
|
543
|
+
// ============================================
|
|
544
|
+
// Private - Health Monitoring
|
|
545
|
+
// ============================================
|
|
546
|
+
async handlePing(peerId, peerState, payload) {
|
|
547
|
+
const pong = {
|
|
548
|
+
sequence: payload.sequence,
|
|
549
|
+
originalTimestamp: payload.timestamp,
|
|
550
|
+
timestamp: Date.now(),
|
|
551
|
+
};
|
|
552
|
+
await this.sendMessage(peerId, {
|
|
553
|
+
type: types_1.CoordinationMessageType.PONG,
|
|
554
|
+
messageId: (0, types_1.generateMessageId)(),
|
|
555
|
+
senderId: this.config.localIdentity.agentId,
|
|
556
|
+
payload: pong,
|
|
557
|
+
timestamp: Date.now(),
|
|
558
|
+
});
|
|
559
|
+
}
|
|
560
|
+
async handlePong(_peerId, peerState, payload) {
|
|
561
|
+
peerState.healthMonitor.recordPong(payload.sequence, payload.originalTimestamp, payload.timestamp);
|
|
562
|
+
}
|
|
563
|
+
async handleCapabilities(peerId, peerState, capabilities) {
|
|
564
|
+
peerState.info.capabilities = capabilities;
|
|
565
|
+
this.log(`Updated capabilities for ${peerId}`);
|
|
566
|
+
}
|
|
567
|
+
async handleConflict(peerId, peerState, payload) {
|
|
568
|
+
peerState.info.metrics.conflictsDetected++;
|
|
569
|
+
this.emit(types_1.CoordinationEventType.CONFLICT_DETECTED, peerId, payload);
|
|
570
|
+
}
|
|
571
|
+
async handleError(peerId, _peerState, payload) {
|
|
572
|
+
this.logError(`Received error from ${peerId}:`, payload);
|
|
573
|
+
this.emit(types_1.CoordinationEventType.ERROR, peerId, payload);
|
|
574
|
+
}
|
|
575
|
+
async handleDisconnect(peerId, _peerState, payload) {
|
|
576
|
+
this.log(`Peer ${peerId} disconnected: ${payload.reason ?? 'no reason given'}`);
|
|
577
|
+
this.cleanupPeer(peerId);
|
|
578
|
+
this.emit(types_1.CoordinationEventType.PEER_DISCONNECTED, peerId, payload);
|
|
579
|
+
}
|
|
580
|
+
// ============================================
|
|
581
|
+
// Private - Peer State Management
|
|
582
|
+
// ============================================
|
|
583
|
+
createPeerState(peerId, role) {
|
|
584
|
+
const info = {
|
|
585
|
+
peerId,
|
|
586
|
+
state: types_1.CoordinationState.DISCONNECTED,
|
|
587
|
+
role,
|
|
588
|
+
health: (0, types_1.createDefaultHealthStatus)(),
|
|
589
|
+
metrics: (0, types_1.createDefaultMetrics)(),
|
|
590
|
+
syncStatus: (0, types_1.createDefaultSyncStatus)(),
|
|
591
|
+
isAuthenticated: false,
|
|
592
|
+
isTrusted: false,
|
|
593
|
+
capabilities: (0, types_1.createDefaultCapabilities)(),
|
|
594
|
+
lastSeenAt: Date.now(),
|
|
595
|
+
reconnectAttempts: 0,
|
|
596
|
+
};
|
|
597
|
+
const healthMonitor = new HealthMonitor_1.HealthMonitor({
|
|
598
|
+
peerId,
|
|
599
|
+
pingInterval: this.config.pingInterval,
|
|
600
|
+
onPing: async (sequence) => {
|
|
601
|
+
await this.sendPing(peerId, sequence);
|
|
602
|
+
},
|
|
603
|
+
onHealthChange: (health) => {
|
|
604
|
+
const peerState = this.peers.get(peerId);
|
|
605
|
+
if (peerState) {
|
|
606
|
+
peerState.info.health = health;
|
|
607
|
+
this.handleHealthChange(peerId, health);
|
|
608
|
+
}
|
|
609
|
+
},
|
|
610
|
+
});
|
|
611
|
+
const syncOrchestrator = new SyncOrchestrator_1.SyncOrchestrator({
|
|
612
|
+
localAgentId: this.config.localIdentity.agentId,
|
|
613
|
+
peerId,
|
|
614
|
+
config: this.config.syncConfig,
|
|
615
|
+
sendMessage: async (message) => {
|
|
616
|
+
await this.sendMessage(peerId, message);
|
|
617
|
+
},
|
|
618
|
+
onSyncProgress: (status) => {
|
|
619
|
+
const peerState = this.peers.get(peerId);
|
|
620
|
+
if (peerState) {
|
|
621
|
+
peerState.info.syncStatus = status;
|
|
622
|
+
this.emit(types_1.CoordinationEventType.SYNC_PROGRESS, peerId, status);
|
|
623
|
+
}
|
|
624
|
+
},
|
|
625
|
+
});
|
|
626
|
+
return {
|
|
627
|
+
info,
|
|
628
|
+
healthMonitor,
|
|
629
|
+
syncOrchestrator,
|
|
630
|
+
pendingResponses: new Map(),
|
|
631
|
+
lastSequence: 0,
|
|
632
|
+
};
|
|
633
|
+
}
|
|
634
|
+
updatePeerState(peerId, newState) {
|
|
635
|
+
const peerState = this.peers.get(peerId);
|
|
636
|
+
if (!peerState) {
|
|
637
|
+
return;
|
|
638
|
+
}
|
|
639
|
+
const previousState = peerState.info.state;
|
|
640
|
+
peerState.info.state = newState;
|
|
641
|
+
this.emit(types_1.CoordinationEventType.STATE_CHANGED, peerId, {
|
|
642
|
+
previousState,
|
|
643
|
+
newState,
|
|
644
|
+
});
|
|
645
|
+
}
|
|
646
|
+
handleHealthChange(peerId, health) {
|
|
647
|
+
if (health.level === types_1.HealthLevel.WARNING) {
|
|
648
|
+
this.emit(types_1.CoordinationEventType.HEALTH_WARNING, peerId, health);
|
|
649
|
+
// Update state to degraded if currently synchronized
|
|
650
|
+
const peerState = this.peers.get(peerId);
|
|
651
|
+
if (peerState?.info.state === types_1.CoordinationState.SYNCHRONIZED) {
|
|
652
|
+
this.updatePeerState(peerId, types_1.CoordinationState.DEGRADED);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
else if (health.level === types_1.HealthLevel.CRITICAL || health.level === types_1.HealthLevel.UNHEALTHY) {
|
|
656
|
+
this.emit(types_1.CoordinationEventType.HEALTH_CRITICAL, peerId, health);
|
|
657
|
+
// Trigger reconnection if configured
|
|
658
|
+
if (this.config.autoReconnect) {
|
|
659
|
+
this.attemptReconnection(peerId);
|
|
660
|
+
}
|
|
661
|
+
}
|
|
662
|
+
else if (health.level === types_1.HealthLevel.HEALTHY) {
|
|
663
|
+
// Recover from degraded state
|
|
664
|
+
const peerState = this.peers.get(peerId);
|
|
665
|
+
if (peerState?.info.state === types_1.CoordinationState.DEGRADED) {
|
|
666
|
+
this.updatePeerState(peerId, types_1.CoordinationState.SYNCHRONIZED);
|
|
667
|
+
this.emit(types_1.CoordinationEventType.HEALTH_RECOVERED, peerId, health);
|
|
668
|
+
}
|
|
669
|
+
}
|
|
670
|
+
}
|
|
671
|
+
async attemptReconnection(peerId) {
|
|
672
|
+
const peerState = this.peers.get(peerId);
|
|
673
|
+
if (!peerState) {
|
|
674
|
+
return;
|
|
675
|
+
}
|
|
676
|
+
if (peerState.info.reconnectAttempts >= this.config.maxReconnectAttempts) {
|
|
677
|
+
this.logError(`Max reconnection attempts reached for ${peerId}`);
|
|
678
|
+
this.updatePeerState(peerId, types_1.CoordinationState.ERROR);
|
|
679
|
+
this.emit(types_1.CoordinationEventType.RECONNECT_FAILED, peerId, {
|
|
680
|
+
attempts: peerState.info.reconnectAttempts,
|
|
681
|
+
});
|
|
682
|
+
return;
|
|
683
|
+
}
|
|
684
|
+
peerState.info.reconnectAttempts++;
|
|
685
|
+
peerState.info.metrics.reconnectionAttempts++;
|
|
686
|
+
this.updatePeerState(peerId, types_1.CoordinationState.RECONNECTING);
|
|
687
|
+
this.emit(types_1.CoordinationEventType.RECONNECTING, peerId, {
|
|
688
|
+
attempt: peerState.info.reconnectAttempts,
|
|
689
|
+
maxAttempts: this.config.maxReconnectAttempts,
|
|
690
|
+
});
|
|
691
|
+
// Exponential backoff
|
|
692
|
+
const delay = Math.min(1000 * Math.pow(2, peerState.info.reconnectAttempts - 1), this.config.reconnectTimeout);
|
|
693
|
+
await this.delay(delay);
|
|
694
|
+
try {
|
|
695
|
+
// Reset authentication state
|
|
696
|
+
peerState.info.isAuthenticated = false;
|
|
697
|
+
peerState.pendingChallenge = undefined;
|
|
698
|
+
peerState.sessionId = undefined;
|
|
699
|
+
// Attempt to reconnect
|
|
700
|
+
await this.sendAuthChallenge(peerId, peerState);
|
|
701
|
+
}
|
|
702
|
+
catch (error) {
|
|
703
|
+
this.logError(`Reconnection attempt ${peerState.info.reconnectAttempts} failed:`, error);
|
|
704
|
+
await this.attemptReconnection(peerId);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
cleanupPeer(peerId) {
|
|
708
|
+
const peerState = this.peers.get(peerId);
|
|
709
|
+
if (!peerState) {
|
|
710
|
+
return;
|
|
711
|
+
}
|
|
712
|
+
// Stop health monitoring
|
|
713
|
+
peerState.healthMonitor.stop();
|
|
714
|
+
// Stop sync orchestrator
|
|
715
|
+
peerState.syncOrchestrator.stop();
|
|
716
|
+
// Clear pending responses
|
|
717
|
+
peerState.pendingResponses.forEach((pending) => {
|
|
718
|
+
clearTimeout(pending.timeout);
|
|
719
|
+
pending.reject(new Error('Peer disconnected'));
|
|
720
|
+
});
|
|
721
|
+
peerState.pendingResponses.clear();
|
|
722
|
+
// Remove from peers map
|
|
723
|
+
this.peers.delete(peerId);
|
|
724
|
+
}
|
|
725
|
+
getPeerStateOrThrow(peerId) {
|
|
726
|
+
const peerState = this.peers.get(peerId);
|
|
727
|
+
if (!peerState) {
|
|
728
|
+
throw new types_1.CoordinationError(`Peer not found: ${peerId}`, types_1.CoordinationErrorCode.PEER_NOT_FOUND, peerId);
|
|
729
|
+
}
|
|
730
|
+
return peerState;
|
|
731
|
+
}
|
|
732
|
+
// ============================================
|
|
733
|
+
// Private - Messaging
|
|
734
|
+
// ============================================
|
|
735
|
+
async sendMessage(peerId, message) {
|
|
736
|
+
if (!this.messageSender) {
|
|
737
|
+
throw new types_1.CoordinationError('No message sender configured', types_1.CoordinationErrorCode.CONNECTION_FAILED, peerId);
|
|
738
|
+
}
|
|
739
|
+
const peerState = this.peers.get(peerId);
|
|
740
|
+
if (peerState) {
|
|
741
|
+
peerState.info.metrics.messagesSent++;
|
|
742
|
+
}
|
|
743
|
+
await this.messageSender(peerId, message);
|
|
744
|
+
}
|
|
745
|
+
async sendPing(peerId, sequence) {
|
|
746
|
+
const payload = {
|
|
747
|
+
sequence,
|
|
748
|
+
timestamp: Date.now(),
|
|
749
|
+
};
|
|
750
|
+
await this.sendMessage(peerId, {
|
|
751
|
+
type: types_1.CoordinationMessageType.PING,
|
|
752
|
+
messageId: (0, types_1.generateMessageId)(),
|
|
753
|
+
senderId: this.config.localIdentity.agentId,
|
|
754
|
+
payload,
|
|
755
|
+
timestamp: Date.now(),
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
// ============================================
|
|
759
|
+
// Private - Crypto Helpers
|
|
760
|
+
// ============================================
|
|
761
|
+
async signData(data) {
|
|
762
|
+
// Simplified signing using Web Crypto API
|
|
763
|
+
// In production, use proper Ed25519 signing via @noble/ed25519
|
|
764
|
+
const keyData = this.base64ToArray(this.config.localKeyPair.privateKey);
|
|
765
|
+
// Use HMAC as a placeholder for Ed25519 signing
|
|
766
|
+
// This is for demonstration - use proper Ed25519 in production
|
|
767
|
+
const key = await crypto.subtle.importKey('raw', keyData.slice(0, 32).buffer, { name: 'HMAC', hash: 'SHA-256' }, false, ['sign']);
|
|
768
|
+
const signature = await crypto.subtle.sign('HMAC', key, data.buffer);
|
|
769
|
+
return new Uint8Array(signature);
|
|
770
|
+
}
|
|
771
|
+
async verifySignature(data, signature, publicKey) {
|
|
772
|
+
// Simplified verification using Web Crypto API
|
|
773
|
+
// In production, use proper Ed25519 verification
|
|
774
|
+
try {
|
|
775
|
+
const key = await crypto.subtle.importKey('raw', publicKey.buffer, { name: 'HMAC', hash: 'SHA-256' }, false, ['verify']);
|
|
776
|
+
return await crypto.subtle.verify('HMAC', key, signature.buffer, data.buffer);
|
|
777
|
+
}
|
|
778
|
+
catch {
|
|
779
|
+
return false;
|
|
780
|
+
}
|
|
781
|
+
}
|
|
782
|
+
arrayToBase64(array) {
|
|
783
|
+
return btoa(Array.from(array).map((b) => String.fromCharCode(b)).join(''));
|
|
784
|
+
}
|
|
785
|
+
base64ToArray(base64) {
|
|
786
|
+
const binary = atob(base64);
|
|
787
|
+
const array = new Uint8Array(binary.length);
|
|
788
|
+
for (let i = 0; i < binary.length; i++) {
|
|
789
|
+
array[i] = binary.charCodeAt(i);
|
|
790
|
+
}
|
|
791
|
+
return array;
|
|
792
|
+
}
|
|
793
|
+
// ============================================
|
|
794
|
+
// Private - Utilities
|
|
795
|
+
// ============================================
|
|
796
|
+
emit(type, peerId, data) {
|
|
797
|
+
const event = {
|
|
798
|
+
type,
|
|
799
|
+
timestamp: Date.now(),
|
|
800
|
+
peerId,
|
|
801
|
+
data,
|
|
802
|
+
};
|
|
803
|
+
const handlers = this.eventHandlers.get(type);
|
|
804
|
+
handlers?.forEach((handler) => {
|
|
805
|
+
try {
|
|
806
|
+
handler(event);
|
|
807
|
+
}
|
|
808
|
+
catch (error) {
|
|
809
|
+
this.logError(`Event handler error for ${type}:`, error);
|
|
810
|
+
}
|
|
811
|
+
});
|
|
812
|
+
}
|
|
813
|
+
ensureNotDestroyed() {
|
|
814
|
+
if (this.isDestroyed) {
|
|
815
|
+
throw new types_1.CoordinationError('CoordinationManager has been destroyed', types_1.CoordinationErrorCode.CONNECTION_CLOSED);
|
|
816
|
+
}
|
|
817
|
+
}
|
|
818
|
+
delay(ms) {
|
|
819
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
820
|
+
}
|
|
821
|
+
setupLogging() {
|
|
822
|
+
const noop = () => { };
|
|
823
|
+
if (!this.config.enableLogging) {
|
|
824
|
+
this.log = noop;
|
|
825
|
+
this.logDebug = noop;
|
|
826
|
+
this.logWarn = noop;
|
|
827
|
+
this.logError = noop;
|
|
828
|
+
return;
|
|
829
|
+
}
|
|
830
|
+
const prefix = '[CoordinationManager]';
|
|
831
|
+
this.log = (...args) => console.log(prefix, ...args);
|
|
832
|
+
this.logDebug = this.config.logLevel === 'debug'
|
|
833
|
+
? (...args) => console.debug(prefix, ...args)
|
|
834
|
+
: noop;
|
|
835
|
+
this.logWarn = ['debug', 'info', 'warn'].includes(this.config.logLevel)
|
|
836
|
+
? (...args) => console.warn(prefix, ...args)
|
|
837
|
+
: noop;
|
|
838
|
+
this.logError = (...args) => console.error(prefix, ...args);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
exports.CoordinationManager = CoordinationManager;
|
|
842
|
+
// ============================================
|
|
843
|
+
// Factory Functions
|
|
844
|
+
// ============================================
|
|
845
|
+
/**
|
|
846
|
+
* Create a new CoordinationManager instance
|
|
847
|
+
*/
|
|
848
|
+
function createCoordinationManager(config) {
|
|
849
|
+
return new CoordinationManager(config);
|
|
850
|
+
}
|
|
851
|
+
//# sourceMappingURL=CoordinationManager.js.map
|