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,1824 +0,0 @@
1
- /**
2
- * Unified Data Viewer Component
3
- *
4
- * Consolidates all data formatting and display logic from event-driven tabs
5
- * (Activity, Events, Agents) into a single, reusable component.
6
- *
7
- * WHY: Eliminates code duplication across multiple components and provides
8
- * consistent data display formatting throughout the dashboard.
9
- *
10
- * DESIGN DECISION: Auto-detects data type and applies appropriate formatting,
11
- * while allowing manual type specification for edge cases.
12
- */
13
-
14
- class UnifiedDataViewer {
15
- constructor(containerId = 'module-data-content') {
16
- this.container = document.getElementById(containerId);
17
- this.currentData = null;
18
- this.currentType = null;
19
-
20
- // Global JSON visibility state - synchronized with localStorage
21
- // This ensures all JSON sections maintain consistent state
22
- this.globalJsonExpanded = localStorage.getItem('dashboard-json-expanded') === 'true';
23
-
24
- // Separate state for "Full Event Data" sections - uses its own localStorage key
25
- // This allows independent control of Full Event Data visibility
26
- this.fullEventDataExpanded = localStorage.getItem('dashboard-full-event-expanded') === 'true';
27
-
28
- // Listen for global JSON toggle changes from other components
29
- document.addEventListener('jsonToggleChanged', (e) => {
30
- this.globalJsonExpanded = e.detail.expanded;
31
- this.updateAllJsonSections();
32
- });
33
-
34
- // Listen for full event data toggle changes
35
- document.addEventListener('fullEventToggleChanged', (e) => {
36
- this.fullEventDataExpanded = e.detail.expanded;
37
- this.updateAllFullEventSections();
38
- });
39
- }
40
-
41
- /**
42
- * Main display method - auto-detects type and renders data
43
- * @param {Object|Array} data - Data to display
44
- * @param {string|null} type - Optional type override
45
- */
46
- display(data, type = null) {
47
- if (!this.container) {
48
- console.warn('UnifiedDataViewer: Container not found');
49
- return;
50
- }
51
-
52
- // Store current data for reference
53
- this.currentData = data;
54
- this.currentType = type;
55
-
56
- // Auto-detect type if not provided
57
- if (!type) {
58
- type = this.detectType(data);
59
- }
60
-
61
- // Clear container
62
- this.container.innerHTML = '';
63
-
64
- // Display based on type
65
- switch(type) {
66
- case 'event':
67
- this.displayEvent(data);
68
- break;
69
- case 'agent':
70
- this.displayAgent(data);
71
- break;
72
- case 'tool':
73
- this.displayTool(data);
74
- break;
75
- case 'todo':
76
- this.displayTodo(data);
77
- break;
78
- case 'instruction':
79
- this.displayInstruction(data);
80
- break;
81
- case 'session':
82
- this.displaySession(data);
83
- break;
84
- case 'file_operation':
85
- // Convert file tool to file operation format if needed
86
- if (data.name && (data.params || data.tool_parameters)) {
87
- const convertedData = this.convertToolToFileOperation(data);
88
- this.displayFileOperation(convertedData);
89
- } else {
90
- this.displayFileOperation(data);
91
- }
92
- break;
93
- case 'hook':
94
- this.displayHook(data);
95
- break;
96
- default:
97
- this.displayGeneric(data);
98
- }
99
- }
100
-
101
- /**
102
- * Auto-detect data type based on object properties
103
- * @param {Object} data - Data to analyze
104
- * @returns {string} Detected type
105
- */
106
- detectType(data) {
107
- if (!data || typeof data !== 'object') return 'generic';
108
-
109
- // Event detection
110
- if (data.hook_event_name || data.event_type || (data.type && data.timestamp)) {
111
- return 'event';
112
- }
113
-
114
- // Agent detection
115
- if (data.agent_name || data.agentName ||
116
- (data.name && (data.status === 'active' || data.status === 'completed'))) {
117
- return 'agent';
118
- }
119
-
120
- // Tool detection - PRIORITY: Check if it's a tool first
121
- // This includes TodoWrite tools which should always be displayed as tools, not todos
122
- if (data.tool_name || data.name === 'TodoWrite' || data.name === 'Read' ||
123
- data.tool_parameters || (data.params && data.icon) ||
124
- (data.name && data.type === 'tool')) {
125
- return 'tool';
126
- }
127
-
128
- // Todo detection - Only for standalone todo lists, not tool todos
129
- if (data.todos && !data.name && !data.params) {
130
- return 'todo';
131
- }
132
-
133
- // Single todo item detection
134
- if (data.content && data.activeForm && data.status && !data.name && !data.params) {
135
- return 'todo';
136
- }
137
-
138
- // Instruction detection
139
- if (data.text && data.preview && data.type === 'user_instruction') {
140
- return 'instruction';
141
- }
142
-
143
- // Session detection
144
- if (data.session_id && (data.startTime || data.lastActivity)) {
145
- return 'session';
146
- }
147
-
148
- // File operation detection
149
- if (data.file_path && (data.operations || data.operation)) {
150
- return 'file_operation';
151
- }
152
-
153
- // File tool detection - handle file tools as file operations when they have file_path
154
- if ((data.name === 'Read' || data.name === 'Write' || data.name === 'Edit' ||
155
- data.name === 'MultiEdit' || data.name === 'Grep' || data.name === 'Glob') &&
156
- (data.params?.file_path || data.tool_parameters?.file_path)) {
157
- // Convert file tool to file operation format for better display
158
- return 'file_operation';
159
- }
160
-
161
- // Hook detection
162
- if (data.event_type && (data.hook_name || data.subtype)) {
163
- return 'hook';
164
- }
165
-
166
- return 'generic';
167
- }
168
-
169
- /**
170
- * Display event data with comprehensive formatting
171
- * PRIMARY: Event type, timestamp, and key details
172
- * SECONDARY: Full event data in collapsible JSON
173
- */
174
- displayEvent(data) {
175
- const eventType = this.formatEventType(data);
176
- const timestamp = this.formatTimestamp(data.timestamp);
177
-
178
- let html = `
179
- <div class="unified-viewer-header">
180
- <h6>${eventType}</h6>
181
- <span class="unified-viewer-timestamp">${timestamp}</span>
182
- </div>
183
- <div class="unified-viewer-content">
184
- `;
185
-
186
- // PRIMARY DATA: Event-specific key details
187
- html += `<div class="primary-data">`;
188
- html += this.formatEventDetails(data);
189
-
190
- // Show important tool parameters inline if present
191
- if (data.tool_name || data.data?.tool_name) {
192
- const toolName = data.tool_name || data.data.tool_name;
193
- html += `
194
- <div class="detail-row highlight">
195
- <span class="detail-label">Tool:</span>
196
- <span class="detail-value">${this.getToolIcon(toolName)} ${toolName}</span>
197
- </div>
198
- `;
199
-
200
- // Show key parameters for specific tools
201
- const params = data.tool_parameters || data.data?.tool_parameters;
202
- if (params) {
203
- if (params.file_path) {
204
- html += `
205
- <div class="detail-row">
206
- <span class="detail-label">File:</span>
207
- <span class="detail-value code">${params.file_path}</span>
208
- </div>
209
- `;
210
- }
211
- if (params.command) {
212
- html += `
213
- <div class="detail-row">
214
- <span class="detail-label">Command:</span>
215
- <pre class="code-snippet">${this.escapeHtml(params.command)}</pre>
216
- </div>
217
- `;
218
- }
219
- }
220
- }
221
- html += `</div>`;
222
-
223
- // SECONDARY DATA: Collapsible JSON viewer for full event data
224
- html += this.createCollapsibleJSON(data, 'Full Event Data');
225
-
226
- html += '</div>';
227
- this.container.innerHTML = html;
228
- }
229
-
230
- /**
231
- * Display agent data with full details
232
- * PRIMARY: Agent status, active tools, and key info
233
- * SECONDARY: Full agent data in collapsible JSON
234
- */
235
- displayAgent(data) {
236
- const agentIcon = this.getAgentIcon(data.name || data.agentName);
237
- const agentName = data.name || data.agentName || 'Unknown Agent';
238
- const status = this.formatStatus(data.status);
239
-
240
- let html = `
241
- <div class="unified-viewer-header">
242
- <h6>${agentIcon} ${agentName}</h6>
243
- <span class="unified-viewer-status">${status}</span>
244
- </div>
245
- <div class="unified-viewer-content">
246
- `;
247
-
248
- // PRIMARY DATA: Key agent information
249
- html += `<div class="primary-data">`;
250
-
251
- // Status with visual indicator
252
- html += `
253
- <div class="detail-row highlight">
254
- <span class="detail-label">Status:</span>
255
- <span class="detail-value ${this.formatStatusClass(status)}">${status}</span>
256
- </div>
257
- `;
258
-
259
- // Tools summary if present
260
- if (data.tools && data.tools.length > 0) {
261
- // Show active tools prominently
262
- const activeTools = data.tools.filter(t => t.status === 'in_progress');
263
- const completedTools = data.tools.filter(t => t.status === 'completed');
264
-
265
- if (activeTools.length > 0) {
266
- html += `
267
- <div class="active-tools-section">
268
- <span class="section-label">🔄 Active Tools:</span>
269
- <div class="tools-grid">
270
- `;
271
- activeTools.forEach(tool => {
272
- html += `
273
- <div class="tool-chip active">
274
- ${this.getToolIcon(tool.name)} ${tool.name}
275
- </div>
276
- `;
277
- });
278
- html += `</div></div>`;
279
- }
280
-
281
- html += `
282
- <div class="detail-row">
283
- <span class="detail-label">Tools Summary:</span>
284
- <span class="detail-value">
285
- ${activeTools.length} active, ${completedTools.length} completed, ${data.tools.length} total
286
- </span>
287
- </div>
288
- `;
289
- }
290
-
291
- // Current task if available
292
- if (data.currentTask || data.description) {
293
- html += `
294
- <div class="detail-row">
295
- <span class="detail-label">Current Task:</span>
296
- <span class="detail-value">${data.currentTask || data.description}</span>
297
- </div>
298
- `;
299
- }
300
-
301
- html += `</div>`;
302
-
303
- // SECONDARY DATA: Collapsible JSON viewer
304
- html += this.createCollapsibleJSON(data, 'Full Agent Details');
305
-
306
- html += '</div>';
307
- this.container.innerHTML = html;
308
- }
309
-
310
- /**
311
- * Display tool data with parameters and results
312
- * Special handling for TodoWrite to show todos prominently
313
- */
314
- displayTool(data) {
315
- const toolName = data.name || data.tool_name || 'Unknown Tool';
316
- const toolIcon = this.getToolIcon(toolName);
317
- const status = this.formatStatus(data.status);
318
-
319
- // Special handling for TodoWrite tool
320
- if (toolName === 'TodoWrite') {
321
- this.displayTodoWriteTool(data);
322
- return;
323
- }
324
-
325
- let html = `
326
- <div class="unified-viewer-header">
327
- <h6>${toolIcon} ${toolName}</h6>
328
- <span class="unified-viewer-status">${status}</span>
329
- </div>
330
- <div class="unified-viewer-content">
331
- `;
332
-
333
- // PRIMARY DATA: Show important tool-specific information first
334
- const params = data.params || data.tool_parameters || {};
335
-
336
- // Tool-specific primary data display
337
- if (toolName === 'Read' || toolName === 'Edit' || toolName === 'Write') {
338
- // File tools - show file path prominently
339
- if (params.file_path) {
340
- html += `
341
- <div class="primary-data">
342
- <div class="detail-row highlight">
343
- <span class="detail-label">📁 File:</span>
344
- <span class="detail-value code">${params.file_path}</span>
345
- </div>
346
- `;
347
- if (params.old_string) {
348
- html += `
349
- <div class="detail-row">
350
- <span class="detail-label">Old Text:</span>
351
- <pre class="code-snippet">${this.escapeHtml(params.old_string.substring(0, 200))}${params.old_string.length > 200 ? '...' : ''}</pre>
352
- </div>
353
- `;
354
- }
355
- if (params.new_string) {
356
- html += `
357
- <div class="detail-row">
358
- <span class="detail-label">New Text:</span>
359
- <pre class="code-snippet">${this.escapeHtml(params.new_string.substring(0, 200))}${params.new_string.length > 200 ? '...' : ''}</pre>
360
- </div>
361
- `;
362
- }
363
- html += '</div>';
364
- }
365
- } else if (toolName === 'Bash') {
366
- // Bash tool - show command prominently
367
- if (params.command) {
368
- html += `
369
- <div class="primary-data">
370
- <div class="detail-row highlight">
371
- <span class="detail-label">💻 Command:</span>
372
- <pre class="code-snippet">${this.escapeHtml(params.command)}</pre>
373
- </div>
374
- </div>
375
- `;
376
- }
377
- } else if (toolName === 'Grep' || toolName === 'Glob') {
378
- // Search tools - show pattern prominently
379
- if (params.pattern) {
380
- html += `
381
- <div class="primary-data">
382
- <div class="detail-row highlight">
383
- <span class="detail-label">🔍 Pattern:</span>
384
- <span class="detail-value code">${this.escapeHtml(params.pattern)}</span>
385
- </div>
386
- `;
387
- if (params.path) {
388
- html += `
389
- <div class="detail-row">
390
- <span class="detail-label">Path:</span>
391
- <span class="detail-value">${params.path}</span>
392
- </div>
393
- `;
394
- }
395
- html += '</div>';
396
- }
397
- } else if (toolName === 'Task') {
398
- // Task tool - show delegation info prominently
399
- if (params.subagent_type) {
400
- html += `
401
- <div class="primary-data">
402
- <div class="detail-row highlight">
403
- <span class="detail-label">🤖 Delegating to:</span>
404
- <span class="detail-value">${params.subagent_type} agent</span>
405
- </div>
406
- `;
407
- if (params.description) {
408
- html += `
409
- <div class="detail-row">
410
- <span class="detail-label">Task:</span>
411
- <span class="detail-value">${params.description}</span>
412
- </div>
413
- `;
414
- }
415
- html += '</div>';
416
- }
417
- }
418
-
419
- // Status and metadata
420
- html += `
421
- <div class="detail-row">
422
- <span class="detail-label">Status:</span>
423
- <span class="detail-value">${status}</span>
424
- </div>
425
- `;
426
-
427
- if (data.callCount) {
428
- html += `
429
- <div class="detail-row">
430
- <span class="detail-label">Call Count:</span>
431
- <span class="detail-value">${data.callCount}</span>
432
- </div>
433
- `;
434
- }
435
-
436
- // Collapsible JSON viewer for full details
437
- html += this.createCollapsibleJSON(data, 'Full Tool Details');
438
-
439
- html += '</div>';
440
- this.container.innerHTML = html;
441
- }
442
-
443
- /**
444
- * Display TodoWrite tool with todos list prominently after title
445
- */
446
- displayTodoWriteTool(data) {
447
- const status = this.formatStatus(data.status);
448
- const params = data.params || data.tool_parameters || {};
449
- const todos = params.todos || [];
450
-
451
- let html = `
452
- <div class="unified-viewer-header">
453
- <h6>📝 TodoWrite</h6>
454
- <span class="unified-viewer-status">${status}</span>
455
- </div>
456
- <div class="unified-viewer-content">
457
- `;
458
-
459
- // PRIMARY DATA: Todo list and status summary immediately after title
460
- if (todos.length > 0) {
461
- const statusCounts = this.getTodoStatusCounts(todos);
462
-
463
- // Status summary - horizontal single line format
464
- html += `
465
- <div class="todo-status-line">
466
- <span class="status-inline">✅ ${statusCounts.completed} Done</span>
467
- <span class="status-inline">🔄 ${statusCounts.in_progress} Active</span>
468
- <span class="status-inline">⏳ ${statusCounts.pending} Pending</span>
469
- </div>
470
- `;
471
-
472
- // Todo items list
473
- html += `
474
- <div class="todo-list-primary">
475
- `;
476
-
477
- todos.forEach((todo, index) => {
478
- const statusIcon = this.getCheckboxIcon(todo.status);
479
- const displayText = todo.status === 'in_progress' ?
480
- (todo.activeForm || todo.content) : todo.content;
481
- const statusClass = this.formatStatusClass(todo.status);
482
-
483
- html += `
484
- <div class="todo-item ${todo.status}">
485
- <span class="todo-icon ${statusClass}">${statusIcon}</span>
486
- <span class="todo-text">${this.escapeHtml(displayText)}</span>
487
- ${todo.status === 'in_progress' ? '<span class="todo-badge active">ACTIVE</span>' : ''}
488
- </div>
489
- `;
490
- });
491
-
492
- html += `
493
- </div>
494
- `;
495
- } else {
496
- html += `
497
- <div class="detail-row">
498
- <span class="detail-value">No todos in list</span>
499
- </div>
500
- `;
501
- }
502
-
503
- // Metadata section
504
- if (data.callCount && data.callCount > 1) {
505
- html += `
506
- <div class="detail-row">
507
- <span class="detail-label">Updates:</span>
508
- <span class="detail-value">${data.callCount}</span>
509
- </div>
510
- `;
511
- }
512
-
513
- // Collapsible JSON viewer for full details
514
- html += this.createCollapsibleJSON(data, 'Full Details');
515
-
516
- html += '</div>';
517
- this.container.innerHTML = html;
518
- }
519
-
520
- /**
521
- * Display todo data with checklist formatting (for standalone todos, not TodoWrite)
522
- */
523
- displayTodo(data) {
524
- // Handle different data structures for standalone todos
525
- let todos;
526
- let toolName = 'Todo List';
527
-
528
- if (data.todos && Array.isArray(data.todos)) {
529
- todos = data.todos;
530
- } else if (Array.isArray(data)) {
531
- todos = data;
532
- } else if (data.content && data.activeForm && data.status) {
533
- todos = [data];
534
- } else {
535
- todos = [];
536
- }
537
-
538
- let html = `
539
- <div class="unified-viewer-header">
540
- <h6>📋 ${toolName}</h6>
541
- </div>
542
- <div class="unified-viewer-content">
543
- `;
544
-
545
- if (todos.length > 0) {
546
- // Show todos immediately
547
- html += `
548
- <div class="todo-list-primary">
549
- `;
550
-
551
- todos.forEach((todo) => {
552
- const statusIcon = this.getCheckboxIcon(todo.status);
553
- const displayText = todo.status === 'in_progress' ?
554
- (todo.activeForm || todo.content) : todo.content;
555
- const statusClass = this.formatStatusClass(todo.status);
556
-
557
- html += `
558
- <div class="todo-item ${todo.status}">
559
- <span class="todo-icon ${statusClass}">${statusIcon}</span>
560
- <span class="todo-text">${this.escapeHtml(displayText)}</span>
561
- <span class="todo-status-text ${statusClass}">${todo.status.replace('_', ' ')}</span>
562
- </div>
563
- `;
564
- });
565
-
566
- html += `
567
- </div>
568
- `;
569
- } else {
570
- html += `
571
- <div class="detail-section">
572
- <div class="no-todos">No todo items found</div>
573
- </div>
574
- `;
575
- }
576
-
577
- html += '</div>';
578
- this.container.innerHTML = html;
579
- }
580
-
581
- /**
582
- * Display instruction data
583
- * PRIMARY: Instruction text prominently displayed
584
- * SECONDARY: Metadata in collapsible section
585
- */
586
- displayInstruction(data) {
587
- let html = `
588
- <div class="unified-viewer-header">
589
- <h6>💬 User Instruction</h6>
590
- <span class="unified-viewer-timestamp">${this.formatTimestamp(data.timestamp)}</span>
591
- </div>
592
- <div class="unified-viewer-content">
593
- `;
594
-
595
- // PRIMARY DATA: The instruction text itself
596
- html += `
597
- <div class="primary-data">
598
- <div class="instruction-content">
599
- ${this.escapeHtml(data.text)}
600
- </div>
601
- <div class="instruction-meta">
602
- <span class="meta-item">📏 ${data.text.length} characters</span>
603
- <span class="meta-item">🕐 ${this.formatTimestamp(data.timestamp)}</span>
604
- </div>
605
- </div>
606
- `;
607
-
608
- // SECONDARY DATA: Full instruction object if there's more data
609
- if (Object.keys(data).length > 3) {
610
- html += this.createCollapsibleJSON(data, 'Full Instruction Data');
611
- }
612
-
613
- html += '</div>';
614
- this.container.innerHTML = html;
615
- }
616
-
617
- /**
618
- * Display session data
619
- */
620
- displaySession(data) {
621
- let html = `
622
- <div class="unified-viewer-header">
623
- <h6>🎯 Session: ${data.session_id || data.id}</h6>
624
- <span class="unified-viewer-status">${this.formatStatus(data.status || 'active')}</span>
625
- </div>
626
- <div class="unified-viewer-content">
627
- <div class="detail-row">
628
- <span class="detail-label">Session ID:</span>
629
- <span class="detail-value">${data.session_id || data.id}</span>
630
- </div>
631
- <div class="detail-row">
632
- <span class="detail-label">Start Time:</span>
633
- <span class="detail-value">${this.formatTimestamp(data.startTime || data.timestamp)}</span>
634
- </div>
635
- `;
636
-
637
- if (data.working_directory) {
638
- html += `
639
- <div class="detail-row">
640
- <span class="detail-label">Working Directory:</span>
641
- <span class="detail-value">${data.working_directory}</span>
642
- </div>
643
- `;
644
- }
645
-
646
- if (data.git_branch) {
647
- html += `
648
- <div class="detail-row">
649
- <span class="detail-label">Git Branch:</span>
650
- <span class="detail-value">${data.git_branch}</span>
651
- </div>
652
- `;
653
- }
654
-
655
- if (data.eventCount !== undefined) {
656
- html += `
657
- <div class="detail-row">
658
- <span class="detail-label">Events:</span>
659
- <span class="detail-value">${data.eventCount}</span>
660
- </div>
661
- `;
662
- }
663
-
664
- html += '</div>';
665
- this.container.innerHTML = html;
666
- }
667
-
668
- /**
669
- * Display file operation data with enhanced file viewing capabilities
670
- */
671
- displayFileOperation(data) {
672
- const fileName = data.file_path ? data.file_path.split('/').pop() : 'Unknown File';
673
- const isSingleFile = this.isSingleFileOperation(data);
674
- const fileIcon = this.getFileIcon(data.file_path);
675
- const fileType = this.getFileType(data.file_path);
676
-
677
- let html = `
678
- <div class="unified-viewer-header ${isSingleFile ? 'single-file-header' : ''}">
679
- <h6>${fileIcon} File: ${fileName}</h6>
680
- <span class="unified-viewer-count">${data.operations ? data.operations.length : 1} operation${data.operations && data.operations.length !== 1 ? 's' : ''}</span>
681
- ${fileType ? `<span class="file-type-badge">${fileType}</span>` : ''}
682
- </div>
683
- <div class="unified-viewer-content">
684
- <div class="primary-data">
685
- <div class="detail-row highlight">
686
- <span class="detail-label">📁 File Path:</span>
687
- <span class="detail-value code clickable-file-path"
688
- onclick="window.showFileViewerModal && window.showFileViewerModal('${data.file_path}')"
689
- title="Click to view file contents\\nKeyboard: Hover + V key or Ctrl/Cmd + Click\\nFile: ${data.file_path}"
690
- tabindex="0"
691
- role="button"
692
- aria-label="Open file ${data.file_path} in viewer"
693
- onkeypress="if(event.key==='Enter'||event.key===' '){window.showFileViewerModal && window.showFileViewerModal('${data.file_path}')}">${data.file_path}</span>
694
- </div>
695
- `;
696
-
697
- // Enhanced file viewing for single file operations
698
- if (data.file_path) {
699
- const shouldShowPreview = this.shouldShowInlinePreview(data);
700
-
701
- html += `
702
- <div class="file-actions ${isSingleFile ? 'single-file-actions' : ''}">
703
- <button class="file-action-btn view-file-btn ${isSingleFile ? 'primary-action' : ''}"
704
- onclick="window.showFileViewerModal && window.showFileViewerModal('${data.file_path}')"
705
- title="View file contents with syntax highlighting">
706
- ${fileIcon} View File Contents
707
- </button>
708
- ${isSingleFile && this.isTextFile(data.file_path) ? `
709
- <button class="file-action-btn inline-preview-btn"
710
- onclick="window.unifiedDataViewer && window.unifiedDataViewer.toggleInlinePreview('${data.file_path}', this)"
711
- title="Toggle inline preview">
712
- 📖 Quick Preview
713
- </button>
714
- ` : ''}
715
- </div>
716
- `;
717
-
718
- // Add inline preview container for single file operations
719
- if (isSingleFile && shouldShowPreview) {
720
- const previewId = this.generatePreviewId(data.file_path);
721
- html += `
722
- <div class="inline-preview-container" id="preview-${previewId}" style="display: none;">
723
- <div class="inline-preview-loading">Loading preview...</div>
724
- </div>
725
- `;
726
- }
727
- }
728
-
729
- html += `</div>`;
730
-
731
- if (data.operations && Array.isArray(data.operations)) {
732
- html += `
733
- <div class="detail-section">
734
- <span class="detail-section-title">Operations (${data.operations.length}):</span>
735
- <div class="operations-list">
736
- ${data.operations.map((op, index) => `
737
- <div class="operation-item">
738
- <div class="operation-header">
739
- <span class="operation-type">${this.getOperationIcon(op.operation)} ${op.operation}</span>
740
- <span class="operation-timestamp">${this.formatTimestamp(op.timestamp)}</span>
741
- </div>
742
- <div class="operation-details">
743
- <span class="operation-agent">by ${op.agent || 'Unknown'}</span>
744
- ${op.workingDirectory ? `<span class="operation-dir">in ${op.workingDirectory}</span>` : ''}
745
- </div>
746
- </div>
747
- `).join('')}
748
- </div>
749
- </div>
750
- `;
751
- }
752
-
753
- // Add collapsible JSON viewer for full file data
754
- html += this.createCollapsibleJSON(data, 'Full File Data');
755
-
756
- html += '</div>';
757
- this.container.innerHTML = html;
758
- }
759
-
760
- /**
761
- * Display hook event data
762
- */
763
- displayHook(data) {
764
- const hookType = data.event_type || data.subtype || 'unknown';
765
-
766
- let html = `
767
- <div class="unified-viewer-header">
768
- <h6>🔗 Hook: ${hookType}</h6>
769
- <span class="unified-viewer-timestamp">${this.formatTimestamp(data.timestamp)}</span>
770
- </div>
771
- <div class="unified-viewer-content">
772
- `;
773
-
774
- html += this.formatHookDetails(data);
775
- html += '</div>';
776
- this.container.innerHTML = html;
777
- }
778
-
779
- /**
780
- * Display generic data with fallback formatting
781
- */
782
- displayGeneric(data) {
783
- let html = `
784
- <div class="unified-viewer-header">
785
- <h6>📊 Data Details</h6>
786
- ${data.timestamp ? `<span class="unified-viewer-timestamp">${this.formatTimestamp(data.timestamp)}</span>` : ''}
787
- </div>
788
- <div class="unified-viewer-content">
789
- `;
790
-
791
- if (typeof data === 'object' && data !== null) {
792
- // Display meaningful properties
793
- const meaningfulProps = ['id', 'name', 'type', 'status', 'timestamp', 'text', 'content', 'message'];
794
-
795
- for (let prop of meaningfulProps) {
796
- if (data[prop] !== undefined) {
797
- let value = data[prop];
798
- if (typeof value === 'string' && value.length > 200) {
799
- value = value.substring(0, 200) + '...';
800
- }
801
-
802
- html += `
803
- <div class="detail-row">
804
- <span class="detail-label">${prop}:</span>
805
- <span class="detail-value">${this.escapeHtml(String(value))}</span>
806
- </div>
807
- `;
808
- }
809
- }
810
- } else {
811
- html += `<div class="simple-value">${this.escapeHtml(String(data))}</div>`;
812
- }
813
-
814
- html += '</div>';
815
- this.container.innerHTML = html;
816
- }
817
-
818
- // ==================== FORMATTING UTILITIES ====================
819
-
820
- /**
821
- * Format event type for display
822
- */
823
- formatEventType(event) {
824
- if (event.type && event.subtype) {
825
- if (event.type === event.subtype || event.subtype === 'generic') {
826
- return event.type;
827
- }
828
- return `${event.type}.${event.subtype}`;
829
- }
830
- if (event.type) return event.type;
831
- if (event.hook_event_name) return event.hook_event_name;
832
- return 'unknown';
833
- }
834
-
835
- /**
836
- * Format detailed event data based on type
837
- */
838
- formatEventDetails(event) {
839
- const data = event.data || {};
840
-
841
- switch (event.type) {
842
- case 'hook':
843
- return this.formatHookDetails(event);
844
- case 'agent':
845
- return this.formatAgentEventDetails(event);
846
- case 'todo':
847
- return this.formatTodoEventDetails(event);
848
- case 'session':
849
- return this.formatSessionEventDetails(event);
850
- default:
851
- return this.formatGenericEventDetails(event);
852
- }
853
- }
854
-
855
- /**
856
- * Format hook event details
857
- */
858
- formatHookDetails(event) {
859
- const data = event.data || {};
860
- const hookType = event.subtype || event.event_type || 'unknown';
861
-
862
- let html = `
863
- <div class="detail-row">
864
- <span class="detail-label">Hook Type:</span>
865
- <span class="detail-value">${hookType}</span>
866
- </div>
867
- `;
868
-
869
- switch (hookType) {
870
- case 'user_prompt':
871
- const prompt = data.prompt_text || data.prompt_preview || '';
872
- html += `
873
- <div class="detail-row">
874
- <span class="detail-label">Prompt:</span>
875
- <div class="detail-value prompt-text">${this.escapeHtml(prompt)}</div>
876
- </div>
877
- `;
878
- break;
879
-
880
- case 'pre_tool':
881
- case 'post_tool':
882
- const toolName = data.tool_name || 'Unknown tool';
883
- html += `
884
- <div class="detail-row">
885
- <span class="detail-label">Tool:</span>
886
- <span class="detail-value">${toolName}</span>
887
- </div>
888
- `;
889
- if (data.operation_type) {
890
- html += `
891
- <div class="detail-row">
892
- <span class="detail-label">Operation:</span>
893
- <span class="detail-value">${data.operation_type}</span>
894
- </div>
895
- `;
896
- }
897
- if (hookType === 'post_tool' && data.duration_ms) {
898
- html += `
899
- <div class="detail-row">
900
- <span class="detail-label">Duration:</span>
901
- <span class="detail-value">${data.duration_ms}ms</span>
902
- </div>
903
- `;
904
- }
905
- break;
906
-
907
- case 'subagent_start':
908
- case 'subagent_stop':
909
- const agentType = data.agent_type || data.agent || 'Unknown';
910
- html += `
911
- <div class="detail-row">
912
- <span class="detail-label">Agent:</span>
913
- <span class="detail-value">${agentType}</span>
914
- </div>
915
- `;
916
- if (hookType === 'subagent_start' && data.prompt) {
917
- html += `
918
- <div class="detail-row">
919
- <span class="detail-label">Task:</span>
920
- <div class="detail-value">${this.escapeHtml(data.prompt)}</div>
921
- </div>
922
- `;
923
- }
924
- if (hookType === 'subagent_stop' && data.reason) {
925
- html += `
926
- <div class="detail-row">
927
- <span class="detail-label">Reason:</span>
928
- <span class="detail-value">${data.reason}</span>
929
- </div>
930
- `;
931
- }
932
- break;
933
- }
934
-
935
- return html;
936
- }
937
-
938
- /**
939
- * Format agent event details
940
- */
941
- formatAgentEventDetails(event) {
942
- const data = event.data || {};
943
- let html = '';
944
-
945
- if (data.agent_type || data.name) {
946
- html += `
947
- <div class="detail-row">
948
- <span class="detail-label">Agent Type:</span>
949
- <span class="detail-value">${data.agent_type || data.name}</span>
950
- </div>
951
- `;
952
- }
953
-
954
- if (event.subtype) {
955
- html += `
956
- <div class="detail-row">
957
- <span class="detail-label">Action:</span>
958
- <span class="detail-value">${event.subtype}</span>
959
- </div>
960
- `;
961
- }
962
-
963
- return html;
964
- }
965
-
966
- /**
967
- * Format todo event details
968
- */
969
- formatTodoEventDetails(event) {
970
- const data = event.data || {};
971
- let html = '';
972
-
973
- if (data.todos && Array.isArray(data.todos)) {
974
- const statusCounts = this.getTodoStatusCounts(data.todos);
975
- html += `
976
- <div class="detail-row">
977
- <span class="detail-label">Todo Items:</span>
978
- <span class="detail-value">${data.todos.length} total</span>
979
- </div>
980
- <div class="detail-row">
981
- <span class="detail-label">Status:</span>
982
- <span class="detail-value">${statusCounts.completed} completed, ${statusCounts.in_progress} in progress</span>
983
- </div>
984
- `;
985
- }
986
-
987
- return html;
988
- }
989
-
990
- /**
991
- * Format session event details
992
- */
993
- formatSessionEventDetails(event) {
994
- const data = event.data || {};
995
- let html = '';
996
-
997
- if (data.session_id) {
998
- html += `
999
- <div class="detail-row">
1000
- <span class="detail-label">Session ID:</span>
1001
- <span class="detail-value">${data.session_id}</span>
1002
- </div>
1003
- `;
1004
- }
1005
-
1006
- if (event.subtype) {
1007
- html += `
1008
- <div class="detail-row">
1009
- <span class="detail-label">Action:</span>
1010
- <span class="detail-value">${event.subtype}</span>
1011
- </div>
1012
- `;
1013
- }
1014
-
1015
- return html;
1016
- }
1017
-
1018
- /**
1019
- * Format generic event details
1020
- */
1021
- formatGenericEventDetails(event) {
1022
- const data = event.data || {};
1023
- let html = '';
1024
-
1025
- // Show basic data properties
1026
- const basicProps = ['message', 'description', 'value', 'result'];
1027
- for (let prop of basicProps) {
1028
- if (data[prop] !== undefined) {
1029
- let value = data[prop];
1030
- if (typeof value === 'string' && value.length > 200) {
1031
- value = value.substring(0, 200) + '...';
1032
- }
1033
- html += `
1034
- <div class="detail-row">
1035
- <span class="detail-label">${prop}:</span>
1036
- <span class="detail-value">${this.escapeHtml(String(value))}</span>
1037
- </div>
1038
- `;
1039
- }
1040
- }
1041
-
1042
- return html;
1043
- }
1044
-
1045
- /**
1046
- * Format event data section
1047
- */
1048
- formatEventData(event) {
1049
- const data = event.data;
1050
- if (!data || Object.keys(data).length === 0) return '';
1051
-
1052
- return `
1053
- <div class="detail-section">
1054
- <span class="detail-section-title">Event Data:</span>
1055
- <pre class="event-data-json">${this.escapeHtml(JSON.stringify(data, null, 2))}</pre>
1056
- </div>
1057
- `;
1058
- }
1059
-
1060
- /**
1061
- * Format tool/event parameters
1062
- */
1063
- formatParameters(params, title = 'Parameters') {
1064
- if (!params || Object.keys(params).length === 0) {
1065
- return `
1066
- <div class="detail-section">
1067
- <span class="detail-section-title">${title}:</span>
1068
- <div class="no-params">No parameters</div>
1069
- </div>
1070
- `;
1071
- }
1072
-
1073
- const paramKeys = Object.keys(params);
1074
- return `
1075
- <div class="detail-section">
1076
- <span class="detail-section-title">${title} (${paramKeys.length}):</span>
1077
- <div class="params-list">
1078
- ${paramKeys.map(key => {
1079
- const value = params[key];
1080
- const displayValue = this.formatParameterValue(value);
1081
- return `
1082
- <div class="param-item">
1083
- <div class="param-key">${key}:</div>
1084
- <div class="param-value">${displayValue}</div>
1085
- </div>
1086
- `;
1087
- }).join('')}
1088
- </div>
1089
- </div>
1090
- `;
1091
- }
1092
-
1093
- /**
1094
- * Format parameter value with appropriate styling
1095
- */
1096
- formatParameterValue(value) {
1097
- if (typeof value === 'string') {
1098
- if (value.length > 500) {
1099
- return `<pre class="param-text-long">${this.escapeHtml(value.substring(0, 500) + '...\n\n[Content truncated - ' + value.length + ' total characters]')}</pre>`;
1100
- } else if (value.length > 100) {
1101
- return `<pre class="param-text">${this.escapeHtml(value)}</pre>`;
1102
- } else {
1103
- return `<span class="param-text-short">${this.escapeHtml(value)}</span>`;
1104
- }
1105
- } else if (typeof value === 'object' && value !== null) {
1106
- // Special handling for todos array - display as formatted list instead of raw JSON
1107
- if (Array.isArray(value) && value.length > 0 &&
1108
- value[0].hasOwnProperty('content') && value[0].hasOwnProperty('status')) {
1109
- return this.formatTodosAsParameter(value);
1110
- }
1111
-
1112
- try {
1113
- return `<pre class="param-json">${this.escapeHtml(JSON.stringify(value, null, 2))}</pre>`;
1114
- } catch (e) {
1115
- return `<span class="param-error">Error displaying object</span>`;
1116
- }
1117
- } else {
1118
- return `<span class="param-primitive">${this.escapeHtml(String(value))}</span>`;
1119
- }
1120
- }
1121
-
1122
- /**
1123
- * Format todos array as a parameter value
1124
- */
1125
- formatTodosAsParameter(todos) {
1126
- const statusCounts = this.getTodoStatusCounts(todos);
1127
-
1128
- let html = `
1129
- <div class="param-todos">
1130
- <div class="param-todos-header">
1131
- Array of todo objects (${todos.length} items)
1132
- </div>
1133
- <div class="param-todos-summary">
1134
- ${statusCounts.completed} completed • ${statusCounts.in_progress} in progress • ${statusCounts.pending} pending
1135
- </div>
1136
- <div class="param-todos-list">
1137
- `;
1138
-
1139
- todos.forEach((todo, index) => {
1140
- const statusIcon = this.getCheckboxIcon(todo.status);
1141
- const displayText = todo.status === 'in_progress' ?
1142
- (todo.activeForm || todo.content) : todo.content;
1143
- const statusClass = this.formatStatusClass(todo.status);
1144
-
1145
- html += `
1146
- <div class="param-todo-item ${todo.status}">
1147
- <div class="param-todo-checkbox">
1148
- <span class="param-checkbox-icon ${statusClass}">${statusIcon}</span>
1149
- </div>
1150
- <div class="param-todo-text">
1151
- <span class="param-todo-content">${this.escapeHtml(displayText)}</span>
1152
- <span class="param-todo-status-badge ${statusClass}">${todo.status.replace('_', ' ')}</span>
1153
- </div>
1154
- </div>
1155
- `;
1156
- });
1157
-
1158
- html += `
1159
- </div>
1160
- </div>
1161
- `;
1162
-
1163
- return html;
1164
- }
1165
-
1166
- // ==================== FILE OPERATION UTILITIES ====================
1167
-
1168
- /**
1169
- * Determine if this is a single file operation
1170
- */
1171
- isSingleFileOperation(data) {
1172
- // Single file if no operations array or only one operation
1173
- if (!data.operations) return true;
1174
- return data.operations.length === 1;
1175
- }
1176
-
1177
- /**
1178
- * Get file icon based on file extension
1179
- */
1180
- getFileIcon(filePath) {
1181
- if (!filePath) return '📄';
1182
-
1183
- const ext = filePath.split('.').pop()?.toLowerCase();
1184
- const iconMap = {
1185
- // Code files
1186
- 'js': '🟨',
1187
- 'jsx': '⚛️',
1188
- 'ts': '🔷',
1189
- 'tsx': '⚛️',
1190
- 'py': '🐍',
1191
- 'java': '☕',
1192
- 'cpp': '⚡',
1193
- 'c': '⚡',
1194
- 'cs': '#️⃣',
1195
- 'php': '🐘',
1196
- 'rb': '💎',
1197
- 'go': '🐹',
1198
- 'rs': '🦀',
1199
- 'swift': '🦉',
1200
- 'kt': '🅺',
1201
- 'scala': '🎯',
1202
-
1203
- // Web files
1204
- 'html': '🌐',
1205
- 'htm': '🌐',
1206
- 'css': '🎨',
1207
- 'scss': '🎨',
1208
- 'sass': '🎨',
1209
- 'less': '🎨',
1210
- 'vue': '💚',
1211
-
1212
- // Config files
1213
- 'json': '📋',
1214
- 'xml': '📄',
1215
- 'yaml': '⚙️',
1216
- 'yml': '⚙️',
1217
- 'toml': '⚙️',
1218
- 'ini': '⚙️',
1219
- 'conf': '⚙️',
1220
- 'config': '⚙️',
1221
-
1222
- // Documentation
1223
- 'md': '📝',
1224
- 'txt': '📃',
1225
- 'rtf': '📃',
1226
- 'pdf': '📕',
1227
- 'doc': '📘',
1228
- 'docx': '📘',
1229
-
1230
- // Images
1231
- 'jpg': '🖼️',
1232
- 'jpeg': '🖼️',
1233
- 'png': '🖼️',
1234
- 'gif': '🖼️',
1235
- 'svg': '🎨',
1236
- 'webp': '🖼️',
1237
- 'ico': '🖼️',
1238
-
1239
- // Archives
1240
- 'zip': '🗜️',
1241
- 'tar': '🗜️',
1242
- 'gz': '🗜️',
1243
- 'rar': '🗜️',
1244
- '7z': '🗜️',
1245
-
1246
- // Other
1247
- 'sql': '🗃️',
1248
- 'db': '🗃️',
1249
- 'log': '📊',
1250
- 'env': '🔐',
1251
- 'lock': '🔒'
1252
- };
1253
-
1254
- return iconMap[ext] || '📄';
1255
- }
1256
-
1257
- /**
1258
- * Get file type description
1259
- */
1260
- getFileType(filePath) {
1261
- if (!filePath) return null;
1262
-
1263
- const ext = filePath.split('.').pop()?.toLowerCase();
1264
- const typeMap = {
1265
- 'js': 'JavaScript',
1266
- 'jsx': 'React JSX',
1267
- 'ts': 'TypeScript',
1268
- 'tsx': 'React TSX',
1269
- 'py': 'Python',
1270
- 'java': 'Java',
1271
- 'cpp': 'C++',
1272
- 'c': 'C',
1273
- 'cs': 'C#',
1274
- 'php': 'PHP',
1275
- 'rb': 'Ruby',
1276
- 'go': 'Go',
1277
- 'rs': 'Rust',
1278
- 'html': 'HTML',
1279
- 'css': 'CSS',
1280
- 'scss': 'SCSS',
1281
- 'json': 'JSON',
1282
- 'xml': 'XML',
1283
- 'yaml': 'YAML',
1284
- 'yml': 'YAML',
1285
- 'md': 'Markdown',
1286
- 'txt': 'Text',
1287
- 'sql': 'SQL',
1288
- 'log': 'Log File'
1289
- };
1290
-
1291
- return typeMap[ext] || null;
1292
- }
1293
-
1294
- /**
1295
- * Check if file should show inline preview
1296
- */
1297
- shouldShowInlinePreview(data) {
1298
- // Show preview for single file text operations
1299
- return this.isSingleFileOperation(data) && this.isTextFile(data.file_path);
1300
- }
1301
-
1302
- /**
1303
- * Check if file is a text file suitable for preview
1304
- */
1305
- isTextFile(filePath) {
1306
- if (!filePath) return false;
1307
-
1308
- const ext = filePath.split('.').pop()?.toLowerCase();
1309
- const textExtensions = [
1310
- 'txt', 'md', 'json', 'xml', 'yaml', 'yml', 'ini', 'conf', 'config',
1311
- 'js', 'jsx', 'ts', 'tsx', 'py', 'java', 'cpp', 'c', 'cs', 'php', 'rb',
1312
- 'go', 'rs', 'swift', 'kt', 'scala', 'html', 'htm', 'css', 'scss', 'sass',
1313
- 'less', 'vue', 'sql', 'log', 'env', 'gitignore', 'dockerignore'
1314
- ];
1315
-
1316
- return textExtensions.includes(ext);
1317
- }
1318
-
1319
- /**
1320
- * Toggle inline preview for a file
1321
- */
1322
- async toggleInlinePreview(filePath, buttonElement) {
1323
- const containerId = `preview-${this.generatePreviewId(filePath)}`;
1324
- const container = document.getElementById(containerId);
1325
-
1326
- if (!container) {
1327
- console.warn('Preview container not found');
1328
- return;
1329
- }
1330
-
1331
- if (container.style.display === 'none') {
1332
- // Show preview
1333
- container.style.display = 'block';
1334
- buttonElement.innerHTML = '📖 Hide Preview';
1335
- await this.loadInlinePreview(filePath, container);
1336
- } else {
1337
- // Hide preview
1338
- container.style.display = 'none';
1339
- buttonElement.innerHTML = '📖 Quick Preview';
1340
- }
1341
- }
1342
-
1343
- /**
1344
- * Load inline preview content
1345
- */
1346
- async loadInlinePreview(filePath, container) {
1347
- try {
1348
- // This would typically make an API call to get file contents
1349
- // For now, show a placeholder
1350
- container.innerHTML = `
1351
- <div class="inline-preview-header">
1352
- <span class="preview-label">Quick Preview:</span>
1353
- <span class="preview-file">${filePath}</span>
1354
- </div>
1355
- <div class="inline-preview-content">
1356
- <div class="preview-note">
1357
- 💡 Inline preview feature ready - API integration needed
1358
- <br>Click "View File Contents" for full syntax-highlighted view
1359
- </div>
1360
- </div>
1361
- `;
1362
- } catch (error) {
1363
- container.innerHTML = `
1364
- <div class="inline-preview-error">
1365
- ❌ Could not load preview: ${error.message}
1366
- </div>
1367
- `;
1368
- }
1369
- }
1370
-
1371
- /**
1372
- * Generate a unique ID for preview containers
1373
- */
1374
- generateId() {
1375
- return Date.now().toString(36) + Math.random().toString(36).substr(2, 9);
1376
- }
1377
-
1378
- /**
1379
- * Generate preview ID based on file path
1380
- */
1381
- generatePreviewId(filePath) {
1382
- return btoa(filePath).replace(/[^a-zA-Z0-9]/g, '');
1383
- }
1384
-
1385
- // ==================== UTILITY METHODS ====================
1386
-
1387
- /**
1388
- * Format timestamp for display
1389
- */
1390
- formatTimestamp(timestamp) {
1391
- if (!timestamp) return 'Unknown time';
1392
-
1393
- try {
1394
- const date = new Date(timestamp);
1395
- if (isNaN(date.getTime())) return 'Invalid date';
1396
- return date.toLocaleString();
1397
- } catch (error) {
1398
- return 'Invalid date';
1399
- }
1400
- }
1401
-
1402
- /**
1403
- * Format status with appropriate styling
1404
- */
1405
- formatStatus(status) {
1406
- if (!status) return 'unknown';
1407
-
1408
- const statusMap = {
1409
- 'active': '🟢 Active',
1410
- 'completed': '✅ Completed',
1411
- 'in_progress': '🔄 In Progress',
1412
- 'pending': '⏳ Pending',
1413
- 'error': '❌ Error',
1414
- 'failed': '❌ Failed'
1415
- };
1416
-
1417
- return statusMap[status] || status;
1418
- }
1419
-
1420
- /**
1421
- * Get CSS class for status styling
1422
- */
1423
- formatStatusClass(status) {
1424
- return `status-${status}`;
1425
- }
1426
-
1427
- /**
1428
- * Get icon for agent type
1429
- */
1430
- getAgentIcon(agentName) {
1431
- const icons = {
1432
- 'PM': '🎯',
1433
- 'Engineer': '🔧',
1434
- 'Engineer Agent': '🔧',
1435
- 'Research': '🔍',
1436
- 'Research Agent': '🔍',
1437
- 'QA': '✅',
1438
- 'QA Agent': '✅',
1439
- 'Architect': '🏗️',
1440
- 'Architect Agent': '🏗️',
1441
- 'Ops': '⚙️',
1442
- 'Ops Agent': '⚙️'
1443
- };
1444
- return icons[agentName] || '🤖';
1445
- }
1446
-
1447
- /**
1448
- * Get icon for tool type
1449
- */
1450
- getToolIcon(toolName) {
1451
- const icons = {
1452
- 'Read': '👁️',
1453
- 'Write': '✍️',
1454
- 'Edit': '✏️',
1455
- 'MultiEdit': '📝',
1456
- 'Bash': '💻',
1457
- 'Grep': '🔍',
1458
- 'Glob': '📂',
1459
- 'LS': '📁',
1460
- 'TodoWrite': '📝',
1461
- 'Task': '📋',
1462
- 'WebFetch': '🌐'
1463
- };
1464
- return icons[toolName] || '🔧';
1465
- }
1466
-
1467
- /**
1468
- * Get checkbox icon for todo status
1469
- */
1470
- getCheckboxIcon(status) {
1471
- const icons = {
1472
- 'pending': '⏳',
1473
- 'in_progress': '🔄',
1474
- 'completed': '✅'
1475
- };
1476
- return icons[status] || '❓';
1477
- }
1478
-
1479
- /**
1480
- * Get icon for file operation type
1481
- */
1482
- getOperationIcon(operation) {
1483
- const icons = {
1484
- 'read': '👁️',
1485
- 'write': '✍️',
1486
- 'edit': '✏️',
1487
- 'delete': '🗑️',
1488
- 'create': '📝',
1489
- 'search': '🔍',
1490
- 'list': '📂',
1491
- 'copy': '📋',
1492
- 'move': '📦',
1493
- 'bash': '💻'
1494
- };
1495
- return icons[operation.toLowerCase()] || '📄';
1496
- }
1497
-
1498
- /**
1499
- * Convert tool data to file operation format for better display
1500
- */
1501
- convertToolToFileOperation(toolData) {
1502
- const params = toolData.params || toolData.tool_parameters || {};
1503
- const filePath = params.file_path || params.path || params.notebook_path;
1504
-
1505
- if (!filePath) {
1506
- return toolData; // Return original if no file path
1507
- }
1508
-
1509
- // Create file operation format
1510
- const operation = {
1511
- operation: toolData.name.toLowerCase(),
1512
- timestamp: toolData.timestamp || new Date().toISOString(),
1513
- agent: 'Activity Tool',
1514
- sessionId: toolData.sessionId || 'unknown',
1515
- details: {
1516
- parameters: params,
1517
- tool_name: toolData.name,
1518
- status: toolData.status || 'completed'
1519
- }
1520
- };
1521
-
1522
- return {
1523
- file_path: filePath,
1524
- operations: [operation],
1525
- lastOperation: operation.timestamp,
1526
- // Preserve original tool data for reference
1527
- originalTool: toolData
1528
- };
1529
- }
1530
-
1531
- /**
1532
- * Get todo status counts
1533
- */
1534
- getTodoStatusCounts(todos) {
1535
- const counts = { completed: 0, in_progress: 0, pending: 0 };
1536
-
1537
- todos.forEach(todo => {
1538
- if (counts.hasOwnProperty(todo.status)) {
1539
- counts[todo.status]++;
1540
- }
1541
- });
1542
-
1543
- return counts;
1544
- }
1545
-
1546
- /**
1547
- * Escape HTML for safe display
1548
- */
1549
- escapeHtml(text) {
1550
- if (typeof text !== 'string') return '';
1551
-
1552
- const div = document.createElement('div');
1553
- div.textContent = text;
1554
- return div.innerHTML;
1555
- }
1556
-
1557
- /**
1558
- * Toggle JSON section visibility and update global state
1559
- * WHY: Maintains sticky state across all JSON sections for consistent behavior
1560
- * @param {string} sectionId - ID of the specific section being toggled
1561
- * @param {HTMLElement} button - The button element that was clicked
1562
- */
1563
- toggleJsonSection(sectionId, button) {
1564
- // Toggle the global state
1565
- this.globalJsonExpanded = !this.globalJsonExpanded;
1566
-
1567
- // Persist the preference to localStorage
1568
- localStorage.setItem('dashboard-json-expanded', this.globalJsonExpanded.toString());
1569
-
1570
- // Update ALL JSON sections on the page
1571
- this.updateAllJsonSections();
1572
-
1573
- // Dispatch event to notify other components (like module-viewer) of the change
1574
- document.dispatchEvent(new CustomEvent('jsonToggleChanged', {
1575
- detail: { expanded: this.globalJsonExpanded }
1576
- }));
1577
- }
1578
-
1579
- /**
1580
- * Toggle Full Event Data section visibility and update state
1581
- * WHY: Maintains separate sticky state for Full Event Data sections
1582
- * @param {string} sectionId - ID of the specific section being toggled
1583
- * @param {HTMLElement} button - The button element that was clicked
1584
- */
1585
- toggleFullEventSection(sectionId, button) {
1586
- // Toggle the full event data state
1587
- this.fullEventDataExpanded = !this.fullEventDataExpanded;
1588
-
1589
- // Persist the preference to localStorage
1590
- localStorage.setItem('dashboard-full-event-expanded', this.fullEventDataExpanded.toString());
1591
-
1592
- // Update ALL Full Event sections on the page
1593
- this.updateAllFullEventSections();
1594
-
1595
- // Dispatch event to notify other components of the change
1596
- document.dispatchEvent(new CustomEvent('fullEventToggleChanged', {
1597
- detail: { expanded: this.fullEventDataExpanded }
1598
- }));
1599
- }
1600
-
1601
- /**
1602
- * Update all JSON sections on the page to match global state
1603
- * WHY: Ensures all "Structured Data" sections maintain consistent visibility
1604
- */
1605
- updateAllJsonSections() {
1606
- // Find all unified JSON sections (NOT full event sections)
1607
- const allJsonContents = document.querySelectorAll('.unified-json-content');
1608
- const allJsonButtons = document.querySelectorAll('.unified-json-toggle');
1609
-
1610
- // Update each JSON section
1611
- allJsonContents.forEach(content => {
1612
- if (this.globalJsonExpanded) {
1613
- content.style.display = 'block';
1614
- } else {
1615
- content.style.display = 'none';
1616
- }
1617
- });
1618
-
1619
- // Update all button states
1620
- allJsonButtons.forEach(button => {
1621
- const title = button.textContent.substring(2); // Remove arrow
1622
- if (this.globalJsonExpanded) {
1623
- button.innerHTML = '▼ ' + title;
1624
- button.classList.add('expanded');
1625
- } else {
1626
- button.innerHTML = '▶ ' + title;
1627
- button.classList.remove('expanded');
1628
- }
1629
- });
1630
- }
1631
-
1632
- /**
1633
- * Update all Full Event Data sections on the page to match state
1634
- * WHY: Ensures all "Full Event Data" sections maintain consistent visibility
1635
- */
1636
- updateAllFullEventSections() {
1637
- // Find all full event sections
1638
- const allFullEventContents = document.querySelectorAll('.full-event-content');
1639
- const allFullEventButtons = document.querySelectorAll('.full-event-toggle');
1640
-
1641
- // Update each full event section
1642
- allFullEventContents.forEach(content => {
1643
- if (this.fullEventDataExpanded) {
1644
- content.style.display = 'block';
1645
- } else {
1646
- content.style.display = 'none';
1647
- }
1648
- });
1649
-
1650
- // Update all button states
1651
- allFullEventButtons.forEach(button => {
1652
- const title = button.textContent.substring(2); // Remove arrow
1653
- if (this.fullEventDataExpanded) {
1654
- button.innerHTML = '▼ ' + title;
1655
- button.classList.add('expanded');
1656
- } else {
1657
- button.innerHTML = '▶ ' + title;
1658
- button.classList.remove('expanded');
1659
- }
1660
- });
1661
- }
1662
-
1663
- /**
1664
- * Create a collapsible JSON viewer for secondary details
1665
- * Provides a clean way to show full data without cluttering the main view
1666
- */
1667
- createCollapsibleJSON(data, title = 'Full Details') {
1668
- // Generate unique ID for this collapsible section
1669
- const sectionId = `json-details-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
1670
-
1671
- // Filter out sensitive or overly verbose properties
1672
- const cleanData = this.cleanDataForDisplay(data);
1673
-
1674
- // Determine which state to use based on title
1675
- // "Full Event Data" and similar titles use the fullEventDataExpanded state
1676
- // Other titles use the global JSON state (for backward compatibility)
1677
- const isFullEventData = title.includes('Full Event') || title.includes('Full Details') ||
1678
- title.includes('Full Agent') || title.includes('Full Tool');
1679
- const isExpanded = isFullEventData ? this.fullEventDataExpanded : this.globalJsonExpanded;
1680
- const display = isExpanded ? 'block' : 'none';
1681
- const arrow = isExpanded ? '▼' : '▶';
1682
- const expandedClass = isExpanded ? 'expanded' : '';
1683
-
1684
- // Use different toggle function based on section type
1685
- const toggleFunction = isFullEventData ? 'toggleFullEventSection' : 'toggleJsonSection';
1686
-
1687
- return `
1688
- <div class="collapsible-json-section">
1689
- <button class="collapsible-json-toggle ${isFullEventData ? 'full-event-toggle' : 'unified-json-toggle'} ${expandedClass}"
1690
- data-section-id="${sectionId}"
1691
- data-is-full-event="${isFullEventData}"
1692
- onclick="window.unifiedDataViewer.${toggleFunction}('${sectionId}', this)">
1693
- ${arrow} ${title}
1694
- </button>
1695
- <div id="${sectionId}" class="collapsible-json-content ${isFullEventData ? 'full-event-content' : 'unified-json-content'}" style="display: ${display};">
1696
- <pre class="json-viewer">${this.escapeHtml(JSON.stringify(cleanData, null, 2))}</pre>
1697
- </div>
1698
- </div>
1699
- `;
1700
- }
1701
-
1702
- /**
1703
- * Clean data for display in JSON viewer
1704
- * Removes circular references and limits string lengths
1705
- */
1706
- cleanDataForDisplay(data) {
1707
- const seen = new WeakSet();
1708
-
1709
- return JSON.parse(JSON.stringify(data, (key, value) => {
1710
- // Handle circular references
1711
- if (typeof value === 'object' && value !== null) {
1712
- if (seen.has(value)) {
1713
- return '[Circular Reference]';
1714
- }
1715
- seen.add(value);
1716
- }
1717
-
1718
- // Truncate very long strings
1719
- if (typeof value === 'string' && value.length > 1000) {
1720
- return value.substring(0, 1000) + '... [truncated]';
1721
- }
1722
-
1723
- // Handle functions
1724
- if (typeof value === 'function') {
1725
- return '[Function]';
1726
- }
1727
-
1728
- return value;
1729
- }));
1730
- }
1731
-
1732
- // ==================== PUBLIC API METHODS ====================
1733
-
1734
- /**
1735
- * Clear the viewer
1736
- */
1737
- clear() {
1738
- if (this.container) {
1739
- this.container.innerHTML = '';
1740
- }
1741
- this.currentData = null;
1742
- this.currentType = null;
1743
- }
1744
-
1745
- /**
1746
- * Get current displayed data
1747
- */
1748
- getCurrentData() {
1749
- return this.currentData;
1750
- }
1751
-
1752
- /**
1753
- * Get current data type
1754
- */
1755
- getCurrentType() {
1756
- return this.currentType;
1757
- }
1758
-
1759
- /**
1760
- * Check if viewer has data
1761
- */
1762
- hasData() {
1763
- return this.currentData !== null;
1764
- }
1765
- }
1766
-
1767
- // Export for module use
1768
- export { UnifiedDataViewer };
1769
- export default UnifiedDataViewer;
1770
-
1771
- // Make globally available for non-module usage
1772
- window.UnifiedDataViewer = UnifiedDataViewer;
1773
-
1774
- // Create a global instance immediately for inline onclick handlers
1775
- // This ensures the instance is available when HTML is rendered dynamically
1776
- if (typeof window !== 'undefined') {
1777
- // Always create/update the global instance
1778
- window.unifiedDataViewer = new UnifiedDataViewer();
1779
-
1780
- // Also expose the methods directly on window as a fallback
1781
- window.toggleFullEventSection = function(sectionId, button) {
1782
- if (window.unifiedDataViewer) {
1783
- window.unifiedDataViewer.toggleFullEventSection(sectionId, button);
1784
- }
1785
- };
1786
-
1787
- window.toggleJsonSection = function(sectionId, button) {
1788
- if (window.unifiedDataViewer) {
1789
- window.unifiedDataViewer.toggleJsonSection(sectionId, button);
1790
- }
1791
- };
1792
- }
1793
-
1794
- // Create a global instance for inline preview functionality
1795
- if (typeof window !== 'undefined') {
1796
- window.addEventListener('DOMContentLoaded', function() {
1797
- // Create global instance if one doesn't exist
1798
- if (!window.unifiedDataViewer) {
1799
- window.unifiedDataViewer = new UnifiedDataViewer();
1800
- }
1801
-
1802
- // Add keyboard shortcuts for file operations
1803
- document.addEventListener('keydown', function(e) {
1804
- // Ctrl/Cmd + Click on file paths to open file viewer
1805
- if ((e.ctrlKey || e.metaKey) && e.target.classList.contains('clickable-file-path')) {
1806
- e.preventDefault();
1807
- const filePath = e.target.textContent.trim();
1808
- if (window.showFileViewerModal) {
1809
- window.showFileViewerModal(filePath);
1810
- }
1811
- }
1812
-
1813
- // 'V' key to open file viewer when hovering over clickable file paths
1814
- if (e.key.toLowerCase() === 'v' && document.querySelector('.clickable-file-path:hover')) {
1815
- const hoveredPath = document.querySelector('.clickable-file-path:hover');
1816
- if (hoveredPath && window.showFileViewerModal) {
1817
- e.preventDefault();
1818
- const filePath = hoveredPath.textContent.trim();
1819
- window.showFileViewerModal(filePath);
1820
- }
1821
- }
1822
- });
1823
- });
1824
- }