claude-mpm 5.1.9__py3-none-any.whl → 5.4.48__py3-none-any.whl

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.

Potentially problematic release.


This version of claude-mpm might be problematic. Click here for more details.

Files changed (248) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +4 -0
  3. claude_mpm/agents/BASE_AGENT.md +164 -0
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +1 -1
  5. claude_mpm/agents/MEMORY.md +1 -1
  6. claude_mpm/agents/PM_INSTRUCTIONS.md +843 -900
  7. claude_mpm/agents/WORKFLOW.md +5 -254
  8. claude_mpm/agents/agent_loader.py +13 -44
  9. claude_mpm/agents/base_agent.json +1 -1
  10. claude_mpm/agents/frontmatter_validator.py +2 -2
  11. claude_mpm/agents/templates/circuit-breakers.md +138 -1
  12. claude_mpm/cli/__main__.py +4 -0
  13. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  14. claude_mpm/cli/commands/agent_state_manager.py +18 -27
  15. claude_mpm/cli/commands/agents.py +9 -40
  16. claude_mpm/cli/commands/auto_configure.py +210 -25
  17. claude_mpm/cli/commands/config.py +88 -2
  18. claude_mpm/cli/commands/configure.py +1098 -159
  19. claude_mpm/cli/commands/configure_agent_display.py +25 -6
  20. claude_mpm/cli/commands/mpm_init/core.py +225 -46
  21. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  22. claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
  23. claude_mpm/cli/commands/postmortem.py +1 -1
  24. claude_mpm/cli/commands/profile.py +277 -0
  25. claude_mpm/cli/commands/skills.py +218 -197
  26. claude_mpm/cli/commands/summarize.py +413 -0
  27. claude_mpm/cli/executor.py +21 -3
  28. claude_mpm/cli/interactive/agent_wizard.py +2 -2
  29. claude_mpm/cli/parsers/agents_parser.py +0 -9
  30. claude_mpm/cli/parsers/auto_configure_parser.py +0 -138
  31. claude_mpm/cli/parsers/base_parser.py +12 -0
  32. claude_mpm/cli/parsers/config_parser.py +153 -83
  33. claude_mpm/cli/parsers/profile_parser.py +148 -0
  34. claude_mpm/cli/parsers/skills_parser.py +0 -5
  35. claude_mpm/cli/startup.py +876 -149
  36. claude_mpm/commands/mpm-config.md +28 -0
  37. claude_mpm/commands/mpm-doctor.md +9 -22
  38. claude_mpm/commands/mpm-help.md +5 -287
  39. claude_mpm/commands/mpm-init.md +81 -507
  40. claude_mpm/commands/mpm-monitor.md +15 -402
  41. claude_mpm/commands/mpm-organize.md +120 -0
  42. claude_mpm/commands/mpm-postmortem.md +6 -108
  43. claude_mpm/commands/mpm-session-resume.md +12 -363
  44. claude_mpm/commands/mpm-status.md +5 -69
  45. claude_mpm/commands/mpm-ticket-view.md +52 -495
  46. claude_mpm/commands/mpm-version.md +5 -107
  47. claude_mpm/config/agent_sources.py +27 -0
  48. claude_mpm/core/config.py +2 -4
  49. claude_mpm/core/framework/formatters/content_formatter.py +3 -13
  50. claude_mpm/core/framework/loaders/agent_loader.py +8 -5
  51. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  52. claude_mpm/core/framework_loader.py +4 -2
  53. claude_mpm/core/logger.py +13 -0
  54. claude_mpm/core/optimized_startup.py +59 -0
  55. claude_mpm/core/shared/config_loader.py +1 -1
  56. claude_mpm/core/socketio_pool.py +3 -3
  57. claude_mpm/core/unified_agent_registry.py +5 -15
  58. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  59. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
  60. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
  61. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
  62. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
  63. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
  64. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
  65. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
  66. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
  67. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
  68. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
  69. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
  70. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
  71. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
  72. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
  73. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  74. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  75. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  76. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  77. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  78. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  79. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  80. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  81. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  82. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  83. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  84. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  85. claude_mpm/hooks/claude_hooks/event_handlers.py +211 -78
  86. claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
  87. claude_mpm/hooks/claude_hooks/installer.py +33 -10
  88. claude_mpm/hooks/claude_hooks/memory_integration.py +26 -9
  89. claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
  90. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  91. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  92. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  93. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  94. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  95. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  96. claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
  97. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  98. claude_mpm/hooks/memory_integration_hook.py +46 -1
  99. claude_mpm/init.py +63 -19
  100. claude_mpm/models/git_repository.py +3 -3
  101. claude_mpm/scripts/claude-hook-handler.sh +58 -18
  102. claude_mpm/scripts/launch_monitor.py +93 -13
  103. claude_mpm/services/agents/agent_builder.py +3 -3
  104. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  105. claude_mpm/services/agents/agent_review_service.py +280 -0
  106. claude_mpm/services/agents/cache_git_manager.py +6 -6
  107. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  108. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -5
  109. claude_mpm/services/agents/deployment/agent_format_converter.py +23 -13
  110. claude_mpm/services/agents/deployment/agent_template_builder.py +32 -20
  111. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  112. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  113. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  114. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +247 -35
  115. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +392 -87
  116. claude_mpm/services/agents/git_source_manager.py +53 -4
  117. claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
  118. claude_mpm/services/agents/recommender.py +5 -3
  119. claude_mpm/services/agents/single_tier_deployment_service.py +2 -2
  120. claude_mpm/services/agents/sources/git_source_sync_service.py +120 -7
  121. claude_mpm/services/agents/startup_sync.py +22 -2
  122. claude_mpm/services/agents/toolchain_detector.py +10 -6
  123. claude_mpm/services/analysis/__init__.py +11 -1
  124. claude_mpm/services/analysis/clone_detector.py +1030 -0
  125. claude_mpm/services/command_deployment_service.py +81 -10
  126. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  127. claude_mpm/services/diagnostics/checks/agent_sources_check.py +1 -1
  128. claude_mpm/services/event_bus/config.py +3 -1
  129. claude_mpm/services/git/git_operations_service.py +101 -16
  130. claude_mpm/services/monitor/daemon.py +9 -2
  131. claude_mpm/services/monitor/daemon_manager.py +39 -3
  132. claude_mpm/services/monitor/management/lifecycle.py +8 -1
  133. claude_mpm/services/monitor/server.py +698 -22
  134. claude_mpm/services/pm_skills_deployer.py +711 -0
  135. claude_mpm/services/profile_manager.py +331 -0
  136. claude_mpm/services/self_upgrade_service.py +120 -12
  137. claude_mpm/services/skills/__init__.py +3 -0
  138. claude_mpm/services/skills/git_skill_source_manager.py +130 -2
  139. claude_mpm/services/skills/selective_skill_deployer.py +704 -0
  140. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  141. claude_mpm/services/skills_deployer.py +127 -9
  142. claude_mpm/services/socketio/dashboard_server.py +1 -0
  143. claude_mpm/services/socketio/event_normalizer.py +51 -6
  144. claude_mpm/services/socketio/server/core.py +386 -108
  145. claude_mpm/services/version_control/git_operations.py +103 -0
  146. claude_mpm/skills/skill_manager.py +92 -3
  147. claude_mpm/utils/agent_dependency_loader.py +14 -2
  148. claude_mpm/utils/agent_filters.py +17 -44
  149. claude_mpm/utils/migration.py +4 -4
  150. claude_mpm/utils/robust_installer.py +47 -3
  151. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.48.dist-info}/METADATA +53 -87
  152. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.48.dist-info}/RECORD +157 -197
  153. claude_mpm-5.4.48.dist-info/entry_points.txt +5 -0
  154. claude_mpm-5.4.48.dist-info/licenses/LICENSE +94 -0
  155. claude_mpm-5.4.48.dist-info/licenses/LICENSE-FAQ.md +153 -0
  156. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
  157. claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
  158. claude_mpm/agents/BASE_OPS.md +0 -219
  159. claude_mpm/agents/BASE_PM.md +0 -480
  160. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
  161. claude_mpm/agents/BASE_QA.md +0 -167
  162. claude_mpm/agents/BASE_RESEARCH.md +0 -53
  163. claude_mpm/agents/base_agent_loader.py +0 -601
  164. claude_mpm/cli/commands/agents_detect.py +0 -380
  165. claude_mpm/cli/commands/agents_recommend.py +0 -309
  166. claude_mpm/cli/ticket_cli.py +0 -35
  167. claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
  168. claude_mpm/commands/mpm-agents-detect.md +0 -177
  169. claude_mpm/commands/mpm-agents-list.md +0 -131
  170. claude_mpm/commands/mpm-agents-recommend.md +0 -223
  171. claude_mpm/commands/mpm-config-view.md +0 -150
  172. claude_mpm/commands/mpm-ticket-organize.md +0 -304
  173. claude_mpm/dashboard/analysis_runner.py +0 -455
  174. claude_mpm/dashboard/index.html +0 -13
  175. claude_mpm/dashboard/open_dashboard.py +0 -66
  176. claude_mpm/dashboard/static/css/activity.css +0 -1958
  177. claude_mpm/dashboard/static/css/connection-status.css +0 -370
  178. claude_mpm/dashboard/static/css/dashboard.css +0 -4701
  179. claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
  180. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
  181. claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
  182. claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
  183. claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
  184. claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
  185. claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
  186. claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
  187. claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
  188. claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
  189. claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
  190. claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
  191. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
  192. claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
  193. claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
  194. claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
  195. claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
  196. claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
  197. claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
  198. claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
  199. claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
  200. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
  201. claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
  202. claude_mpm/dashboard/static/js/connection-manager.js +0 -536
  203. claude_mpm/dashboard/static/js/dashboard.js +0 -1914
  204. claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
  205. claude_mpm/dashboard/static/js/socket-client.js +0 -1474
  206. claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
  207. claude_mpm/dashboard/static/socket.io.min.js +0 -7
  208. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
  209. claude_mpm/dashboard/templates/code_simple.html +0 -153
  210. claude_mpm/dashboard/templates/index.html +0 -606
  211. claude_mpm/dashboard/test_dashboard.html +0 -372
  212. claude_mpm/scripts/mcp_server.py +0 -75
  213. claude_mpm/scripts/mcp_wrapper.py +0 -39
  214. claude_mpm/services/mcp_gateway/__init__.py +0 -159
  215. claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
  216. claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
  217. claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
  218. claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
  219. claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
  220. claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
  221. claude_mpm/services/mcp_gateway/core/base.py +0 -312
  222. claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
  223. claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
  224. claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
  225. claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
  226. claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
  227. claude_mpm/services/mcp_gateway/main.py +0 -589
  228. claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
  229. claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
  230. claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
  231. claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
  232. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
  233. claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
  234. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
  235. claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
  236. claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
  237. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
  238. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
  239. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
  240. claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
  241. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
  242. claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
  243. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
  244. claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
  245. claude_mpm-5.1.9.dist-info/entry_points.txt +0 -10
  246. claude_mpm-5.1.9.dist-info/licenses/LICENSE +0 -21
  247. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.48.dist-info}/WHEEL +0 -0
  248. {claude_mpm-5.1.9.dist-info → claude_mpm-5.4.48.dist-info}/top_level.txt +0 -0
