claude-mpm 5.0.9__py3-none-any.whl → 5.6.23__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 (614) 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_OUTPUT_STYLE.md +115 -0
  5. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  6. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +186 -0
  7. claude_mpm/agents/MEMORY.md +1 -1
  8. claude_mpm/agents/PM_INSTRUCTIONS.md +479 -616
  9. claude_mpm/agents/WORKFLOW.md +6 -253
  10. claude_mpm/agents/agent_loader.py +13 -44
  11. claude_mpm/agents/base_agent.json +1 -1
  12. claude_mpm/agents/frontmatter_validator.py +70 -2
  13. claude_mpm/agents/templates/circuit-breakers.md +457 -62
  14. claude_mpm/cli/__init__.py +5 -2
  15. claude_mpm/cli/__main__.py +4 -0
  16. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  17. claude_mpm/cli/commands/agent_state_manager.py +18 -27
  18. claude_mpm/cli/commands/agents.py +177 -41
  19. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  20. claude_mpm/cli/commands/auto_configure.py +723 -236
  21. claude_mpm/cli/commands/autotodos.py +566 -0
  22. claude_mpm/cli/commands/commander.py +216 -0
  23. claude_mpm/cli/commands/config.py +88 -2
  24. claude_mpm/cli/commands/configure.py +1874 -170
  25. claude_mpm/cli/commands/configure_agent_display.py +27 -6
  26. claude_mpm/cli/commands/hook_errors.py +60 -60
  27. claude_mpm/cli/commands/monitor.py +2 -2
  28. claude_mpm/cli/commands/mpm_init/core.py +232 -46
  29. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  30. claude_mpm/cli/commands/mpm_init/prompts.py +280 -0
  31. claude_mpm/cli/commands/postmortem.py +1 -1
  32. claude_mpm/cli/commands/profile.py +276 -0
  33. claude_mpm/cli/commands/run.py +35 -3
  34. claude_mpm/cli/commands/skill_source.py +51 -2
  35. claude_mpm/cli/commands/skills.py +379 -204
  36. claude_mpm/cli/commands/summarize.py +413 -0
  37. claude_mpm/cli/executor.py +141 -19
  38. claude_mpm/cli/interactive/__init__.py +10 -0
  39. claude_mpm/cli/interactive/agent_wizard.py +115 -60
  40. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  41. claude_mpm/cli/interactive/skill_selector.py +481 -0
  42. claude_mpm/cli/parsers/agents_parser.py +54 -9
  43. claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
  44. claude_mpm/cli/parsers/base_parser.py +88 -1
  45. claude_mpm/cli/parsers/commander_parser.py +116 -0
  46. claude_mpm/cli/parsers/config_parser.py +153 -83
  47. claude_mpm/cli/parsers/profile_parser.py +147 -0
  48. claude_mpm/cli/parsers/run_parser.py +10 -0
  49. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  50. claude_mpm/cli/parsers/skills_parser.py +1 -1
  51. claude_mpm/cli/startup.py +1017 -266
  52. claude_mpm/cli/startup_display.py +74 -6
  53. claude_mpm/cli/startup_logging.py +2 -2
  54. claude_mpm/cli/utils.py +7 -3
  55. claude_mpm/commander/__init__.py +78 -0
  56. claude_mpm/commander/adapters/__init__.py +60 -0
  57. claude_mpm/commander/adapters/auggie.py +260 -0
  58. claude_mpm/commander/adapters/base.py +288 -0
  59. claude_mpm/commander/adapters/claude_code.py +392 -0
  60. claude_mpm/commander/adapters/codex.py +237 -0
  61. claude_mpm/commander/adapters/communication.py +366 -0
  62. claude_mpm/commander/adapters/example_usage.py +310 -0
  63. claude_mpm/commander/adapters/mpm.py +389 -0
  64. claude_mpm/commander/adapters/registry.py +204 -0
  65. claude_mpm/commander/api/__init__.py +16 -0
  66. claude_mpm/commander/api/app.py +121 -0
  67. claude_mpm/commander/api/errors.py +133 -0
  68. claude_mpm/commander/api/routes/__init__.py +8 -0
  69. claude_mpm/commander/api/routes/events.py +184 -0
  70. claude_mpm/commander/api/routes/inbox.py +171 -0
  71. claude_mpm/commander/api/routes/messages.py +148 -0
  72. claude_mpm/commander/api/routes/projects.py +271 -0
  73. claude_mpm/commander/api/routes/sessions.py +226 -0
  74. claude_mpm/commander/api/routes/work.py +296 -0
  75. claude_mpm/commander/api/schemas.py +186 -0
  76. claude_mpm/commander/chat/__init__.py +7 -0
  77. claude_mpm/commander/chat/cli.py +146 -0
  78. claude_mpm/commander/chat/commands.py +96 -0
  79. claude_mpm/commander/chat/repl.py +310 -0
  80. claude_mpm/commander/config.py +51 -0
  81. claude_mpm/commander/config_loader.py +115 -0
  82. claude_mpm/commander/core/__init__.py +10 -0
  83. claude_mpm/commander/core/block_manager.py +325 -0
  84. claude_mpm/commander/core/response_manager.py +323 -0
  85. claude_mpm/commander/daemon.py +603 -0
  86. claude_mpm/commander/env_loader.py +59 -0
  87. claude_mpm/commander/events/__init__.py +26 -0
  88. claude_mpm/commander/events/manager.py +332 -0
  89. claude_mpm/commander/frameworks/__init__.py +12 -0
  90. claude_mpm/commander/frameworks/base.py +146 -0
  91. claude_mpm/commander/frameworks/claude_code.py +58 -0
  92. claude_mpm/commander/frameworks/mpm.py +62 -0
  93. claude_mpm/commander/inbox/__init__.py +16 -0
  94. claude_mpm/commander/inbox/dedup.py +128 -0
  95. claude_mpm/commander/inbox/inbox.py +224 -0
  96. claude_mpm/commander/inbox/models.py +70 -0
  97. claude_mpm/commander/instance_manager.py +450 -0
  98. claude_mpm/commander/llm/__init__.py +6 -0
  99. claude_mpm/commander/llm/openrouter_client.py +167 -0
  100. claude_mpm/commander/llm/summarizer.py +70 -0
  101. claude_mpm/commander/memory/__init__.py +45 -0
  102. claude_mpm/commander/memory/compression.py +347 -0
  103. claude_mpm/commander/memory/embeddings.py +230 -0
  104. claude_mpm/commander/memory/entities.py +310 -0
  105. claude_mpm/commander/memory/example_usage.py +290 -0
  106. claude_mpm/commander/memory/integration.py +325 -0
  107. claude_mpm/commander/memory/search.py +381 -0
  108. claude_mpm/commander/memory/store.py +657 -0
  109. claude_mpm/commander/models/__init__.py +18 -0
  110. claude_mpm/commander/models/events.py +121 -0
  111. claude_mpm/commander/models/project.py +162 -0
  112. claude_mpm/commander/models/work.py +214 -0
  113. claude_mpm/commander/parsing/__init__.py +20 -0
  114. claude_mpm/commander/parsing/extractor.py +132 -0
  115. claude_mpm/commander/parsing/output_parser.py +270 -0
  116. claude_mpm/commander/parsing/patterns.py +100 -0
  117. claude_mpm/commander/persistence/__init__.py +11 -0
  118. claude_mpm/commander/persistence/event_store.py +274 -0
  119. claude_mpm/commander/persistence/state_store.py +309 -0
  120. claude_mpm/commander/persistence/work_store.py +164 -0
  121. claude_mpm/commander/polling/__init__.py +13 -0
  122. claude_mpm/commander/polling/event_detector.py +104 -0
  123. claude_mpm/commander/polling/output_buffer.py +49 -0
  124. claude_mpm/commander/polling/output_poller.py +153 -0
  125. claude_mpm/commander/project_session.py +268 -0
  126. claude_mpm/commander/proxy/__init__.py +12 -0
  127. claude_mpm/commander/proxy/formatter.py +89 -0
  128. claude_mpm/commander/proxy/output_handler.py +191 -0
  129. claude_mpm/commander/proxy/relay.py +155 -0
  130. claude_mpm/commander/registry.py +410 -0
  131. claude_mpm/commander/runtime/__init__.py +10 -0
  132. claude_mpm/commander/runtime/executor.py +191 -0
  133. claude_mpm/commander/runtime/monitor.py +346 -0
  134. claude_mpm/commander/session/__init__.py +6 -0
  135. claude_mpm/commander/session/context.py +81 -0
  136. claude_mpm/commander/session/manager.py +59 -0
  137. claude_mpm/commander/tmux_orchestrator.py +361 -0
  138. claude_mpm/commander/web/__init__.py +1 -0
  139. claude_mpm/commander/work/__init__.py +30 -0
  140. claude_mpm/commander/work/executor.py +207 -0
  141. claude_mpm/commander/work/queue.py +405 -0
  142. claude_mpm/commander/workflow/__init__.py +27 -0
  143. claude_mpm/commander/workflow/event_handler.py +241 -0
  144. claude_mpm/commander/workflow/notifier.py +146 -0
  145. claude_mpm/commands/mpm-config.md +36 -0
  146. claude_mpm/commands/mpm-doctor.md +16 -21
  147. claude_mpm/commands/mpm-help.md +12 -286
  148. claude_mpm/commands/mpm-init.md +88 -506
  149. claude_mpm/commands/mpm-monitor.md +22 -401
  150. claude_mpm/commands/mpm-organize.md +128 -0
  151. claude_mpm/commands/mpm-postmortem.md +13 -107
  152. claude_mpm/commands/mpm-session-resume.md +20 -363
  153. claude_mpm/commands/mpm-status.md +13 -69
  154. claude_mpm/commands/mpm-ticket-view.md +60 -495
  155. claude_mpm/commands/mpm-version.md +13 -107
  156. claude_mpm/commands/mpm.md +8 -0
  157. claude_mpm/config/agent_presets.py +8 -7
  158. claude_mpm/config/agent_sources.py +27 -0
  159. claude_mpm/config/skill_sources.py +16 -0
  160. claude_mpm/constants.py +1 -0
  161. claude_mpm/core/claude_runner.py +154 -2
  162. claude_mpm/core/config.py +37 -26
  163. claude_mpm/core/config_constants.py +74 -9
  164. claude_mpm/core/constants.py +56 -12
  165. claude_mpm/core/framework/formatters/content_formatter.py +3 -13
  166. claude_mpm/core/framework/loaders/agent_loader.py +8 -5
  167. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  168. claude_mpm/core/framework_loader.py +4 -2
  169. claude_mpm/core/hook_manager.py +51 -3
  170. claude_mpm/core/interactive_session.py +12 -11
  171. claude_mpm/core/logger.py +39 -9
  172. claude_mpm/core/logging_utils.py +35 -11
  173. claude_mpm/core/network_config.py +148 -0
  174. claude_mpm/core/oneshot_session.py +7 -6
  175. claude_mpm/core/optimized_startup.py +61 -0
  176. claude_mpm/core/output_style_manager.py +219 -44
  177. claude_mpm/core/shared/config_loader.py +3 -1
  178. claude_mpm/core/socketio_pool.py +16 -8
  179. claude_mpm/core/unified_agent_registry.py +134 -16
  180. claude_mpm/core/unified_config.py +76 -8
  181. claude_mpm/core/unified_paths.py +95 -90
  182. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DR8nis88.js +2 -0
  223. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  224. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  225. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  226. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  227. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  228. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  229. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  230. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  231. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  232. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  233. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  234. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  235. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  236. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  237. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  238. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  239. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  240. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  241. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  242. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  243. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  244. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.RgBboRvH.js +1 -0
  245. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  246. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  247. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  248. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  249. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  250. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  251. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  252. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  253. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  254. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  255. claude_mpm/experimental/cli_enhancements.py +2 -1
  256. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  257. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  258. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  259. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  260. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  261. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  262. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  263. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  264. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  265. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  266. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  267. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  268. claude_mpm/hooks/claude_hooks/event_handlers.py +479 -128
  269. claude_mpm/hooks/claude_hooks/hook_handler.py +254 -83
  270. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  271. claude_mpm/hooks/claude_hooks/installer.py +149 -18
  272. claude_mpm/hooks/claude_hooks/memory_integration.py +67 -19
  273. claude_mpm/hooks/claude_hooks/response_tracking.py +44 -62
  274. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  275. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  276. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  277. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  278. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  279. claude_mpm/hooks/claude_hooks/services/connection_manager.py +69 -30
  280. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
  281. claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
  282. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +73 -75
  283. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  284. claude_mpm/hooks/memory_integration_hook.py +46 -1
  285. claude_mpm/hooks/session_resume_hook.py +89 -1
  286. claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
  287. claude_mpm/init.py +276 -19
  288. claude_mpm/models/agent_definition.py +7 -0
  289. claude_mpm/models/git_repository.py +3 -3
  290. claude_mpm/scripts/claude-hook-handler.sh +87 -20
  291. claude_mpm/scripts/launch_monitor.py +93 -13
  292. claude_mpm/scripts/start_activity_logging.py +0 -0
  293. claude_mpm/services/agents/agent_builder.py +3 -3
  294. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  295. claude_mpm/services/agents/agent_review_service.py +280 -0
  296. claude_mpm/services/agents/agent_selection_service.py +2 -2
  297. claude_mpm/services/agents/cache_git_manager.py +7 -7
  298. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  299. claude_mpm/services/agents/deployment/agent_discovery_service.py +6 -5
  300. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  301. claude_mpm/services/agents/deployment/agent_template_builder.py +42 -20
  302. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  303. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  304. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  305. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  306. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +348 -29
  307. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +570 -68
  308. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  309. claude_mpm/services/agents/git_source_manager.py +57 -4
  310. claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
  311. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  312. claude_mpm/services/agents/recommender.py +5 -3
  313. claude_mpm/services/agents/single_tier_deployment_service.py +6 -6
  314. claude_mpm/services/agents/sources/git_source_sync_service.py +129 -11
  315. claude_mpm/services/agents/startup_sync.py +27 -4
  316. claude_mpm/services/agents/toolchain_detector.py +10 -6
  317. claude_mpm/services/analysis/__init__.py +11 -1
  318. claude_mpm/services/analysis/clone_detector.py +1030 -0
  319. claude_mpm/services/cli/__init__.py +3 -0
  320. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  321. claude_mpm/services/cli/session_resume_helper.py +10 -2
  322. claude_mpm/services/command_deployment_service.py +81 -10
  323. claude_mpm/services/delegation_detector.py +175 -0
  324. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  325. claude_mpm/services/diagnostics/checks/agent_sources_check.py +31 -1
  326. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  327. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  328. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  329. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  330. claude_mpm/services/diagnostics/models.py +14 -1
  331. claude_mpm/services/event_bus/config.py +3 -1
  332. claude_mpm/services/event_log.py +325 -0
  333. claude_mpm/services/git/git_operations_service.py +101 -16
  334. claude_mpm/services/infrastructure/__init__.py +4 -0
  335. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  336. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  337. claude_mpm/services/monitor/daemon.py +9 -2
  338. claude_mpm/services/monitor/daemon_manager.py +54 -7
  339. claude_mpm/services/monitor/management/lifecycle.py +15 -3
  340. claude_mpm/services/monitor/server.py +796 -30
  341. claude_mpm/services/pm_skills_deployer.py +884 -0
  342. claude_mpm/services/profile_manager.py +337 -0
  343. claude_mpm/services/project/project_organizer.py +4 -0
  344. claude_mpm/services/self_upgrade_service.py +120 -12
  345. claude_mpm/services/skills/__init__.py +3 -0
  346. claude_mpm/services/skills/git_skill_source_manager.py +303 -12
  347. claude_mpm/services/skills/selective_skill_deployer.py +869 -0
  348. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  349. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  350. claude_mpm/services/skills_deployer.py +294 -55
  351. claude_mpm/services/socketio/dashboard_server.py +1 -0
  352. claude_mpm/services/socketio/event_normalizer.py +51 -6
  353. claude_mpm/services/socketio/handlers/hook.py +14 -7
  354. claude_mpm/services/socketio/server/core.py +386 -108
  355. claude_mpm/services/socketio/server/main.py +12 -4
  356. claude_mpm/services/version_control/git_operations.py +103 -0
  357. claude_mpm/skills/__init__.py +2 -1
  358. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  359. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  360. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  361. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  362. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  363. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  364. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  365. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  366. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  367. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  368. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  369. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  370. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  371. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  372. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  373. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  374. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  375. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  376. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  377. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  378. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  379. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  380. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  381. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  382. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  383. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  384. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  385. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  386. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  387. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  388. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  389. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  390. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  391. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  392. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  393. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  394. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  395. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  396. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  397. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  398. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  399. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  400. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  401. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  402. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  403. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  404. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  405. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  406. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  407. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  408. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  409. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  410. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  411. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  412. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  413. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  414. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  415. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  416. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  417. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  418. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  419. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  420. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  421. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  422. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  423. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  424. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  425. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  426. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  427. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  428. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  429. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  430. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  431. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  432. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  433. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  434. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  435. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  436. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  437. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  438. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  439. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  440. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  441. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  442. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  443. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  444. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  445. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  446. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  447. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  448. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  449. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  450. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  451. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  452. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  453. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  454. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  455. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  456. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  457. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  458. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  459. claude_mpm/skills/bundled/security-scanning.md +112 -0
  460. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  461. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  462. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  463. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  464. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  465. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  466. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  467. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  468. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  469. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  470. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  471. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  472. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  473. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  474. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  475. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  476. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  477. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  478. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  479. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  480. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  481. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  482. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  483. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  484. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  485. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  486. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  487. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  488. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  489. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  490. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  491. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  492. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  493. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  494. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  495. claude_mpm/skills/registry.py +295 -90
  496. claude_mpm/skills/skill_manager.py +98 -3
  497. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  498. claude_mpm/utils/agent_dependency_loader.py +115 -4
  499. claude_mpm/utils/agent_filters.py +17 -44
  500. claude_mpm/utils/gitignore.py +3 -0
  501. claude_mpm/utils/migration.py +4 -4
  502. claude_mpm/utils/robust_installer.py +86 -21
  503. claude_mpm-5.6.23.dist-info/METADATA +393 -0
  504. {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/RECORD +508 -261
  505. claude_mpm-5.6.23.dist-info/entry_points.txt +5 -0
  506. claude_mpm-5.6.23.dist-info/licenses/LICENSE +94 -0
  507. claude_mpm-5.6.23.dist-info/licenses/LICENSE-FAQ.md +153 -0
  508. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
  509. claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
  510. claude_mpm/agents/BASE_OPS.md +0 -219
  511. claude_mpm/agents/BASE_PM.md +0 -480
  512. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
  513. claude_mpm/agents/BASE_QA.md +0 -167
  514. claude_mpm/agents/BASE_RESEARCH.md +0 -53
  515. claude_mpm/agents/OUTPUT_STYLE.md +0 -290
  516. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +0 -1322
  517. claude_mpm/agents/base_agent_loader.py +0 -601
  518. claude_mpm/cli/commands/agents_detect.py +0 -380
  519. claude_mpm/cli/commands/agents_recommend.py +0 -309
  520. claude_mpm/cli/ticket_cli.py +0 -35
  521. claude_mpm/commands/mpm-agents-auto-configure.md +0 -278
  522. claude_mpm/commands/mpm-agents-detect.md +0 -177
  523. claude_mpm/commands/mpm-agents-list.md +0 -131
  524. claude_mpm/commands/mpm-agents-recommend.md +0 -223
  525. claude_mpm/commands/mpm-config-view.md +0 -150
  526. claude_mpm/commands/mpm-ticket-organize.md +0 -304
  527. claude_mpm/dashboard/analysis_runner.py +0 -455
  528. claude_mpm/dashboard/index.html +0 -13
  529. claude_mpm/dashboard/open_dashboard.py +0 -66
  530. claude_mpm/dashboard/static/css/activity.css +0 -1958
  531. claude_mpm/dashboard/static/css/connection-status.css +0 -370
  532. claude_mpm/dashboard/static/css/dashboard.css +0 -4701
  533. claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
  534. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
  535. claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
  536. claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
  537. claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
  538. claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
  539. claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
  540. claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
  541. claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
  542. claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
  543. claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
  544. claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
  545. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
  546. claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
  547. claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
  548. claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
  549. claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
  550. claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
  551. claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
  552. claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
  553. claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
  554. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
  555. claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
  556. claude_mpm/dashboard/static/js/connection-manager.js +0 -536
  557. claude_mpm/dashboard/static/js/dashboard.js +0 -1914
  558. claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
  559. claude_mpm/dashboard/static/js/socket-client.js +0 -1474
  560. claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
  561. claude_mpm/dashboard/static/socket.io.min.js +0 -7
  562. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
  563. claude_mpm/dashboard/templates/code_simple.html +0 -153
  564. claude_mpm/dashboard/templates/index.html +0 -606
  565. claude_mpm/dashboard/test_dashboard.html +0 -372
  566. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  567. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  568. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  569. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  570. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  571. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  572. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  573. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  574. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  575. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  576. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  577. claude_mpm/scripts/mcp_server.py +0 -75
  578. claude_mpm/scripts/mcp_wrapper.py +0 -39
  579. claude_mpm/services/mcp_gateway/__init__.py +0 -159
  580. claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
  581. claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
  582. claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
  583. claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
  584. claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
  585. claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
  586. claude_mpm/services/mcp_gateway/core/base.py +0 -312
  587. claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
  588. claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
  589. claude_mpm/services/mcp_gateway/core/process_pool.py +0 -977
  590. claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
  591. claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
  592. claude_mpm/services/mcp_gateway/main.py +0 -589
  593. claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
  594. claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
  595. claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
  596. claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
  597. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -414
  598. claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
  599. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -712
  600. claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
  601. claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
  602. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
  603. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
  604. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
  605. claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
  606. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -555
  607. claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
  608. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
  609. claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
  610. claude_mpm-5.0.9.dist-info/METADATA +0 -1028
  611. claude_mpm-5.0.9.dist-info/entry_points.txt +0 -10
  612. claude_mpm-5.0.9.dist-info/licenses/LICENSE +0 -21
  613. {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/WHEEL +0 -0
  614. {claude_mpm-5.0.9.dist-info → claude_mpm-5.6.23.dist-info}/top_level.txt +0 -0
@@ -1,1914 +0,0 @@
1
- /**
2
- * Refactored Dashboard Coordinator
3
- *
4
- * Main coordinator class that orchestrates all dashboard modules while maintaining
5
- * backward compatibility with the original dashboard interface.
6
- *
7
- * WHY: This refactored version breaks down the monolithic 4,133-line dashboard
8
- * into manageable, focused modules while preserving all existing functionality.
9
- * Each module handles a specific concern, improving maintainability and testability.
10
- *
11
- * DESIGN DECISION: Acts as a thin coordinator layer that initializes modules,
12
- * manages inter-module communication through events, and provides backward
13
- * compatibility for existing code that depends on the dashboard interface.
14
- */
15
-
16
- // NOTE: Components are loaded as ES6 modules via index.html
17
- // They expose their classes globally for backward compatibility
18
- // Commenting out ES6 imports to avoid module resolution errors
19
-
20
- // import { SocketManager } from './components/socket-manager.js';
21
- // import { EventViewer } from './components/event-viewer.js';
22
- // import { ModuleViewer } from './components/module-viewer.js';
23
- // import { SessionManager } from './components/session-manager.js';
24
- // import { AgentInference } from './components/agent-inference.js';
25
- // import { AgentHierarchy } from './components/agent-hierarchy.js';
26
- // import { UIStateManager } from './components/ui-state-manager.js';
27
- // import { EventProcessor } from './components/event-processor.js';
28
- // import { ExportManager } from './components/export-manager.js';
29
- // import { WorkingDirectoryManager } from './components/working-directory.js';
30
- // import { FileToolTracker } from './components/file-tool-tracker.js';
31
- // import { BuildTracker } from './components/build-tracker.js';
32
- // import { UnifiedDataViewer } from './components/unified-data-viewer.js';
33
-
34
- class Dashboard {
35
- constructor() {
36
- // Core components (existing)
37
- this.eventViewer = null;
38
- this.moduleViewer = null;
39
- this.sessionManager = null;
40
-
41
- // Retry prevention
42
- this.activityTreeRetryCount = 0;
43
- this.maxRetryAttempts = 10;
44
-
45
- // New modular components
46
- this.socketManager = null;
47
- this.agentInference = null;
48
- this.agentHierarchy = null;
49
- this.uiStateManager = null;
50
- this.eventProcessor = null;
51
- this.exportManager = null;
52
- this.workingDirectoryManager = null;
53
- this.fileToolTracker = null;
54
- this.buildTracker = null;
55
-
56
- // Initialize the dashboard
57
- this.init();
58
- }
59
-
60
- /**
61
- * Initialize the dashboard and all modules
62
- */
63
- init() {
64
- console.log('Initializing refactored Claude MPM Dashboard...');
65
-
66
- try {
67
- // Fetch server configuration first
68
- this.fetchServerConfig();
69
-
70
- // Initialize modules in dependency order
71
- this.initializeSocketManager();
72
- this.initializeCoreComponents();
73
- this.initializeBuildTracker();
74
- this.initializeAgentInference();
75
- this.initializeAgentHierarchy();
76
- this.initializeUIStateManager();
77
- this.initializeWorkingDirectoryManager();
78
- this.initializeFileToolTracker();
79
- this.initializeEventProcessor();
80
- this.initializeExportManager();
81
-
82
- // Set up inter-module communication
83
- this.setupModuleInteractions();
84
-
85
- // Initialize from URL parameters
86
- this.initializeFromURL();
87
-
88
- // FIX: Render current tab after initialization to display any existing data
89
- // WHY: If events were loaded before dashboard init completed, they won't be visible
90
- console.log('[Dashboard] Initial render after dashboard initialization');
91
- this.renderCurrentTab();
92
-
93
- console.log('Claude MPM Dashboard initialized successfully');
94
- } catch (error) {
95
- console.error('Error during dashboard initialization:', error);
96
- // Re-throw to be caught by DOMContentLoaded handler
97
- throw error;
98
- }
99
- }
100
-
101
- /**
102
- * Fetch server configuration for dashboard initialization
103
- */
104
- fetchServerConfig() {
105
- fetch('/api/config')
106
- .then(response => response.json())
107
- .then(config => {
108
- // Store config globally for other components
109
- window.dashboardConfig = config;
110
-
111
- // Update initial UI elements if they exist
112
- const workingDirEl = document.getElementById('working-dir-path');
113
- if (workingDirEl && config.workingDirectory) {
114
- workingDirEl.textContent = config.workingDirectory;
115
- }
116
-
117
- const gitBranchEl = document.getElementById('footer-git-branch');
118
- if (gitBranchEl && config.gitBranch) {
119
- gitBranchEl.textContent = config.gitBranch;
120
- }
121
-
122
- console.log('Dashboard configuration loaded:', config);
123
- })
124
- .catch(error => {
125
- console.warn('Failed to fetch server config:', error);
126
- // Set default config as fallback
127
- window.dashboardConfig = {
128
- workingDirectory: '.',
129
- gitBranch: 'Unknown'
130
- };
131
- });
132
- }
133
-
134
- /**
135
- * Validate that all critical components are initialized
136
- * WHY: Ensures dashboard is in a valid state after initialization
137
- */
138
- validateInitialization() {
139
- const criticalComponents = [
140
- { name: 'socketManager', component: this.socketManager },
141
- { name: 'eventViewer', component: this.eventViewer },
142
- { name: 'agentHierarchy', component: this.agentHierarchy }
143
- ];
144
-
145
- const missing = criticalComponents.filter(c => !c.component);
146
- if (missing.length > 0) {
147
- console.warn('Missing critical components:', missing.map(c => c.name));
148
- }
149
- }
150
-
151
- /**
152
- * Post-initialization setup that requires window.dashboard to be set
153
- * WHY: Some components need to reference window.dashboard but it's not available
154
- * during constructor execution. This method is called after the Dashboard instance
155
- * is assigned to window.dashboard, ensuring proper initialization order.
156
- *
157
- * DESIGN DECISION: Separate post-init phase prevents "cannot read property of undefined"
158
- * errors when components try to access window.dashboard during construction.
159
- */
160
- postInit() {
161
- try {
162
- // Set global reference for agent hierarchy after dashboard is available
163
- if (this.agentHierarchy) {
164
- window.dashboard.agentHierarchy = this.agentHierarchy;
165
- }
166
-
167
- // Initialize any other components that need window.dashboard
168
- this.validateInitialization();
169
- } catch (error) {
170
- console.error('Error in dashboard postInit:', error);
171
- // Continue execution - non-critical error
172
- }
173
- }
174
-
175
- /**
176
- * Initialize socket manager
177
- */
178
- initializeSocketManager() {
179
- this.socketManager = new SocketManager();
180
-
181
- // Set up connection controls
182
- this.socketManager.setupConnectionControls();
183
-
184
- // Backward compatibility
185
- this.socketClient = this.socketManager.getSocketClient();
186
- window.socketClient = this.socketClient;
187
- }
188
-
189
- /**
190
- * Initialize core existing components
191
- */
192
- initializeCoreComponents() {
193
- // Initialize existing components with socket client
194
- this.eventViewer = new EventViewer('events-list', this.socketClient);
195
- this.moduleViewer = new ModuleViewer();
196
- this.sessionManager = new SessionManager(this.socketClient);
197
-
198
- // Backward compatibility
199
- window.eventViewer = this.eventViewer;
200
- window.moduleViewer = this.moduleViewer;
201
- window.sessionManager = this.sessionManager;
202
- }
203
-
204
- /**
205
- * Initialize build tracker
206
- */
207
- initializeBuildTracker() {
208
- this.buildTracker = new BuildTracker();
209
-
210
- // Set the socket client for receiving updates
211
- this.buildTracker.setSocketClient(this.socketClient);
212
-
213
- // Mount to header with retry logic for DOM readiness
214
- const mountBuildTracker = () => {
215
- const headerTitle = document.querySelector('.header-title');
216
- if (headerTitle) {
217
- // Insert after the title and status badge
218
- this.buildTracker.mount(headerTitle);
219
- console.log('BuildTracker mounted successfully');
220
- } else {
221
- console.warn('Header-title element not found for build tracker, will retry');
222
- // Retry after a short delay if DOM is still being constructed
223
- setTimeout(mountBuildTracker, 100);
224
- }
225
- };
226
-
227
- // Try to mount immediately, with retry logic if needed
228
- mountBuildTracker();
229
-
230
- // Make available globally for debugging
231
- window.buildTracker = this.buildTracker;
232
- }
233
-
234
- /**
235
- * Initialize agent inference system
236
- */
237
- initializeAgentInference() {
238
- this.agentInference = new AgentInference(this.eventViewer);
239
- this.agentInference.initialize();
240
- }
241
-
242
- /**
243
- * Initialize agent hierarchy component
244
- * WHY: Creates the agent hierarchy visualization component but defers global
245
- * reference setting to postInit() to avoid initialization order issues.
246
- */
247
- initializeAgentHierarchy() {
248
- try {
249
- this.agentHierarchy = new AgentHierarchy(this.agentInference, this.eventViewer);
250
- // Global reference will be set in postInit() after window.dashboard exists
251
- } catch (error) {
252
- console.error('Failed to initialize agent hierarchy:', error);
253
- // Create a stub to prevent further errors
254
- this.agentHierarchy = {
255
- render: () => '<div class="error">Agent hierarchy unavailable</div>',
256
- expandAllNodes: () => {},
257
- collapseAllNodes: () => {},
258
- updateWithNewEvents: () => {}
259
- };
260
- }
261
- }
262
-
263
- /**
264
- * Initialize UI state manager
265
- */
266
- initializeUIStateManager() {
267
- this.uiStateManager = new UIStateManager();
268
- this.setupTabFilters(); // Set up filters after UI state manager
269
- }
270
-
271
- /**
272
- * Initialize working directory manager
273
- */
274
- initializeWorkingDirectoryManager() {
275
- this.workingDirectoryManager = new WorkingDirectoryManager(this.socketManager);
276
- }
277
-
278
- /**
279
- * Initialize file-tool tracker
280
- */
281
- initializeFileToolTracker() {
282
- this.fileToolTracker = new FileToolTracker(this.agentInference, this.workingDirectoryManager);
283
- }
284
-
285
- /**
286
- * Initialize event processor
287
- */
288
- initializeEventProcessor() {
289
- this.eventProcessor = new EventProcessor(this.eventViewer, this.agentInference);
290
- }
291
-
292
-
293
- /**
294
- * Initialize export manager
295
- */
296
- initializeExportManager() {
297
- this.exportManager = new ExportManager(this.eventViewer);
298
- }
299
-
300
- /**
301
- * Set up interactions between modules
302
- */
303
- setupModuleInteractions() {
304
- // Socket events to update file operations and tool calls
305
- this.socketManager.onEventUpdate((events) => {
306
- console.log('[Dashboard] Processing event update with', events.length, 'events');
307
-
308
- // Debug: Log some sample events to see their structure
309
- if (events.length > 0) {
310
- console.log('[Dashboard] Sample event structure:', {
311
- first_event: events[0],
312
- has_tool_events: events.some(e => e.tool_name || (e.data && e.data.tool_name)),
313
- hook_events: events.filter(e => e.type === 'hook').length,
314
- tool_subtypes: events.filter(e => e.subtype === 'pre_tool' || e.subtype === 'post_tool').length
315
- });
316
- }
317
-
318
- this.fileToolTracker.updateFileOperations(events);
319
- this.fileToolTracker.updateToolCalls(events);
320
-
321
- // Debug: Check what was tracked
322
- const fileOps = this.fileToolTracker.getFileOperations();
323
- const toolCalls = this.fileToolTracker.getToolCalls();
324
- console.log('[Dashboard] After update - File operations:', fileOps.size, 'Tool calls:', toolCalls.size);
325
-
326
- // Process agent inference for new events
327
- this.agentInference.processAgentInference();
328
-
329
- // Update agent hierarchy with new events
330
- this.agentHierarchy.updateWithNewEvents(events);
331
-
332
- // Auto-scroll events list if on events tab
333
- if (this.uiStateManager.getCurrentTab() === 'events') {
334
- this.exportManager.scrollListToBottom('events-list');
335
- }
336
-
337
- // Re-render current tab
338
- this.renderCurrentTab();
339
- });
340
-
341
- // Connection status changes
342
- this.socketManager.onConnectionStatusChange((status, type) => {
343
- // Set up git branch listener when connected
344
- if (type === 'connected') {
345
- this.workingDirectoryManager.updateGitBranch(
346
- this.workingDirectoryManager.getCurrentWorkingDir()
347
- );
348
-
349
- // FIX: Force render current tab to display initial/historical event data
350
- // WHY: Events are loaded on connection but panes aren't rendered with this data
351
- console.log('[Dashboard] Connection established - rendering current tab with initial data');
352
- this.renderCurrentTab();
353
- }
354
- });
355
-
356
- // Tab changes
357
- document.addEventListener('tabChanged', (e) => {
358
- this.renderCurrentTab();
359
- this.uiStateManager.updateTabNavigationItems();
360
- });
361
-
362
- // Events clearing
363
- document.addEventListener('eventsClearing', () => {
364
- this.fileToolTracker.clear();
365
- this.agentInference.initialize();
366
- });
367
-
368
- // Card details requests
369
- document.addEventListener('showCardDetails', (e) => {
370
- this.showCardDetails(e.detail.tabName, e.detail.index);
371
- });
372
-
373
- // Session changes
374
- document.addEventListener('sessionFilterChanged', (e) => {
375
- this.renderCurrentTab();
376
- });
377
-
378
- // FIX: Listen for history loaded event to render initial data
379
- // WHY: When historical events are loaded from server, panes need to be rendered
380
- document.addEventListener('historyLoaded', (e) => {
381
- console.log('[Dashboard] History loaded event received:', e.detail);
382
- console.log('[Dashboard] Rendering current tab with historical data');
383
- this.renderCurrentTab();
384
- });
385
- }
386
-
387
- /**
388
- * Set up tab filters
389
- */
390
- setupTabFilters() {
391
- // Agents tab filters
392
- const agentsSearchInput = document.getElementById('agents-search-input');
393
- const agentsTypeFilter = document.getElementById('agents-type-filter');
394
-
395
- if (agentsSearchInput) {
396
- agentsSearchInput.addEventListener('input', () => {
397
- if (this.uiStateManager.getCurrentTab() === 'agents') this.renderCurrentTab();
398
- });
399
- }
400
-
401
- if (agentsTypeFilter) {
402
- agentsTypeFilter.addEventListener('change', () => {
403
- if (this.uiStateManager.getCurrentTab() === 'agents') this.renderCurrentTab();
404
- });
405
- }
406
-
407
- // Tools tab filters
408
- const toolsSearchInput = document.getElementById('tools-search-input');
409
- const toolsTypeFilter = document.getElementById('tools-type-filter');
410
-
411
- if (toolsSearchInput) {
412
- toolsSearchInput.addEventListener('input', () => {
413
- if (this.uiStateManager.getCurrentTab() === 'tools') this.renderCurrentTab();
414
- });
415
- }
416
-
417
- if (toolsTypeFilter) {
418
- toolsTypeFilter.addEventListener('change', () => {
419
- if (this.uiStateManager.getCurrentTab() === 'tools') this.renderCurrentTab();
420
- });
421
- }
422
-
423
- // Files tab filters
424
- const filesSearchInput = document.getElementById('files-search-input');
425
- const filesTypeFilter = document.getElementById('files-type-filter');
426
-
427
- if (filesSearchInput) {
428
- filesSearchInput.addEventListener('input', () => {
429
- if (this.uiStateManager.getCurrentTab() === 'files') this.renderCurrentTab();
430
- });
431
- }
432
-
433
- if (filesTypeFilter) {
434
- filesTypeFilter.addEventListener('change', () => {
435
- if (this.uiStateManager.getCurrentTab() === 'files') this.renderCurrentTab();
436
- });
437
- }
438
- }
439
-
440
- /**
441
- * Initialize from URL parameters
442
- */
443
- initializeFromURL() {
444
- const params = new URLSearchParams(window.location.search);
445
- this.socketManager.initializeFromURL(params);
446
- }
447
-
448
- /**
449
- * Render current tab content
450
- */
451
- renderCurrentTab() {
452
- const currentTab = this.uiStateManager.getCurrentTab();
453
-
454
- switch (currentTab) {
455
- case 'events':
456
- // Events tab is handled by EventViewer
457
- break;
458
- case 'activity':
459
- // Trigger Activity tab rendering through the component
460
- // Check if ActivityTree class is available (from built module)
461
- if (window.ActivityTree && typeof window.ActivityTree === 'function') {
462
- // Reset retry count on successful load
463
- this.activityTreeRetryCount = 0;
464
-
465
- // Create or get instance
466
- if (!window.activityTreeInstance) {
467
- window.activityTreeInstance = new window.ActivityTree();
468
- }
469
-
470
- // Initialize if needed and render
471
- if (window.activityTreeInstance) {
472
- if (!window.activityTreeInstance.initialized) {
473
- window.activityTreeInstance.initialize();
474
- }
475
-
476
- if (typeof window.activityTreeInstance.renderWhenVisible === 'function') {
477
- window.activityTreeInstance.renderWhenVisible();
478
- }
479
-
480
- // Force show to ensure the tree is visible
481
- if (typeof window.activityTreeInstance.forceShow === 'function') {
482
- window.activityTreeInstance.forceShow();
483
- }
484
- }
485
- } else if (window.activityTree && typeof window.activityTree === 'function') {
486
- // Fallback to legacy approach if available
487
- const activityTreeInstance = window.activityTree();
488
- if (activityTreeInstance) {
489
- if (typeof activityTreeInstance.renderWhenVisible === 'function') {
490
- activityTreeInstance.renderWhenVisible();
491
- }
492
- if (typeof activityTreeInstance.forceShow === 'function') {
493
- activityTreeInstance.forceShow();
494
- }
495
- }
496
- } else {
497
- // Module not loaded yet, retry after a delay (with retry limit)
498
- if (this.activityTreeRetryCount < this.maxRetryAttempts) {
499
- this.activityTreeRetryCount++;
500
- console.warn(`Activity tree component not available, retrying in 100ms... (attempt ${this.activityTreeRetryCount}/${this.maxRetryAttempts})`);
501
- setTimeout(() => {
502
- if (this.uiStateManager.getCurrentTab() === 'activity') {
503
- this.renderCurrentTab();
504
- }
505
- }, 100);
506
- } else {
507
- console.error('Maximum retry attempts reached for ActivityTree initialization. Giving up.');
508
- const activityContainer = document.getElementById('activity-tree-container') || document.getElementById('activity-tree');
509
- if (activityContainer) {
510
- activityContainer.innerHTML = '<div class="error-message">⚠️ Activity Tree failed to load. Please refresh the page.</div>';
511
- }
512
- }
513
- }
514
- break;
515
- case 'agents':
516
- this.renderAgents();
517
- break;
518
- case 'tools':
519
- this.renderTools();
520
- break;
521
- case 'files':
522
- this.renderFiles();
523
- break;
524
- }
525
-
526
- // Update selection UI if we have a selected card
527
- const selectedCard = this.uiStateManager.getSelectedCard();
528
- if (selectedCard.tab === currentTab) {
529
- this.uiStateManager.updateCardSelectionUI();
530
- }
531
-
532
- // Update unified selection UI to maintain consistency
533
- this.uiStateManager.updateUnifiedSelectionUI();
534
- }
535
-
536
- /**
537
- * Render agents tab with flat chronological view
538
- */
539
- renderAgents() {
540
- const agentsList = document.getElementById('agents-list');
541
- if (!agentsList) return;
542
-
543
- // Get filter values
544
- const searchText = document.getElementById('agents-search-input')?.value || '';
545
- const agentType = document.getElementById('agents-type-filter')?.value || '';
546
-
547
- // Generate flat HTML
548
- const flatHTML = this.renderAgentsFlat(searchText, agentType);
549
- agentsList.innerHTML = flatHTML;
550
-
551
- // Remove hierarchy controls if they exist
552
- this.removeHierarchyControls();
553
-
554
- // Update filter dropdowns with available agent types
555
- const uniqueInstances = this.agentInference.getUniqueAgentInstances();
556
- this.updateAgentsFilterDropdowns(uniqueInstances);
557
- }
558
-
559
- /**
560
- * Remove hierarchy control buttons (flat view doesn't need them)
561
- */
562
- removeHierarchyControls() {
563
- const existingControls = document.getElementById('hierarchy-controls');
564
- if (existingControls) {
565
- existingControls.remove();
566
- }
567
- }
568
-
569
- /**
570
- * Render agents as a flat chronological list
571
- * @param {string} searchText - Search filter
572
- * @param {string} agentType - Agent type filter
573
- * @returns {string} HTML for flat agent list
574
- */
575
- renderAgentsFlat(searchText, agentType) {
576
- const events = this.eventViewer.events;
577
- if (!events || events.length === 0) {
578
- return '<div class="no-events">No agent events found...</div>';
579
- }
580
-
581
- // Process agent inference to get agent mappings
582
- this.agentInference.processAgentInference();
583
- const eventAgentMap = this.agentInference.getEventAgentMap();
584
-
585
- // Collect all agent events with metadata
586
- const agentEvents = [];
587
- events.forEach((event, index) => {
588
- const inference = eventAgentMap.get(index);
589
- if (inference && (inference.type === 'subagent' || inference.type === 'main_agent')) {
590
- // Apply filters
591
- let includeEvent = true;
592
-
593
- if (searchText) {
594
- const searchLower = searchText.toLowerCase();
595
- includeEvent = includeEvent && (
596
- inference.agentName.toLowerCase().includes(searchLower) ||
597
- (event.tool_name && event.tool_name.toLowerCase().includes(searchLower)) ||
598
- (event.data && JSON.stringify(event.data).toLowerCase().includes(searchLower))
599
- );
600
- }
601
-
602
- if (agentType) {
603
- includeEvent = includeEvent && inference.agentName.includes(agentType);
604
- }
605
-
606
- if (includeEvent) {
607
- agentEvents.push({
608
- event,
609
- inference,
610
- index,
611
- timestamp: new Date(event.timestamp)
612
- });
613
- }
614
- }
615
- });
616
-
617
- if (agentEvents.length === 0) {
618
- return '<div class="no-events">No agent events match the current filters...</div>';
619
- }
620
-
621
- // Generate HTML for each event
622
- const html = agentEvents.map((item, listIndex) => {
623
- const { event, inference, index, timestamp } = item;
624
-
625
- // Determine action/tool
626
- let action = 'Activity';
627
- let actionIcon = '📋';
628
- let details = '';
629
-
630
- if (event.event_type === 'SubagentStart') {
631
- action = 'Started';
632
- actionIcon = '🟢';
633
- details = 'Agent session began';
634
- } else if (event.event_type === 'SubagentStop') {
635
- action = 'Stopped';
636
- actionIcon = '🔴';
637
- details = 'Agent session ended';
638
- } else if (event.tool_name) {
639
- action = `Tool: ${event.tool_name}`;
640
- actionIcon = this.getToolIcon(event.tool_name);
641
-
642
- // Add tool parameters as details
643
- if (event.data && event.data.tool_parameters) {
644
- const params = event.data.tool_parameters;
645
- if (params.file_path) {
646
- details = params.file_path;
647
- } else if (params.command) {
648
- details = params.command.substring(0, 50) + (params.command.length > 50 ? '...' : '');
649
- } else if (params.pattern) {
650
- details = `pattern="${params.pattern}"`;
651
- } else if (params.query) {
652
- details = `query="${params.query}"`;
653
- }
654
- }
655
- }
656
-
657
- // Status based on event type
658
- let status = 'completed';
659
- if (event.event_type === 'SubagentStart') {
660
- status = 'active';
661
- } else if (event.data && event.data.error) {
662
- status = 'error';
663
- }
664
-
665
- return `
666
- <div class="agent-event-item" data-index="${listIndex}" onclick="window.dashboard.showCardDetails('agents', ${index})">
667
- <div class="agent-event-header">
668
- <div class="agent-event-time">${this.formatTimestamp(timestamp)}</div>
669
- <div class="agent-event-agent">
670
- ${this.getAgentIcon(inference.agentName)} ${inference.agentName}
671
- </div>
672
- <div class="agent-event-action">
673
- ${actionIcon} ${action}
674
- </div>
675
- <div class="agent-event-status status-${status}">
676
- ${this.getStatusIcon(status)}
677
- </div>
678
- </div>
679
- ${details ? `<div class="agent-event-details">${this.escapeHtml(details)}</div>` : ''}
680
- </div>
681
- `;
682
- }).join('');
683
-
684
- return `<div class="agent-events-flat">${html}</div>`;
685
- }
686
-
687
- /**
688
- * Get icon for agent type
689
- */
690
- getAgentIcon(agentName) {
691
- const agentIcons = {
692
- 'PM': '🎯',
693
- 'Engineer Agent': '🔧',
694
- 'Research Agent': '🔍',
695
- 'QA Agent': '✅',
696
- 'Documentation Agent': '📝',
697
- 'Security Agent': '🔒',
698
- 'Ops Agent': '⚙️',
699
- 'Version Control Agent': '📦',
700
- 'Data Engineer Agent': '💾',
701
- 'Test Integration Agent': '🧪'
702
- };
703
- return agentIcons[agentName] || '🤖';
704
- }
705
-
706
- /**
707
- * Get icon for tool
708
- */
709
- getToolIcon(toolName) {
710
- const toolIcons = {
711
- 'Read': '📖',
712
- 'Write': '✏️',
713
- 'Edit': '📝',
714
- 'Bash': '💻',
715
- 'Grep': '🔍',
716
- 'Glob': '📂',
717
- 'LS': '📁',
718
- 'Task': '📋'
719
- };
720
- return toolIcons[toolName] || '🔧';
721
- }
722
-
723
- /**
724
- * Get icon for status
725
- */
726
- getStatusIcon(status) {
727
- const statusIcons = {
728
- 'active': '🟢',
729
- 'completed': '✅',
730
- 'error': '❌',
731
- 'pending': '🟡'
732
- };
733
- return statusIcons[status] || '❓';
734
- }
735
-
736
- /**
737
- * Format timestamp for display
738
- */
739
- formatTimestamp(timestamp) {
740
- return timestamp.toLocaleTimeString('en-US', {
741
- hour: '2-digit',
742
- minute: '2-digit',
743
- second: '2-digit',
744
- hour12: false
745
- });
746
- }
747
-
748
- /**
749
- * Escape HTML for safe display
750
- */
751
- escapeHtml(text) {
752
- if (!text) return '';
753
- const div = document.createElement('div');
754
- div.textContent = text;
755
- return div.innerHTML;
756
- }
757
-
758
- /**
759
- * Render tools tab with unique instance view (one row per unique tool call)
760
- */
761
- renderTools() {
762
- const toolsList = document.getElementById('tools-list');
763
- if (!toolsList) return;
764
-
765
- const toolCalls = this.fileToolTracker.getToolCalls();
766
- const toolCallsArray = Array.from(toolCalls.entries());
767
- const uniqueToolInstances = this.eventProcessor.getUniqueToolInstances(toolCallsArray);
768
- const toolHTML = this.eventProcessor.generateToolHTML(uniqueToolInstances);
769
-
770
- toolsList.innerHTML = toolHTML;
771
- this.exportManager.scrollListToBottom('tools-list');
772
-
773
- // Update filter dropdowns
774
- this.updateToolsFilterDropdowns(uniqueToolInstances);
775
- }
776
-
777
- /**
778
- * Render files tab with unique instance view (one row per unique file)
779
- */
780
- renderFiles() {
781
- const filesList = document.getElementById('files-list');
782
- if (!filesList) return;
783
-
784
- const fileOperations = this.fileToolTracker.getFileOperations();
785
- const filesArray = Array.from(fileOperations.entries());
786
-
787
- console.log('[renderFiles] File operations map size:', fileOperations.size);
788
- console.log('[renderFiles] Files array:', filesArray);
789
-
790
- const uniqueFileInstances = this.eventProcessor.getUniqueFileInstances(filesArray);
791
- const fileHTML = this.eventProcessor.generateFileHTML(uniqueFileInstances);
792
-
793
- if (filesArray.length === 0) {
794
- filesList.innerHTML = '<div class="empty-state">No file operations tracked yet. File operations will appear here when tools like Read, Write, Edit, or Grep are used.</div>';
795
- } else {
796
- filesList.innerHTML = fileHTML;
797
- }
798
-
799
- this.exportManager.scrollListToBottom('files-list');
800
-
801
- // Update filter dropdowns
802
- this.updateFilesFilterDropdowns(filesArray);
803
- }
804
-
805
- /**
806
- * Update agents filter dropdowns for unique instances
807
- */
808
- updateAgentsFilterDropdowns(uniqueInstances) {
809
- const agentTypes = new Set();
810
-
811
- // uniqueInstances is already an array of unique agent instances
812
- uniqueInstances.forEach(instance => {
813
- if (instance.agentName && instance.agentName !== 'Unknown') {
814
- agentTypes.add(instance.agentName);
815
- }
816
- });
817
-
818
- const sortedTypes = Array.from(agentTypes).filter(type => type && type.trim() !== '');
819
- this.populateFilterDropdown('agents-type-filter', sortedTypes, 'All Agent Types');
820
-
821
- // Agent filter types populated
822
- }
823
-
824
- /**
825
- * Update tools filter dropdowns
826
- */
827
- updateToolsFilterDropdowns(toolCallsArray) {
828
- const toolNames = [...new Set(toolCallsArray.map(([key, toolCall]) => toolCall.tool_name))]
829
- .filter(name => name);
830
-
831
- this.populateFilterDropdown('tools-type-filter', toolNames, 'All Tools');
832
- }
833
-
834
- /**
835
- * Update files filter dropdowns
836
- */
837
- updateFilesFilterDropdowns(filesArray) {
838
- const operations = [...new Set(filesArray.flatMap(([path, data]) =>
839
- data.operations.map(op => op.operation)
840
- ))].filter(op => op);
841
-
842
- this.populateFilterDropdown('files-type-filter', operations, 'All Operations');
843
- }
844
-
845
- /**
846
- * Populate filter dropdown with values
847
- */
848
- populateFilterDropdown(selectId, values, allOption = 'All') {
849
- const select = document.getElementById(selectId);
850
- if (!select) return;
851
-
852
- const currentValue = select.value;
853
- const sortedValues = values.sort((a, b) => a.localeCompare(b));
854
-
855
- // Clear existing options except the first "All" option
856
- select.innerHTML = `<option value="">${allOption}</option>`;
857
-
858
- // Add sorted values
859
- sortedValues.forEach(value => {
860
- const option = document.createElement('option');
861
- option.value = value;
862
- option.textContent = value;
863
- select.appendChild(option);
864
- });
865
-
866
- // Restore previous selection if it still exists
867
- if (currentValue && sortedValues.includes(currentValue)) {
868
- select.value = currentValue;
869
- }
870
- }
871
-
872
- /**
873
- * Show card details for specified tab and index
874
- */
875
- showCardDetails(tabName, index) {
876
- switch (tabName) {
877
- case 'events':
878
- if (this.eventViewer) {
879
- this.eventViewer.showEventDetails(index);
880
- }
881
- break;
882
- case 'agents':
883
- this.showAgentDetailsByIndex(index);
884
- break;
885
- case 'tools':
886
- this.showToolDetailsByIndex(index);
887
- break;
888
- case 'files':
889
- this.showFileDetailsByIndex(index);
890
- break;
891
- }
892
- }
893
-
894
- /**
895
- * Show agent details by index
896
- */
897
- showAgentDetailsByIndex(index) {
898
- const events = this.eventProcessor.getFilteredEventsForTab('agents');
899
-
900
- // Defensive checks
901
- if (!events || !Array.isArray(events) || index < 0 || index >= events.length) {
902
- console.warn('Dashboard: Invalid agent index or events array');
903
- return;
904
- }
905
-
906
- const filteredSingleEvent = this.eventProcessor.applyAgentsFilters([events[index]]);
907
-
908
- if (filteredSingleEvent.length > 0 && this.moduleViewer &&
909
- typeof this.moduleViewer.showAgentEvent === 'function') {
910
- const event = filteredSingleEvent[0];
911
- this.moduleViewer.showAgentEvent(event, index);
912
- }
913
- }
914
-
915
- /**
916
- * Show agent instance details for unique instance view
917
- * @param {string} instanceId - Agent instance ID
918
- */
919
- showAgentInstanceDetails(instanceId) {
920
- const pmDelegations = this.agentInference.getPMDelegations();
921
- const instance = pmDelegations.get(instanceId);
922
-
923
- if (!instance) {
924
- // Check if it's an implied delegation
925
- const uniqueInstances = this.agentInference.getUniqueAgentInstances();
926
- const impliedInstance = uniqueInstances.find(inst => inst.id === instanceId);
927
-
928
- if (!impliedInstance) {
929
- console.error('Agent instance not found:', instanceId);
930
- return;
931
- }
932
-
933
- // For implied instances, show basic info
934
- this.showImpliedAgentDetails(impliedInstance);
935
- return;
936
- }
937
-
938
- // Show full PM delegation details
939
- if (this.moduleViewer && typeof this.moduleViewer.showAgentInstance === 'function') {
940
- this.moduleViewer.showAgentInstance(instance);
941
- } else {
942
- // Fallback: show in console or basic modal
943
- console.log('Agent Instance Details:', {
944
- id: instanceId,
945
- agentName: instance.agentName,
946
- type: 'PM Delegation',
947
- eventCount: instance.agentEvents.length,
948
- startTime: instance.timestamp,
949
- pmCall: instance.pmCall
950
- });
951
- }
952
- }
953
-
954
- /**
955
- * Show implied agent details (agents without explicit PM delegation)
956
- * @param {Object} impliedInstance - Implied agent instance
957
- */
958
- showImpliedAgentDetails(impliedInstance) {
959
- if (this.moduleViewer && typeof this.moduleViewer.showImpliedAgent === 'function') {
960
- this.moduleViewer.showImpliedAgent(impliedInstance);
961
- } else {
962
- // Fallback: show in console or basic modal
963
- console.log('Implied Agent Details:', {
964
- id: impliedInstance.id,
965
- agentName: impliedInstance.agentName,
966
- type: 'Implied PM Delegation',
967
- eventCount: impliedInstance.eventCount,
968
- startTime: impliedInstance.timestamp,
969
- note: 'No explicit PM call found - inferred from agent activity'
970
- });
971
- }
972
- }
973
-
974
- /**
975
- * Show tool details by index
976
- */
977
- showToolDetailsByIndex(index) {
978
- const toolCalls = this.fileToolTracker.getToolCalls();
979
- const toolCallsArray = Array.from(toolCalls.entries());
980
- const filteredToolCalls = this.eventProcessor.applyToolCallFilters(toolCallsArray);
981
-
982
- if (index >= 0 && index < filteredToolCalls.length) {
983
- const [toolCallKey] = filteredToolCalls[index];
984
- this.showToolCallDetails(toolCallKey);
985
- }
986
- }
987
-
988
- /**
989
- * Show file details by index
990
- */
991
- showFileDetailsByIndex(index) {
992
- const fileOperations = this.fileToolTracker.getFileOperations();
993
- let filesArray = Array.from(fileOperations.entries());
994
- filesArray = this.eventProcessor.applyFilesFilters(filesArray);
995
-
996
- if (index >= 0 && index < filesArray.length) {
997
- const [filePath] = filesArray[index];
998
- this.showFileDetails(filePath);
999
- }
1000
- }
1001
-
1002
- /**
1003
- * Show tool call details
1004
- */
1005
- showToolCallDetails(toolCallKey) {
1006
- const toolCall = this.fileToolTracker.getToolCall(toolCallKey);
1007
- if (toolCall && this.moduleViewer) {
1008
- this.moduleViewer.showToolCall(toolCall, toolCallKey);
1009
- }
1010
- }
1011
-
1012
- /**
1013
- * Show file details
1014
- */
1015
- showFileDetails(filePath) {
1016
- const fileData = this.fileToolTracker.getFileOperationsForFile(filePath);
1017
- if (fileData && this.moduleViewer) {
1018
- this.moduleViewer.showFileOperations(fileData, filePath);
1019
- }
1020
- }
1021
-
1022
- // ====================================
1023
- // BACKWARD COMPATIBILITY METHODS
1024
- // ====================================
1025
-
1026
- /**
1027
- * Switch tab (backward compatibility)
1028
- */
1029
- switchTab(tabName) {
1030
- this.uiStateManager.switchTab(tabName);
1031
- }
1032
-
1033
- /**
1034
- * Select card (backward compatibility)
1035
- */
1036
- selectCard(tabName, index, type, data) {
1037
- this.uiStateManager.selectCard(tabName, index, type, data);
1038
- }
1039
-
1040
- /**
1041
- * Clear events (backward compatibility)
1042
- */
1043
- clearEvents() {
1044
- this.exportManager.clearEvents();
1045
- }
1046
-
1047
- /**
1048
- * Export events (backward compatibility)
1049
- */
1050
- exportEvents() {
1051
- this.exportManager.exportEvents();
1052
- }
1053
-
1054
- /**
1055
- * Clear selection (backward compatibility)
1056
- */
1057
- clearSelection() {
1058
- this.uiStateManager.clearSelection();
1059
- if (this.eventViewer) {
1060
- this.eventViewer.clearSelection();
1061
- }
1062
- if (this.moduleViewer) {
1063
- this.moduleViewer.clear();
1064
- }
1065
- }
1066
-
1067
-
1068
- /**
1069
- * Get current working directory (backward compatibility)
1070
- */
1071
- get currentWorkingDir() {
1072
- return this.workingDirectoryManager.getCurrentWorkingDir();
1073
- }
1074
-
1075
- /**
1076
- * Set current working directory (backward compatibility)
1077
- */
1078
- set currentWorkingDir(dir) {
1079
- this.workingDirectoryManager.setWorkingDirectory(dir);
1080
- }
1081
-
1082
- /**
1083
- * Get current tab (backward compatibility)
1084
- */
1085
- get currentTab() {
1086
- return this.uiStateManager.getCurrentTab();
1087
- }
1088
-
1089
- /**
1090
- * Get selected card (backward compatibility)
1091
- */
1092
- get selectedCard() {
1093
- return this.uiStateManager.getSelectedCard();
1094
- }
1095
-
1096
- /**
1097
- * Get file operations (backward compatibility)
1098
- */
1099
- get fileOperations() {
1100
- return this.fileToolTracker.getFileOperations();
1101
- }
1102
-
1103
- /**
1104
- * Get tool calls (backward compatibility)
1105
- */
1106
- get toolCalls() {
1107
- return this.fileToolTracker.getToolCalls();
1108
- }
1109
-
1110
-
1111
- /**
1112
- * Get tab navigation state (backward compatibility)
1113
- */
1114
- get tabNavigation() {
1115
- return this.uiStateManager ? this.uiStateManager.tabNavigation : null;
1116
- }
1117
- }
1118
-
1119
- // Global functions for backward compatibility
1120
- window.clearEvents = function() {
1121
- if (window.dashboard) {
1122
- window.dashboard.clearEvents();
1123
- }
1124
- };
1125
-
1126
- window.exportEvents = function() {
1127
- if (window.dashboard) {
1128
- window.dashboard.exportEvents();
1129
- }
1130
- };
1131
-
1132
- window.clearSelection = function() {
1133
- if (window.dashboard) {
1134
- window.dashboard.clearSelection();
1135
- }
1136
- };
1137
-
1138
- window.switchTab = function(tabName) {
1139
- if (window.dashboard) {
1140
- window.dashboard.switchTab(tabName);
1141
- }
1142
- };
1143
-
1144
- // File Viewer Modal Functions - Removed broken duplicate (using the one at line 1505)
1145
-
1146
- window.copyFileContent = function() {
1147
- const modal = document.getElementById('file-viewer-modal');
1148
- if (!modal) return;
1149
-
1150
- const codeElement = modal.querySelector('.file-content-code');
1151
- if (!codeElement) return;
1152
-
1153
- const text = codeElement.textContent;
1154
-
1155
- if (navigator.clipboard && navigator.clipboard.writeText) {
1156
- navigator.clipboard.writeText(text).then(() => {
1157
- // Show brief feedback
1158
- const button = modal.querySelector('.file-content-copy');
1159
- if (button) {
1160
- const originalText = button.textContent;
1161
- button.textContent = '✅ Copied!';
1162
- setTimeout(() => {
1163
- button.textContent = originalText;
1164
- }, 2000);
1165
- }
1166
- }).catch(err => {
1167
- console.error('Failed to copy text:', err);
1168
- });
1169
- } else {
1170
- // Fallback for older browsers
1171
- const textarea = document.createElement('textarea');
1172
- textarea.value = text;
1173
- document.body.appendChild(textarea);
1174
- textarea.select();
1175
- document.execCommand('copy');
1176
- document.body.removeChild(textarea);
1177
-
1178
- const button = modal.querySelector('.file-content-copy');
1179
- if (button) {
1180
- const originalText = button.textContent;
1181
- button.textContent = '✅ Copied!';
1182
- setTimeout(() => {
1183
- button.textContent = originalText;
1184
- }, 2000);
1185
- }
1186
- }
1187
- };
1188
-
1189
- function createFileViewerModal() {
1190
- const modal = document.createElement('div');
1191
- modal.id = 'file-viewer-modal';
1192
- modal.className = 'modal file-viewer-modal';
1193
-
1194
- modal.innerHTML = `
1195
- <div class="modal-content file-viewer-content">
1196
- <div class="file-viewer-header">
1197
- <h2 class="file-viewer-title">
1198
- <span class="file-viewer-icon">📄</span>
1199
- <span class="file-viewer-title-text">File Viewer</span>
1200
- </h2>
1201
- <div class="file-viewer-meta">
1202
- <span class="file-viewer-file-path"></span>
1203
- <span class="file-viewer-file-size"></span>
1204
- </div>
1205
- <button class="file-viewer-close" onclick="hideFileViewerModal()">
1206
- <span>&times;</span>
1207
- </button>
1208
- </div>
1209
- <div class="file-viewer-body">
1210
- <div class="file-viewer-loading">
1211
- <div class="loading-spinner"></div>
1212
- <span>Loading file content...</span>
1213
- </div>
1214
- <div class="file-viewer-error" style="display: none;">
1215
- <div class="error-icon">⚠️</div>
1216
- <div class="error-message"></div>
1217
- <div class="error-suggestions"></div>
1218
- </div>
1219
- <div class="file-viewer-content-area" style="display: none;">
1220
- <div class="file-viewer-toolbar">
1221
- <div class="file-viewer-info">
1222
- <span class="file-extension"></span>
1223
- <span class="file-encoding"></span>
1224
- </div>
1225
- <div class="file-viewer-actions">
1226
- <button class="file-content-copy" onclick="copyFileContent()">
1227
- 📋 Copy
1228
- </button>
1229
- </div>
1230
- </div>
1231
- <div class="file-viewer-scroll-wrapper">
1232
- <pre class="file-content-display"><code class="file-content-code"></code></pre>
1233
- </div>
1234
- </div>
1235
- </div>
1236
- </div>
1237
- `;
1238
-
1239
- // Close modal when clicking outside
1240
- modal.addEventListener('click', (e) => {
1241
- if (e.target === modal) {
1242
- hideFileViewerModal();
1243
- }
1244
- });
1245
-
1246
- // Close modal with Escape key
1247
- document.addEventListener('keydown', (e) => {
1248
- if (e.key === 'Escape' && modal.style.display === 'flex') {
1249
- hideFileViewerModal();
1250
- }
1251
- });
1252
-
1253
- return modal;
1254
- }
1255
-
1256
- async function updateFileViewerModal(modal, filePath, workingDir) {
1257
- // Update header info
1258
- const filePathElement = modal.querySelector('.file-viewer-file-path');
1259
- const fileSizeElement = modal.querySelector('.file-viewer-file-size');
1260
-
1261
- if (filePathElement) {
1262
- filePathElement.textContent = filePath;
1263
- }
1264
- if (fileSizeElement) {
1265
- fileSizeElement.textContent = '';
1266
- }
1267
-
1268
- // Show loading state
1269
- const loadingElement = modal.querySelector('.file-viewer-loading');
1270
- const errorElement = modal.querySelector('.file-viewer-error');
1271
- const contentArea = modal.querySelector('.file-viewer-content-area');
1272
-
1273
- if (loadingElement) {
1274
- loadingElement.style.display = 'flex';
1275
- }
1276
- if (errorElement) {
1277
- errorElement.style.display = 'none';
1278
- }
1279
- if (contentArea) {
1280
- contentArea.style.display = 'none';
1281
- }
1282
-
1283
- try {
1284
- // Get the Socket.IO client
1285
- const socket = window.socket || window.dashboard?.socketClient?.socket || window.socketClient?.socket;
1286
-
1287
- console.log('[FileViewer] Socket search results:', {
1288
- 'window.socket': !!window.socket,
1289
- 'window.socket.connected': window.socket?.connected,
1290
- 'dashboard.socketClient.socket': !!window.dashboard?.socketClient?.socket,
1291
- 'dashboard.socketClient.socket.connected': window.dashboard?.socketClient?.socket?.connected,
1292
- 'window.socketClient.socket': !!window.socketClient?.socket,
1293
- 'window.socketClient.socket.connected': window.socketClient?.socket?.connected
1294
- });
1295
-
1296
- if (!socket) {
1297
- throw new Error('No socket connection available. Please ensure the dashboard is connected.');
1298
- }
1299
-
1300
- if (!socket.connected) {
1301
- console.warn('[FileViewer] Socket found but not connected, attempting to use anyway...');
1302
- }
1303
-
1304
- console.log('[FileViewer] Socket found, setting up listener for file_content_response');
1305
-
1306
- // Set up one-time listener for file content response
1307
- const responsePromise = new Promise((resolve, reject) => {
1308
- const responseHandler = (data) => {
1309
- console.log('[FileViewer] Received file_content_response:', data);
1310
- if (data.file_path === filePath) {
1311
- socket.off('file_content_response', responseHandler);
1312
- if (data.success) {
1313
- console.log('[FileViewer] File content loaded successfully');
1314
- resolve(data);
1315
- } else {
1316
- console.error('[FileViewer] File read failed:', data.error);
1317
- reject(new Error(data.error || 'Failed to read file'));
1318
- }
1319
- }
1320
- };
1321
-
1322
- socket.on('file_content_response', responseHandler);
1323
- console.log('[FileViewer] Listener registered for file_content_response');
1324
-
1325
- // Timeout after 10 seconds
1326
- setTimeout(() => {
1327
- socket.off('file_content_response', responseHandler);
1328
- console.error('[FileViewer] Request timeout after 10 seconds');
1329
- reject(new Error('Request timeout - server did not respond'));
1330
- }, 10000);
1331
- });
1332
-
1333
- // Send file read request
1334
- const requestData = {
1335
- file_path: filePath,
1336
- working_dir: workingDir
1337
- };
1338
- console.log('[FileViewer] Emitting read_file event with data:', requestData);
1339
- socket.emit('read_file', requestData);
1340
-
1341
- // File viewer request sent
1342
-
1343
- // Wait for response
1344
- const result = await responsePromise;
1345
- // File content received successfully
1346
-
1347
- // Hide loading
1348
- const loadingEl = modal.querySelector('.file-viewer-loading');
1349
- if (loadingEl) {
1350
- loadingEl.style.display = 'none';
1351
- }
1352
-
1353
- // Show successful content
1354
- displayFileContent(modal, result);
1355
-
1356
- } catch (error) {
1357
- console.error('❌ Failed to fetch file content:', error);
1358
-
1359
- const loadingEl2 = modal.querySelector('.file-viewer-loading');
1360
- if (loadingEl2) {
1361
- loadingEl2.style.display = 'none';
1362
- }
1363
-
1364
- // Create detailed error message
1365
- let errorMessage = error.message || 'Unknown error occurred';
1366
- let suggestions = [];
1367
-
1368
- if (error.message.includes('No socket connection')) {
1369
- errorMessage = 'Failed to connect to the monitoring server';
1370
- suggestions = [
1371
- 'Check if the monitoring server is running',
1372
- 'Verify the socket connection in the dashboard',
1373
- 'Try refreshing the page and reconnecting'
1374
- ];
1375
- } else if (error.message.includes('timeout')) {
1376
- errorMessage = 'Request timed out';
1377
- suggestions = [
1378
- 'The file may be too large to load quickly',
1379
- 'Check your network connection',
1380
- 'Try again in a few moments'
1381
- ];
1382
- } else if (error.message.includes('File does not exist')) {
1383
- errorMessage = 'File not found';
1384
- suggestions = [
1385
- 'The file may have been moved or deleted',
1386
- 'Check the file path spelling',
1387
- 'Refresh the file list to see current files'
1388
- ];
1389
- } else if (error.message.includes('Access denied')) {
1390
- errorMessage = 'Access denied';
1391
- suggestions = [
1392
- 'The file is outside the allowed directories',
1393
- 'File access is restricted for security reasons'
1394
- ];
1395
- }
1396
-
1397
- displayFileError(modal, {
1398
- error: errorMessage,
1399
- file_path: filePath,
1400
- working_dir: workingDir,
1401
- suggestions: suggestions
1402
- });
1403
- }
1404
- }
1405
-
1406
- function displayFileContent(modal, result) {
1407
- // Display file content in modal
1408
- const contentArea = modal.querySelector('.file-viewer-content-area');
1409
- const extensionElement = modal.querySelector('.file-extension');
1410
- const encodingElement = modal.querySelector('.file-encoding');
1411
- const fileSizeElement = modal.querySelector('.file-viewer-file-size');
1412
- const codeElement = modal.querySelector('.file-content-code');
1413
-
1414
- // Update metadata
1415
- if (extensionElement) extensionElement.textContent = `Type: ${result.extension || 'unknown'}`;
1416
- if (encodingElement) encodingElement.textContent = `Encoding: ${result.encoding || 'unknown'}`;
1417
- if (fileSizeElement) fileSizeElement.textContent = `Size: ${formatFileSize(result.file_size)}`;
1418
-
1419
- // Update content with basic syntax highlighting
1420
- if (codeElement && result.content) {
1421
- // Setting file content
1422
- codeElement.innerHTML = highlightCode(result.content, result.extension);
1423
-
1424
- // Force scrolling to work by setting explicit heights
1425
- const wrapper = modal.querySelector('.file-viewer-scroll-wrapper');
1426
- if (wrapper) {
1427
- // Give it a moment for content to render
1428
- setTimeout(() => {
1429
- const modalContent = modal.querySelector('.modal-content');
1430
- const header = modal.querySelector('.file-viewer-header');
1431
- const toolbar = modal.querySelector('.file-viewer-toolbar');
1432
-
1433
- const modalHeight = modalContent?.offsetHeight || 0;
1434
- const headerHeight = header?.offsetHeight || 0;
1435
- const toolbarHeight = toolbar?.offsetHeight || 0;
1436
-
1437
- const availableHeight = modalHeight - headerHeight - toolbarHeight - 40; // 40px for padding
1438
-
1439
- // Setting file viewer scroll height
1440
-
1441
- wrapper.style.maxHeight = `${availableHeight}px`;
1442
- wrapper.style.overflowY = 'auto';
1443
- }, 50);
1444
- }
1445
- } else {
1446
- console.warn('⚠️ Missing codeElement or file content');
1447
- }
1448
-
1449
- // Show content area
1450
- if (contentArea) {
1451
- contentArea.style.display = 'block';
1452
- // File content area displayed
1453
- }
1454
- }
1455
-
1456
- function displayFileError(modal, result) {
1457
- const errorArea = modal.querySelector('.file-viewer-error');
1458
- const messageElement = modal.querySelector('.error-message');
1459
- const suggestionsElement = modal.querySelector('.error-suggestions');
1460
-
1461
- let errorMessage = result.error || 'Unknown error occurred';
1462
-
1463
- if (messageElement) {
1464
- messageElement.innerHTML = `
1465
- <div class="error-main">${errorMessage}</div>
1466
- ${result.file_path ? `<div class="error-file">File: ${result.file_path}</div>` : ''}
1467
- ${result.working_dir ? `<div class="error-dir">Working directory: ${result.working_dir}</div>` : ''}
1468
- `;
1469
- }
1470
-
1471
- if (suggestionsElement) {
1472
- if (result.suggestions && result.suggestions.length > 0) {
1473
- suggestionsElement.innerHTML = `
1474
- <h4>Suggestions:</h4>
1475
- <ul>
1476
- ${result.suggestions.map(s => `<li>${s}</li>`).join('')}
1477
- </ul>
1478
- `;
1479
- } else {
1480
- suggestionsElement.innerHTML = '';
1481
- }
1482
- }
1483
-
1484
- console.log('📋 Displaying file viewer error:', {
1485
- originalError: result.error,
1486
- processedMessage: errorMessage,
1487
- suggestions: result.suggestions
1488
- });
1489
-
1490
- if (errorArea) {
1491
- errorArea.style.display = 'block';
1492
- }
1493
- }
1494
-
1495
- function highlightCode(code, extension) {
1496
- /**
1497
- * Apply basic syntax highlighting to code content
1498
- * WHY: Provides basic highlighting for common file types to improve readability.
1499
- * This is a simple implementation that can be enhanced with full syntax highlighting
1500
- * libraries like highlight.js or Prism.js if needed.
1501
- */
1502
-
1503
- // Escape HTML entities first
1504
- const escaped = code
1505
- .replace(/&/g, '&amp;')
1506
- .replace(/</g, '&lt;')
1507
- .replace(/>/g, '&gt;');
1508
-
1509
- // Basic highlighting based on file extension
1510
- switch (extension) {
1511
- case '.js':
1512
- case '.jsx':
1513
- case '.ts':
1514
- case '.tsx':
1515
- return highlightJavaScript(escaped);
1516
- case '.py':
1517
- return highlightPython(escaped);
1518
- case '.json':
1519
- return highlightJSON(escaped);
1520
- case '.css':
1521
- return highlightCSS(escaped);
1522
- case '.html':
1523
- case '.htm':
1524
- return highlightHTML(escaped);
1525
- case '.md':
1526
- case '.markdown':
1527
- return highlightMarkdown(escaped);
1528
- default:
1529
- // Return with line numbers for plain text
1530
- return addLineNumbers(escaped);
1531
- }
1532
- }
1533
-
1534
- function highlightJavaScript(code) {
1535
- return addLineNumbers(code
1536
- .replace(/\b(function|const|let|var|if|else|for|while|return|import|export|class|extends)\b/g, '<span class="keyword">$1</span>')
1537
- .replace(/(\/\*[\s\S]*?\*\/|\/\/.*)/g, '<span class="comment">$1</span>')
1538
- .replace(/('[^']*'|"[^"]*"|`[^`]*`)/g, '<span class="string">$1</span>')
1539
- .replace(/\b(\d+)\b/g, '<span class="number">$1</span>'));
1540
- }
1541
-
1542
- function highlightPython(code) {
1543
- return addLineNumbers(code
1544
- .replace(/\b(def|class|if|elif|else|for|while|return|import|from|as|try|except|finally|with)\b/g, '<span class="keyword">$1</span>')
1545
- .replace(/(#.*)/g, '<span class="comment">$1</span>')
1546
- .replace(/('[^']*'|"[^"]*"|"""[\s\S]*?""")/g, '<span class="string">$1</span>')
1547
- .replace(/\b(\d+)\b/g, '<span class="number">$1</span>'));
1548
- }
1549
-
1550
- function highlightJSON(code) {
1551
- return addLineNumbers(code
1552
- .replace(/("[\w\s]*")\s*:/g, '<span class="property">$1</span>:')
1553
- .replace(/:\s*(".*?")/g, ': <span class="string">$1</span>')
1554
- .replace(/:\s*(\d+)/g, ': <span class="number">$1</span>')
1555
- .replace(/:\s*(true|false|null)/g, ': <span class="keyword">$1</span>'));
1556
- }
1557
-
1558
- function highlightCSS(code) {
1559
- return addLineNumbers(code
1560
- .replace(/([.#]?[\w-]+)\s*\{/g, '<span class="selector">$1</span> {')
1561
- .replace(/([\w-]+)\s*:/g, '<span class="property">$1</span>:')
1562
- .replace(/:\s*([^;]+);/g, ': <span class="value">$1</span>;')
1563
- .replace(/(\/\*[\s\S]*?\*\/)/g, '<span class="comment">$1</span>'));
1564
- }
1565
-
1566
- function highlightHTML(code) {
1567
- return addLineNumbers(code
1568
- .replace(/(&lt;\/?[\w-]+)/g, '<span class="tag">$1</span>')
1569
- .replace(/([\w-]+)=(['"][^'"]*['"])/g, '<span class="attribute">$1</span>=<span class="string">$2</span>')
1570
- .replace(/(&lt;!--[\s\S]*?--&gt;)/g, '<span class="comment">$1</span>'));
1571
- }
1572
-
1573
- function highlightMarkdown(code) {
1574
- return addLineNumbers(code
1575
- .replace(/^(#{1,6})\s+(.*)$/gm, '<span class="header">$1</span> <span class="header-text">$2</span>')
1576
- .replace(/\*\*(.*?)\*\*/g, '<span class="bold">**$1**</span>')
1577
- .replace(/\*(.*?)\*/g, '<span class="italic">*$1*</span>')
1578
- .replace(/`([^`]+)`/g, '<span class="code">`$1`</span>')
1579
- .replace(/^\s*[-*+]\s+(.*)$/gm, '<span class="list-marker">•</span> $1'));
1580
- }
1581
-
1582
- function addLineNumbers(code) {
1583
- const lines = code.split('\n');
1584
- return lines.map((line, index) =>
1585
- `<span class="line-number">${String(index + 1).padStart(3, ' ')}</span> ${line || ' '}`
1586
- ).join('\n');
1587
- }
1588
-
1589
- function formatFileSize(bytes) {
1590
- if (!bytes) return '0 B';
1591
- const k = 1024;
1592
- const sizes = ['B', 'KB', 'MB', 'GB'];
1593
- const i = Math.floor(Math.log(bytes) / Math.log(k));
1594
- return parseFloat((bytes / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i];
1595
- }
1596
-
1597
- // File Viewer Modal Functions
1598
- window.showFileViewerModal = async function(filePath) {
1599
- console.log('[FileViewer] Opening file:', filePath);
1600
-
1601
- // Use the dashboard's current working directory
1602
- let workingDir = '';
1603
- if (window.dashboard && window.dashboard.currentWorkingDir) {
1604
- workingDir = window.dashboard.currentWorkingDir;
1605
- console.log('[FileViewer] Using working directory:', workingDir);
1606
- }
1607
-
1608
- // Create modal if it doesn't exist
1609
- let modal = document.getElementById('file-viewer-modal');
1610
- if (!modal) {
1611
- console.log('[FileViewer] Creating new modal');
1612
- modal = createFileViewerModal();
1613
- document.body.appendChild(modal);
1614
-
1615
- // Small delay to ensure DOM is fully updated
1616
- await new Promise(resolve => setTimeout(resolve, 10));
1617
- }
1618
-
1619
- // Show the modal as flex container first (ensures proper rendering)
1620
- modal.style.display = 'flex';
1621
- document.body.style.overflow = 'hidden'; // Prevent background scrolling
1622
-
1623
- // Update modal content
1624
- updateFileViewerModal(modal, filePath, workingDir).catch(error => {
1625
- console.error('Error updating file viewer modal:', error);
1626
- // Show error in the modal
1627
- displayFileContentError(modal, { error: error.message });
1628
- });
1629
- };
1630
-
1631
- window.hideFileViewerModal = function() {
1632
- const modal = document.getElementById('file-viewer-modal');
1633
- if (modal) {
1634
- modal.style.display = 'none';
1635
- document.body.style.overflow = ''; // Restore background scrolling
1636
- }
1637
- };
1638
-
1639
- window.copyFileContent = function() {
1640
- const modal = document.getElementById('file-viewer-modal');
1641
- if (!modal) return;
1642
-
1643
- const codeElement = modal.querySelector('.file-content-code');
1644
- if (!codeElement) return;
1645
-
1646
- const text = codeElement.textContent;
1647
-
1648
- if (navigator.clipboard && navigator.clipboard.writeText) {
1649
- navigator.clipboard.writeText(text).then(() => {
1650
- // Show brief feedback
1651
- const button = modal.querySelector('.file-content-copy');
1652
- if (button) {
1653
- const originalText = button.textContent;
1654
- button.textContent = '✅ Copied!';
1655
- setTimeout(() => {
1656
- button.textContent = originalText;
1657
- }, 2000);
1658
- }
1659
- }).catch(err => {
1660
- console.error('Failed to copy text:', err);
1661
- });
1662
- } else {
1663
- // Fallback for older browsers
1664
- const textarea = document.createElement('textarea');
1665
- textarea.value = text;
1666
- document.body.appendChild(textarea);
1667
- textarea.select();
1668
- document.execCommand('copy');
1669
- document.body.removeChild(textarea);
1670
-
1671
- const button = modal.querySelector('.file-content-copy');
1672
- if (button) {
1673
- const originalText = button.textContent;
1674
- button.textContent = '✅ Copied!';
1675
- setTimeout(() => {
1676
- button.textContent = originalText;
1677
- }, 2000);
1678
- }
1679
- }
1680
- };
1681
-
1682
-
1683
-
1684
-
1685
- function displayFileContentError(modal, result) {
1686
- const errorArea = modal.querySelector('.file-viewer-error');
1687
- const messageElement = modal.querySelector('.error-message');
1688
- const suggestionsElement = modal.querySelector('.error-suggestions');
1689
- const loadingElement = modal.querySelector('.file-viewer-loading');
1690
- const contentArea = modal.querySelector('.file-viewer-content-area');
1691
-
1692
- // Hide loading and content areas, show error
1693
- if (loadingElement) {
1694
- loadingElement.style.display = 'none';
1695
- }
1696
- if (contentArea) {
1697
- contentArea.style.display = 'none';
1698
- }
1699
- if (errorArea) {
1700
- errorArea.style.display = 'flex';
1701
- }
1702
-
1703
- // Create user-friendly error messages
1704
- let errorMessage = result.error || 'Unknown error occurred';
1705
-
1706
- if (errorMessage.includes('not found')) {
1707
- errorMessage = '📁 File not found or not accessible';
1708
- } else if (errorMessage.includes('permission')) {
1709
- errorMessage = '🔒 Permission denied accessing this file';
1710
- } else if (errorMessage.includes('too large')) {
1711
- errorMessage = '📏 File is too large to display';
1712
- } else if (errorMessage.includes('socket connection')) {
1713
- errorMessage = '🔌 Not connected to the server. Please check your connection.';
1714
- } else if (errorMessage.includes('timeout')) {
1715
- errorMessage = '⏱️ Request timed out. The server may be busy or unresponsive.';
1716
- } else if (!errorMessage.includes('📁') && !errorMessage.includes('🔒') && !errorMessage.includes('📏')) {
1717
- errorMessage = `⚠️ ${errorMessage}`;
1718
- }
1719
-
1720
- if (messageElement) {
1721
- messageElement.textContent = errorMessage;
1722
- }
1723
-
1724
- // Add suggestions if available
1725
- if (suggestionsElement) {
1726
- if (result.suggestions && result.suggestions.length > 0) {
1727
- suggestionsElement.innerHTML = `
1728
- <h4>Suggestions:</h4>
1729
- <ul>
1730
- ${result.suggestions.map(suggestion => `<li>${suggestion}</li>`).join('')}
1731
- </ul>
1732
- `;
1733
- } else {
1734
- suggestionsElement.innerHTML = `
1735
- <h4>Try:</h4>
1736
- <ul>
1737
- <li>Check if the file exists and is readable</li>
1738
- <li>Verify file permissions</li>
1739
- <li>Ensure the monitoring server has access to this file</li>
1740
- </ul>
1741
- `;
1742
- }
1743
- }
1744
-
1745
- console.log('📋 Displaying file content error:', {
1746
- originalError: result.error,
1747
- processedMessage: errorMessage,
1748
- suggestions: result.suggestions
1749
- });
1750
-
1751
- if (errorArea) {
1752
- errorArea.style.display = 'block';
1753
- }
1754
- }
1755
-
1756
- // Search Viewer Modal Functions
1757
- window.showSearchViewerModal = function(searchParams, searchResults) {
1758
- // Create modal if it doesn't exist
1759
- let modal = document.getElementById('search-viewer-modal');
1760
- if (!modal) {
1761
- modal = createSearchViewerModal();
1762
- document.body.appendChild(modal);
1763
- }
1764
-
1765
- // Update modal content
1766
- updateSearchViewerModal(modal, searchParams, searchResults);
1767
-
1768
- // Show the modal as flex container
1769
- modal.style.display = 'flex';
1770
- document.body.style.overflow = 'hidden'; // Prevent background scrolling
1771
- };
1772
-
1773
- window.hideSearchViewerModal = function() {
1774
- const modal = document.getElementById('search-viewer-modal');
1775
- if (modal) {
1776
- modal.style.display = 'none';
1777
- document.body.style.overflow = ''; // Restore background scrolling
1778
- }
1779
- };
1780
-
1781
- function createSearchViewerModal() {
1782
- const modal = document.createElement('div');
1783
- modal.id = 'search-viewer-modal';
1784
- modal.className = 'modal search-viewer-modal';
1785
-
1786
- modal.innerHTML = `
1787
- <div class="modal-content search-viewer-content">
1788
- <div class="search-viewer-header">
1789
- <h2 class="search-viewer-title">
1790
- <span class="search-viewer-icon">🔍</span>
1791
- <span class="search-viewer-title-text">Search Results</span>
1792
- </h2>
1793
- <button class="search-viewer-close" onclick="hideSearchViewerModal()">
1794
- <span>&times;</span>
1795
- </button>
1796
- </div>
1797
- <div class="search-viewer-body">
1798
- <div class="search-params-section">
1799
- <h3>Search Parameters</h3>
1800
- <pre class="search-params-display"></pre>
1801
- </div>
1802
- <div class="search-results-section">
1803
- <h3>Search Results</h3>
1804
- <div class="search-results-display"></div>
1805
- </div>
1806
- </div>
1807
- </div>
1808
- `;
1809
-
1810
- // Close modal when clicking outside
1811
- modal.addEventListener('click', (e) => {
1812
- if (e.target === modal) {
1813
- hideSearchViewerModal();
1814
- }
1815
- });
1816
-
1817
- // Close modal on Escape key
1818
- document.addEventListener('keydown', (e) => {
1819
- if (e.key === 'Escape' && modal.style.display === 'flex') {
1820
- hideSearchViewerModal();
1821
- }
1822
- });
1823
-
1824
- return modal;
1825
- }
1826
-
1827
- function updateSearchViewerModal(modal, searchParams, searchResults) {
1828
- const paramsDisplay = modal.querySelector('.search-params-display');
1829
- const resultsDisplay = modal.querySelector('.search-results-display');
1830
-
1831
- // Display search parameters in formatted JSON
1832
- if (paramsDisplay && searchParams) {
1833
- paramsDisplay.textContent = JSON.stringify(searchParams, null, 2);
1834
- }
1835
-
1836
- // Display search results
1837
- if (resultsDisplay && searchResults) {
1838
- let resultsHTML = '';
1839
-
1840
- if (typeof searchResults === 'string') {
1841
- // If results are a string, display as preformatted text
1842
- resultsHTML = `<pre class="search-results-text">${escapeHtml(searchResults)}</pre>`;
1843
- } else if (Array.isArray(searchResults)) {
1844
- // If results are an array, display as a list
1845
- resultsHTML = '<ul class="search-results-list">';
1846
- searchResults.forEach(result => {
1847
- if (typeof result === 'object') {
1848
- resultsHTML += `<li><pre>${JSON.stringify(result, null, 2)}</pre></li>`;
1849
- } else {
1850
- resultsHTML += `<li>${escapeHtml(String(result))}</li>`;
1851
- }
1852
- });
1853
- resultsHTML += '</ul>';
1854
- } else if (typeof searchResults === 'object') {
1855
- // If results are an object, display as formatted JSON
1856
- resultsHTML = `<pre class="search-results-json">${JSON.stringify(searchResults, null, 2)}</pre>`;
1857
- } else {
1858
- // Fallback: display as text
1859
- resultsHTML = `<div class="search-results-text">${escapeHtml(String(searchResults))}</div>`;
1860
- }
1861
-
1862
- resultsDisplay.innerHTML = resultsHTML;
1863
- }
1864
- }
1865
-
1866
- function escapeHtml(text) {
1867
- const div = document.createElement('div');
1868
- div.textContent = text;
1869
- return div.innerHTML;
1870
- }
1871
-
1872
- // Global window functions for backward compatibility
1873
- window.showAgentInstanceDetails = function(instanceId) {
1874
- if (window.dashboard && typeof window.dashboard.showAgentInstanceDetails === 'function') {
1875
- window.dashboard.showAgentInstanceDetails(instanceId);
1876
- } else {
1877
- console.error('Dashboard not available or method not found');
1878
- }
1879
- };
1880
-
1881
- // Initialize dashboard when page loads
1882
- document.addEventListener('DOMContentLoaded', function() {
1883
- try {
1884
- // Create dashboard instance
1885
- window.dashboard = new Dashboard();
1886
-
1887
- // Call post-initialization setup that requires window.dashboard
1888
- // This must happen after window.dashboard is set
1889
- if (window.dashboard && typeof window.dashboard.postInit === 'function') {
1890
- window.dashboard.postInit();
1891
- }
1892
-
1893
- console.log('Dashboard loaded and initialized successfully');
1894
-
1895
- // Dispatch custom event to signal dashboard ready
1896
- document.dispatchEvent(new CustomEvent('dashboardReady', {
1897
- detail: { dashboard: window.dashboard }
1898
- }));
1899
- } catch (error) {
1900
- console.error('Failed to initialize dashboard:', error);
1901
- // Show user-friendly error message
1902
- document.body.innerHTML = `
1903
- <div style="padding: 20px; font-family: sans-serif;">
1904
- <h1>Dashboard Initialization Error</h1>
1905
- <p>The dashboard failed to load properly. Please refresh the page or check the console for details.</p>
1906
- <pre style="background: #f5f5f5; padding: 10px; border-radius: 4px;">${error.message}</pre>
1907
- </div>
1908
- `;
1909
- }
1910
- });
1911
-
1912
- // ES6 Module export
1913
- export { Dashboard };
1914
- export default Dashboard;