@@ -1,536 +0,0 @@
1
- /**
2
- * Enhanced Connection Manager for Dashboard
3
- *
4
- * Provides robust connection management with:
5
- * - Persistent client ID across reconnections
6
- * - Event sequence tracking and replay
7
- * - Exponential backoff for reconnection
8
- * - Connection health monitoring
9
- * - Visual status indicators
10
- * - Local event buffering
11
- */
12
-
13
- class EnhancedConnectionManager {
14
- constructor(socketClient) {
15
- this.socketClient = socketClient;
16
- this.socket = null;
17
- this.clientId = this.loadClientId();
18
- this.lastSequence = this.loadLastSequence();
19
- this.connectionState = 'disconnected';
20
- this.connectionQuality = 1.0;
21
- this.reconnectAttempts = 0;
22
- this.maxReconnectAttempts = 10;
23
- this.baseReconnectDelay = 1000; // 1 second
24
- this.maxReconnectDelay = 30000; // 30 seconds
25
- this.heartbeatInterval = 30000; // 30 seconds
26
- this.heartbeatTimer = null;
27
- this.pingTimer = null;
28
- this.lastPingTime = null;
29
- this.lastPongTime = null;
30
- this.missedHeartbeats = 0;
31
- this.maxMissedHeartbeats = 3;
32
-
33
- // Event buffering for offline mode
34
- this.eventBuffer = [];
35
- this.maxEventBuffer = 100;
36
-
37
- // Connection metrics
38
- this.metrics = {
39
- connectTime: null,
40
- disconnectTime: null,
41
- totalConnections: 0,
42
- totalReconnections: 0,
43
- totalEvents: 0,
44
- eventsAcked: 0,
45
- lastActivity: null
46
- };
47
-
48
- // Status update callbacks
49
- this.statusCallbacks = new Set();
50
- this.qualityCallbacks = new Set();
51
-
52
- // Initialize
53
- this.setupEventHandlers();
54
- this.startHealthMonitoring();
55
- }
56
-
57
- /**
58
- * Load or generate client ID for persistent identification
59
- */
60
- loadClientId() {
61
- let clientId = localStorage.getItem('claude_mpm_client_id');
62
- if (!clientId) {
63
- clientId = 'client_' + Math.random().toString(36).substr(2, 9);
64
- localStorage.setItem('claude_mpm_client_id', clientId);
65
- }
66
- return clientId;
67
- }
68
-
69
- /**
70
- * Load last received event sequence for replay
71
- */
72
- loadLastSequence() {
73
- const sequence = localStorage.getItem('claude_mpm_last_sequence');
74
- return sequence ? parseInt(sequence, 10) : 0;
75
- }
76
-
77
- /**
78
- * Save last received event sequence
79
- */
80
- saveLastSequence(sequence) {
81
- this.lastSequence = sequence;
82
- localStorage.setItem('claude_mpm_last_sequence', sequence.toString());
83
- }
84
-
85
- /**
86
- * Connect with enhanced options and authentication
87
- */
88
- connect(port = '8765') {
89
- const url = `http://localhost:${port}`;
90
-
91
- console.log(`[ConnectionManager] Connecting to ${url} with client ID: ${this.clientId}`);
92
- this.updateConnectionState('connecting');
93
-
94
- // Create socket with enhanced options
95
- this.socket = io(url, {
96
- auth: {
97
- client_id: this.clientId,
98
- last_sequence: this.lastSequence
99
- },
100
- reconnection: true,
101
- reconnectionDelay: this.calculateReconnectDelay(),
102
- reconnectionDelayMax: this.maxReconnectDelay,
103
- reconnectionAttempts: this.maxReconnectAttempts,
104
- timeout: 20000,
105
- transports: ['websocket', 'polling'],
106
- pingInterval: 25000,
107
- pingTimeout: 20000
108
- });
109
-
110
- this.setupSocketHandlers();
111
- this.socketClient.socket = this.socket;
112
- }
113
-
114
- /**
115
- * Calculate exponential backoff delay for reconnection
116
- */
117
- calculateReconnectDelay() {
118
- const delay = Math.min(
119
- this.baseReconnectDelay * Math.pow(2, this.reconnectAttempts),
120
- this.maxReconnectDelay
121
- );
122
- return delay + Math.random() * 1000; // Add jitter
123
- }
124
-
125
- /**
126
- * Setup socket event handlers
127
- */
128
- setupSocketHandlers() {
129
- if (!this.socket) return;
130
-
131
- // Connection established
132
- this.socket.on('connection_established', (data) => {
133
- console.log('[ConnectionManager] Connection established:', data);
134
- this.clientId = data.client_id;
135
- this.metrics.connectTime = Date.now();
136
- this.metrics.totalConnections++;
137
- this.reconnectAttempts = 0;
138
- this.missedHeartbeats = 0;
139
- this.updateConnectionState('connected');
140
- this.startHeartbeat();
141
-
142
- // Flush buffered events if any
143
- this.flushEventBuffer();
144
- });
145
-
146
- // Event replay after reconnection
147
- this.socket.on('event_replay', (data) => {
148
- console.log(`[ConnectionManager] Replaying ${data.count} events from sequence ${data.from_sequence}`);
149
-
150
- if (data.events && data.events.length > 0) {
151
- data.events.forEach(event => {
152
- // Update sequence
153
- if (event.sequence) {
154
- this.saveLastSequence(event.sequence);
155
- }
156
-
157
- // Process replayed event
158
- this.socketClient.handleEvent('claude_event', event);
159
- });
160
-
161
- this.showNotification(`Replayed ${data.count} missed events`, 'info');
162
- }
163
- });
164
-
165
- // Normal event with sequence tracking
166
- this.socket.on('claude_event', (event) => {
167
- if (event.sequence) {
168
- this.saveLastSequence(event.sequence);
169
-
170
- // Send acknowledgment
171
- this.socket.emit('acknowledge_event', {
172
- sequence: event.sequence
173
- });
174
-
175
- this.metrics.eventsAcked++;
176
- }
177
-
178
- this.metrics.totalEvents++;
179
- this.metrics.lastActivity = Date.now();
180
- });
181
-
182
- // Heartbeat response
183
- this.socket.on('heartbeat_response', (data) => {
184
- this.missedHeartbeats = 0;
185
- this.updateConnectionQuality(1.0);
186
- });
187
-
188
- // Pong response
189
- this.socket.on('pong', (data) => {
190
- this.lastPongTime = Date.now();
191
- const latency = this.lastPongTime - this.lastPingTime;
192
- this.updateLatency(latency);
193
- });
194
-
195
- // Connection stats response
196
- this.socket.on('connection_stats', (data) => {
197
- console.log('[ConnectionManager] Connection stats:', data);
198
- if (data.connection) {
199
- this.updateConnectionQuality(data.connection.quality);
200
- }
201
- });
202
-
203
- // Standard Socket.IO events
204
- this.socket.on('connect', () => {
205
- console.log('[ConnectionManager] Socket connected');
206
- if (this.metrics.disconnectTime) {
207
- const downtime = Date.now() - this.metrics.disconnectTime;
208
- console.log(`[ConnectionManager] Reconnected after ${(downtime / 1000).toFixed(1)}s`);
209
- this.metrics.totalReconnections++;
210
- }
211
- });
212
-
213
- this.socket.on('disconnect', (reason) => {
214
- console.log('[ConnectionManager] Socket disconnected:', reason);
215
- this.metrics.disconnectTime = Date.now();
216
- this.updateConnectionState('disconnected');
217
- this.stopHeartbeat();
218
-
219
- // Handle different disconnect reasons
220
- if (reason === 'io server disconnect') {
221
- // Server initiated disconnect
222
- this.showNotification('Server disconnected the connection', 'warning');
223
- } else if (reason === 'ping timeout') {
224
- // Connection timeout
225
- this.showNotification('Connection timeout - attempting to reconnect', 'warning');
226
- }
227
- });
228
-
229
- this.socket.on('connect_error', (error) => {
230
- console.error('[ConnectionManager] Connection error:', error.message);
231
- this.reconnectAttempts++;
232
-
233
- if (this.reconnectAttempts >= this.maxReconnectAttempts) {
234
- this.updateConnectionState('failed');
235
- this.showNotification('Failed to connect after multiple attempts', 'error');
236
- } else {
237
- const delay = this.calculateReconnectDelay();
238
- this.showNotification(
239
- `Connection failed, retrying in ${(delay / 1000).toFixed(1)}s...`,
240
- 'warning'
241
- );
242
- }
243
- });
244
-
245
- this.socket.on('reconnect', (attemptNumber) => {
246
- console.log(`[ConnectionManager] Reconnected after ${attemptNumber} attempts`);
247
- this.showNotification('Reconnected successfully', 'success');
248
-
249
- // Request event replay
250
- this.socket.emit('request_replay', {
251
- last_sequence: this.lastSequence
252
- });
253
- });
254
-
255
- this.socket.on('reconnect_attempt', (attemptNumber) => {
256
- console.log(`[ConnectionManager] Reconnection attempt ${attemptNumber}`);
257
- this.updateConnectionState('reconnecting');
258
- });
259
- }
260
-
261
- /**
262
- * Start heartbeat monitoring
263
- */
264
- startHeartbeat() {
265
- this.stopHeartbeat();
266
-
267
- this.heartbeatTimer = setInterval(() => {
268
- if (this.socket && this.socket.connected) {
269
- this.socket.emit('heartbeat');
270
- this.missedHeartbeats++;
271
-
272
- if (this.missedHeartbeats >= this.maxMissedHeartbeats) {
273
- console.warn('[ConnectionManager] Too many missed heartbeats, connection may be stale');
274
- this.updateConnectionQuality(0.3);
275
- this.updateConnectionState('stale');
276
- }
277
- }
278
- }, this.heartbeatInterval);
279
-
280
- // Also start ping monitoring for latency
281
- this.pingTimer = setInterval(() => {
282
- if (this.socket && this.socket.connected) {
283
- this.lastPingTime = Date.now();
284
- this.socket.emit('ping');
285
- }
286
- }, 10000); // Every 10 seconds
287
- }
288
-
289
- /**
290
- * Stop heartbeat monitoring
291
- */
292
- stopHeartbeat() {
293
- if (this.heartbeatTimer) {
294
- clearInterval(this.heartbeatTimer);
295
- this.heartbeatTimer = null;
296
- }
297
-
298
- if (this.pingTimer) {
299
- clearInterval(this.pingTimer);
300
- this.pingTimer = null;
301
- }
302
- }
303
-
304
- /**
305
- * Start health monitoring
306
- */
307
- startHealthMonitoring() {
308
- // Periodic connection stats request
309
- setInterval(() => {
310
- if (this.socket && this.socket.connected) {
311
- this.socket.emit('get_connection_stats');
312
- }
313
- }, 60000); // Every minute
314
-
315
- // Activity timeout detection
316
- setInterval(() => {
317
- if (this.connectionState === 'connected' && this.metrics.lastActivity) {
318
- const timeSinceActivity = Date.now() - this.metrics.lastActivity;
319
- if (timeSinceActivity > 120000) { // 2 minutes
320
- console.warn('[ConnectionManager] No activity for 2 minutes');
321
- this.updateConnectionQuality(0.5);
322
- }
323
- }
324
- }, 30000); // Check every 30 seconds
325
- }
326
-
327
- /**
328
- * Update connection state and notify listeners
329
- */
330
- updateConnectionState(state) {
331
- const previousState = this.connectionState;
332
- this.connectionState = state;
333
-
334
- if (previousState !== state) {
335
- console.log(`[ConnectionManager] State change: ${previousState} -> ${state}`);
336
-
337
- // Update UI
338
- this.updateConnectionUI(state);
339
-
340
- // Notify callbacks
341
- this.statusCallbacks.forEach(callback => {
342
- try {
343
- callback(state, previousState);
344
- } catch (error) {
345
- console.error('Error in status callback:', error);
346
- }
347
- });
348
- }
349
- }
350
-
351
- /**
352
- * Update connection quality score
353
- */
354
- updateConnectionQuality(quality) {
355
- this.connectionQuality = Math.max(0, Math.min(1, quality));
356
-
357
- // Notify callbacks
358
- this.qualityCallbacks.forEach(callback => {
359
- try {
360
- callback(this.connectionQuality);
361
- } catch (error) {
362
- console.error('Error in quality callback:', error);
363
- }
364
- });
365
-
366
- // Update UI indicator
367
- this.updateQualityUI(this.connectionQuality);
368
- }
369
-
370
- /**
371
- * Update latency display
372
- */
373
- updateLatency(latency) {
374
- const latencyElement = document.getElementById('connection-latency');
375
- if (latencyElement) {
376
- latencyElement.textContent = `${latency}ms`;
377
-
378
- // Color code based on latency
379
- if (latency < 50) {
380
- latencyElement.className = 'latency-good';
381
- } else if (latency < 150) {
382
- latencyElement.className = 'latency-moderate';
383
- } else {
384
- latencyElement.className = 'latency-poor';
385
- }
386
- }
387
- }
388
-
389
- /**
390
- * Update connection UI based on state
391
- */
392
- updateConnectionUI(state) {
393
- const statusElement = document.getElementById('connection-status');
394
- if (!statusElement) return;
395
-
396
- const stateConfig = {
397
- 'connecting': { text: 'Connecting...', class: 'status-connecting', icon: '⟳' },
398
- 'connected': { text: 'Connected', class: 'status-connected', icon: '●' },
399
- 'reconnecting': { text: 'Reconnecting...', class: 'status-reconnecting', icon: '⟳' },
400
- 'disconnected': { text: 'Disconnected', class: 'status-disconnected', icon: '●' },
401
- 'stale': { text: 'Connection Stale', class: 'status-stale', icon: '⚠' },
402
- 'failed': { text: 'Connection Failed', class: 'status-failed', icon: '✕' }
403
- };
404
-
405
- const config = stateConfig[state] || stateConfig['disconnected'];
406
- statusElement.innerHTML = `<span>${config.icon}</span> ${config.text}`;
407
- statusElement.className = `status-badge ${config.class}`;
408
- }
409
-
410
- /**
411
- * Update connection quality UI
412
- */
413
- updateQualityUI(quality) {
414
- const qualityElement = document.getElementById('connection-quality');
415
- if (!qualityElement) return;
416
-
417
- const percentage = Math.round(quality * 100);
418
- let qualityClass = 'quality-good';
419
- let qualityText = 'Excellent';
420
-
421
- if (quality < 0.3) {
422
- qualityClass = 'quality-poor';
423
- qualityText = 'Poor';
424
- } else if (quality < 0.7) {
425
- qualityClass = 'quality-moderate';
426
- qualityText = 'Fair';
427
- }
428
-
429
- qualityElement.innerHTML = `
430
- <div class="quality-bar ${qualityClass}">
431
- <div class="quality-fill" style="width: ${percentage}%"></div>
432
- </div>
433
- <span class="quality-text">${qualityText} (${percentage}%)</span>
434
- `;
435
- }
436
-
437
- /**
438
- * Buffer events when disconnected
439
- */
440
- bufferEvent(event) {
441
- if (this.eventBuffer.length >= this.maxEventBuffer) {
442
- this.eventBuffer.shift(); // Remove oldest
443
- }
444
-
445
- this.eventBuffer.push({
446
- ...event,
447
- buffered_at: Date.now()
448
- });
449
-
450
- // Save to localStorage for persistence
451
- localStorage.setItem('claude_mpm_event_buffer', JSON.stringify(this.eventBuffer));
452
- }
453
-
454
- /**
455
- * Flush buffered events after reconnection
456
- */
457
- flushEventBuffer() {
458
- if (this.eventBuffer.length === 0) return;
459
-
460
- console.log(`[ConnectionManager] Flushing ${this.eventBuffer.length} buffered events`);
461
-
462
- // Process buffered events
463
- this.eventBuffer.forEach(event => {
464
- this.socketClient.handleEvent('claude_event', event);
465
- });
466
-
467
- // Clear buffer
468
- this.eventBuffer = [];
469
- localStorage.removeItem('claude_mpm_event_buffer');
470
- }
471
-
472
- /**
473
- * Show notification to user
474
- */
475
- showNotification(message, type = 'info') {
476
- const notificationArea = document.getElementById('connection-notifications');
477
- if (!notificationArea) return;
478
-
479
- const notification = document.createElement('div');
480
- notification.className = `notification notification-${type}`;
481
- notification.textContent = message;
482
-
483
- notificationArea.appendChild(notification);
484
-
485
- // Auto-remove after 5 seconds
486
- setTimeout(() => {
487
- notification.style.opacity = '0';
488
- setTimeout(() => notification.remove(), 300);
489
- }, 5000);
490
- }
491
-
492
- /**
493
- * Register status change callback
494
- */
495
- onStatusChange(callback) {
496
- this.statusCallbacks.add(callback);
497
- }
498
-
499
- /**
500
- * Register quality change callback
501
- */
502
- onQualityChange(callback) {
503
- this.qualityCallbacks.add(callback);
504
- }
505
-
506
- /**
507
- * Get connection metrics
508
- */
509
- getMetrics() {
510
- return {
511
- ...this.metrics,
512
- connectionState: this.connectionState,
513
- connectionQuality: this.connectionQuality,
514
- clientId: this.clientId,
515
- lastSequence: this.lastSequence,
516
- bufferedEvents: this.eventBuffer.length
517
- };
518
- }
519
-
520
- /**
521
- * Disconnect and cleanup
522
- */
523
- disconnect() {
524
- this.stopHeartbeat();
525
-
526
- if (this.socket) {
527
- this.socket.disconnect();
528
- this.socket = null;
529
- }
530
-
531
- this.updateConnectionState('disconnected');
532
- }
533
- }
534
-
535
- // Export for use in other modules
536
- export { EnhancedConnectionManager };