claude-mpm 4.1.26__py3-none-any.whl → 5.0.9__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 (792) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__init__.py +20 -5
  4. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
  5. claude_mpm/agents/BASE_DOCUMENTATION.md +53 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/BASE_OPS.md +219 -0
  8. claude_mpm/agents/BASE_PM.md +432 -158
  9. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +787 -0
  10. claude_mpm/agents/BASE_QA.md +167 -0
  11. claude_mpm/agents/BASE_RESEARCH.md +53 -0
  12. claude_mpm/agents/OUTPUT_STYLE.md +254 -29
  13. claude_mpm/agents/PM_INSTRUCTIONS.md +969 -0
  14. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  15. claude_mpm/agents/WORKFLOW.md +355 -191
  16. claude_mpm/agents/__init__.py +6 -0
  17. claude_mpm/agents/agent_loader.py +41 -14
  18. claude_mpm/agents/agent_loader_integration.py +3 -2
  19. claude_mpm/agents/async_agent_loader.py +3 -3
  20. claude_mpm/agents/base_agent.json +6 -3
  21. claude_mpm/agents/base_agent_loader.py +21 -44
  22. claude_mpm/agents/frontmatter_validator.py +292 -252
  23. claude_mpm/agents/system_agent_config.py +3 -2
  24. claude_mpm/agents/templates/README.md +465 -0
  25. claude_mpm/agents/templates/circuit-breakers.md +1005 -0
  26. claude_mpm/agents/templates/context-management-examples.md +544 -0
  27. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  28. claude_mpm/agents/templates/pm-examples.md +474 -0
  29. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  30. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  31. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  32. claude_mpm/agents/templates/response-format.md +583 -0
  33. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  34. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  35. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  36. claude_mpm/agents/templates/validation-templates.md +312 -0
  37. claude_mpm/cli/__init__.py +72 -376
  38. claude_mpm/cli/commands/__init__.py +4 -0
  39. claude_mpm/cli/commands/agent_manager.py +675 -20
  40. claude_mpm/cli/commands/agent_source.py +774 -0
  41. claude_mpm/cli/commands/agent_state_manager.py +344 -0
  42. claude_mpm/cli/commands/agents.py +1673 -178
  43. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  44. claude_mpm/cli/commands/agents_detect.py +380 -0
  45. claude_mpm/cli/commands/agents_discover.py +338 -0
  46. claude_mpm/cli/commands/agents_recommend.py +309 -0
  47. claude_mpm/cli/commands/aggregate.py +11 -7
  48. claude_mpm/cli/commands/analyze.py +18 -13
  49. claude_mpm/cli/commands/analyze_code.py +8 -4
  50. claude_mpm/cli/commands/auto_configure.py +566 -0
  51. claude_mpm/cli/commands/cleanup.py +12 -12
  52. claude_mpm/cli/commands/config.py +54 -17
  53. claude_mpm/cli/commands/configure.py +1184 -1055
  54. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  55. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  56. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  57. claude_mpm/cli/commands/configure_models.py +18 -0
  58. claude_mpm/cli/commands/configure_navigation.py +184 -0
  59. claude_mpm/cli/commands/configure_paths.py +104 -0
  60. claude_mpm/cli/commands/configure_persistence.py +254 -0
  61. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  62. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  63. claude_mpm/cli/commands/configure_validators.py +73 -0
  64. claude_mpm/cli/commands/dashboard.py +50 -52
  65. claude_mpm/cli/commands/debug.py +19 -19
  66. claude_mpm/cli/commands/doctor.py +51 -7
  67. claude_mpm/cli/commands/hook_errors.py +277 -0
  68. claude_mpm/cli/commands/info.py +3 -4
  69. claude_mpm/cli/commands/local_deploy.py +534 -0
  70. claude_mpm/cli/commands/mcp.py +17 -10
  71. claude_mpm/cli/commands/mcp_command_router.py +11 -0
  72. claude_mpm/cli/commands/mcp_config.py +154 -0
  73. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  74. claude_mpm/cli/commands/mcp_install_commands.py +101 -32
  75. claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
  76. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  77. claude_mpm/cli/commands/memory.py +55 -21
  78. claude_mpm/cli/commands/monitor.py +160 -70
  79. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  80. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  81. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  82. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  83. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  84. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  85. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  86. claude_mpm/cli/commands/mpm_init_handler.py +114 -4
  87. claude_mpm/cli/commands/postmortem.py +401 -0
  88. claude_mpm/cli/commands/run.py +252 -167
  89. claude_mpm/cli/commands/search.py +458 -0
  90. claude_mpm/cli/commands/skill_source.py +694 -0
  91. claude_mpm/cli/commands/skills.py +1225 -0
  92. claude_mpm/cli/commands/uninstall.py +176 -0
  93. claude_mpm/cli/commands/upgrade.py +152 -0
  94. claude_mpm/cli/commands/verify.py +119 -0
  95. claude_mpm/cli/executor.py +279 -0
  96. claude_mpm/cli/helpers.py +105 -0
  97. claude_mpm/cli/interactive/__init__.py +21 -0
  98. claude_mpm/cli/interactive/agent_wizard.py +1872 -0
  99. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  100. claude_mpm/cli/parser.py +79 -2
  101. claude_mpm/cli/parsers/__init__.py +7 -1
  102. claude_mpm/cli/parsers/agent_manager_parser.py +161 -1
  103. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  104. claude_mpm/cli/parsers/agents_parser.py +369 -1
  105. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  106. claude_mpm/cli/parsers/base_parser.py +196 -3
  107. claude_mpm/cli/parsers/config_parser.py +96 -43
  108. claude_mpm/cli/parsers/configure_parser.py +11 -15
  109. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  110. claude_mpm/cli/parsers/mcp_parser.py +15 -0
  111. claude_mpm/cli/parsers/monitor_parser.py +12 -2
  112. claude_mpm/cli/parsers/mpm_init_parser.py +179 -9
  113. claude_mpm/cli/parsers/run_parser.py +5 -0
  114. claude_mpm/cli/parsers/search_parser.py +245 -0
  115. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  116. claude_mpm/cli/parsers/skills_parser.py +282 -0
  117. claude_mpm/cli/parsers/source_parser.py +138 -0
  118. claude_mpm/cli/shared/argument_patterns.py +20 -13
  119. claude_mpm/cli/shared/base_command.py +2 -2
  120. claude_mpm/cli/shared/output_formatters.py +28 -19
  121. claude_mpm/cli/startup.py +994 -0
  122. claude_mpm/cli/startup_display.py +480 -0
  123. claude_mpm/cli/startup_logging.py +179 -13
  124. claude_mpm/cli/utils.py +54 -3
  125. claude_mpm/cli_module/commands.py +1 -1
  126. claude_mpm/commands/mpm-agents-auto-configure.md +278 -0
  127. claude_mpm/commands/mpm-agents-detect.md +177 -0
  128. claude_mpm/commands/mpm-agents-list.md +131 -0
  129. claude_mpm/commands/mpm-agents-recommend.md +223 -0
  130. claude_mpm/commands/mpm-config-view.md +150 -0
  131. claude_mpm/commands/mpm-doctor.md +9 -0
  132. claude_mpm/commands/mpm-help.md +297 -5
  133. claude_mpm/commands/mpm-init.md +401 -17
  134. claude_mpm/commands/mpm-monitor.md +418 -0
  135. claude_mpm/commands/mpm-postmortem.md +123 -0
  136. claude_mpm/commands/mpm-session-resume.md +381 -0
  137. claude_mpm/commands/mpm-status.md +79 -8
  138. claude_mpm/commands/mpm-ticket-organize.md +304 -0
  139. claude_mpm/commands/mpm-ticket-view.md +552 -0
  140. claude_mpm/commands/mpm-version.md +122 -0
  141. claude_mpm/commands/mpm.md +12 -0
  142. claude_mpm/config/agent_config.py +4 -4
  143. claude_mpm/config/agent_presets.py +488 -0
  144. claude_mpm/config/agent_sources.py +325 -0
  145. claude_mpm/config/experimental_features.py +7 -7
  146. claude_mpm/config/model_config.py +428 -0
  147. claude_mpm/config/paths.py +3 -2
  148. claude_mpm/config/skill_presets.py +392 -0
  149. claude_mpm/config/skill_sources.py +590 -0
  150. claude_mpm/config/socketio_config.py +3 -3
  151. claude_mpm/constants.py +28 -1
  152. claude_mpm/core/__init__.py +53 -17
  153. claude_mpm/core/agent_name_normalizer.py +3 -2
  154. claude_mpm/core/agent_registry.py +2 -2
  155. claude_mpm/core/agent_session_manager.py +10 -10
  156. claude_mpm/core/api_validator.py +330 -0
  157. claude_mpm/core/base_service.py +33 -23
  158. claude_mpm/core/cache.py +9 -9
  159. claude_mpm/core/claude_runner.py +24 -42
  160. claude_mpm/core/config.py +101 -8
  161. claude_mpm/core/config_aliases.py +7 -6
  162. claude_mpm/core/constants.py +66 -1
  163. claude_mpm/core/container.py +11 -5
  164. claude_mpm/core/enums.py +452 -0
  165. claude_mpm/core/error_handler.py +623 -0
  166. claude_mpm/core/factories.py +1 -1
  167. claude_mpm/core/file_utils.py +764 -0
  168. claude_mpm/core/framework/__init__.py +25 -0
  169. claude_mpm/core/framework/formatters/__init__.py +11 -0
  170. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  171. claude_mpm/core/framework/formatters/content_formatter.py +288 -0
  172. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  173. claude_mpm/core/framework/loaders/__init__.py +13 -0
  174. claude_mpm/core/framework/loaders/agent_loader.py +210 -0
  175. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  176. claude_mpm/core/framework/loaders/instruction_loader.py +181 -0
  177. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  178. claude_mpm/core/framework/processors/__init__.py +11 -0
  179. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  180. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  181. claude_mpm/core/framework/processors/template_processor.py +244 -0
  182. claude_mpm/core/framework_loader.py +321 -1631
  183. claude_mpm/core/hook_error_memory.py +381 -0
  184. claude_mpm/core/hook_manager.py +49 -8
  185. claude_mpm/core/injectable_service.py +11 -8
  186. claude_mpm/core/instruction_reinforcement_hook.py +4 -3
  187. claude_mpm/core/interactive_session.py +146 -18
  188. claude_mpm/core/interfaces.py +56 -1
  189. claude_mpm/core/lazy.py +3 -3
  190. claude_mpm/core/log_manager.py +92 -23
  191. claude_mpm/core/logger.py +22 -15
  192. claude_mpm/core/logging_config.py +6 -2
  193. claude_mpm/core/logging_utils.py +520 -0
  194. claude_mpm/core/oneshot_session.py +122 -15
  195. claude_mpm/core/optimized_agent_loader.py +9 -9
  196. claude_mpm/core/optimized_startup.py +1 -1
  197. claude_mpm/core/output_style_manager.py +12 -192
  198. claude_mpm/core/pm_hook_interceptor.py +18 -12
  199. claude_mpm/core/protocols/__init__.py +23 -0
  200. claude_mpm/core/protocols/runner_protocol.py +103 -0
  201. claude_mpm/core/protocols/session_protocol.py +131 -0
  202. claude_mpm/core/service_registry.py +7 -3
  203. claude_mpm/core/session_manager.py +14 -12
  204. claude_mpm/core/shared/config_loader.py +1 -1
  205. claude_mpm/core/shared/singleton_manager.py +11 -4
  206. claude_mpm/core/socketio_pool.py +15 -15
  207. claude_mpm/core/system_context.py +38 -0
  208. claude_mpm/core/tool_access_control.py +3 -2
  209. claude_mpm/core/types.py +4 -11
  210. claude_mpm/core/typing_utils.py +7 -6
  211. claude_mpm/core/unified_agent_registry.py +115 -11
  212. claude_mpm/core/unified_config.py +6 -6
  213. claude_mpm/core/unified_paths.py +23 -20
  214. claude_mpm/dashboard/analysis_runner.py +4 -4
  215. claude_mpm/dashboard/api/simple_directory.py +261 -0
  216. claude_mpm/dashboard/static/css/activity.css +69 -69
  217. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  218. claude_mpm/dashboard/static/css/dashboard.css +600 -18
  219. claude_mpm/dashboard/static/js/components/activity-tree.js +181 -195
  220. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +105 -102
  221. claude_mpm/dashboard/static/js/components/agent-inference.js +34 -31
  222. claude_mpm/dashboard/static/js/components/build-tracker.js +67 -59
  223. claude_mpm/dashboard/static/js/components/code-simple.js +857 -0
  224. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  225. claude_mpm/dashboard/static/js/components/diff-viewer.js +891 -0
  226. claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
  227. claude_mpm/dashboard/static/js/components/event-viewer.js +50 -13
  228. claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
  229. claude_mpm/dashboard/static/js/components/file-change-tracker.js +443 -0
  230. claude_mpm/dashboard/static/js/components/file-change-viewer.js +690 -0
  231. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +36 -16
  232. claude_mpm/dashboard/static/js/components/file-viewer.js +580 -0
  233. claude_mpm/dashboard/static/js/components/module-viewer.js +49 -23
  234. claude_mpm/dashboard/static/js/components/session-manager.js +19 -19
  235. claude_mpm/dashboard/static/js/components/socket-manager.js +5 -1
  236. claude_mpm/dashboard/static/js/components/ui-state-manager.js +356 -41
  237. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +520 -88
  238. claude_mpm/dashboard/static/js/components/working-directory.js +46 -11
  239. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  240. claude_mpm/dashboard/static/js/dashboard.js +309 -178
  241. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  242. claude_mpm/dashboard/static/js/socket-client.js +183 -139
  243. claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
  244. claude_mpm/dashboard/static/socket.io.min.js +7 -0
  245. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
  246. claude_mpm/dashboard/templates/code_simple.html +153 -0
  247. claude_mpm/dashboard/templates/index.html +125 -122
  248. claude_mpm/experimental/cli_enhancements.py +5 -7
  249. claude_mpm/generators/agent_profile_generator.py +5 -3
  250. claude_mpm/hooks/__init__.py +37 -1
  251. claude_mpm/hooks/base_hook.py +5 -4
  252. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  253. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  254. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  255. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  256. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  257. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  258. claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
  259. claude_mpm/hooks/claude_hooks/event_handlers.py +24 -19
  260. claude_mpm/hooks/claude_hooks/hook_handler.py +29 -22
  261. claude_mpm/hooks/claude_hooks/installer.py +67 -22
  262. claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
  263. claude_mpm/hooks/claude_hooks/response_tracking.py +57 -17
  264. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  265. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  266. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  267. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  268. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  269. claude_mpm/hooks/claude_hooks/services/connection_manager.py +62 -64
  270. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +140 -76
  271. claude_mpm/hooks/claude_hooks/services/state_manager.py +11 -9
  272. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
  273. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  274. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  275. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  276. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  277. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  278. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  279. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  280. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  281. claude_mpm/hooks/memory_integration_hook.py +1 -1
  282. claude_mpm/hooks/session_resume_hook.py +121 -0
  283. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  284. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  285. claude_mpm/hooks/tool_call_interceptor.py +8 -5
  286. claude_mpm/hooks/validation_hooks.py +3 -3
  287. claude_mpm/init.py +23 -4
  288. claude_mpm/models/agent_session.py +8 -6
  289. claude_mpm/models/git_repository.py +198 -0
  290. claude_mpm/models/resume_log.py +340 -0
  291. claude_mpm/scripts/claude-hook-handler.sh +35 -9
  292. claude_mpm/scripts/launch_monitor.py +85 -0
  293. claude_mpm/scripts/mcp_server.py +3 -5
  294. claude_mpm/scripts/mpm_doctor.py +3 -2
  295. claude_mpm/scripts/socketio_daemon.py +159 -512
  296. claude_mpm/scripts/start_activity_logging.py +3 -1
  297. claude_mpm/services/__init__.py +144 -160
  298. claude_mpm/services/agents/__init__.py +18 -5
  299. claude_mpm/services/agents/agent_builder.py +56 -18
  300. claude_mpm/services/agents/agent_preset_service.py +238 -0
  301. claude_mpm/services/agents/agent_selection_service.py +484 -0
  302. claude_mpm/services/agents/auto_config_manager.py +796 -0
  303. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  304. claude_mpm/services/agents/cache_git_manager.py +621 -0
  305. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  306. claude_mpm/services/agents/deployment/agent_deployment.py +164 -17
  307. claude_mpm/services/agents/deployment/agent_discovery_service.py +191 -41
  308. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +5 -5
  309. claude_mpm/services/agents/deployment/agent_format_converter.py +56 -12
  310. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -7
  311. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  312. claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
  313. claude_mpm/services/agents/deployment/agent_record_service.py +4 -4
  314. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  315. claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
  316. claude_mpm/services/agents/deployment/agent_template_builder.py +939 -50
  317. claude_mpm/services/agents/deployment/agent_validator.py +31 -7
  318. claude_mpm/services/agents/deployment/agent_version_manager.py +8 -5
  319. claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
  320. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  321. claude_mpm/services/agents/deployment/async_agent_deployment.py +3 -2
  322. claude_mpm/services/agents/deployment/deployment_config_loader.py +131 -7
  323. claude_mpm/services/agents/deployment/deployment_type_detector.py +10 -14
  324. claude_mpm/services/agents/deployment/deployment_wrapper.py +58 -0
  325. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  326. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  327. claude_mpm/services/agents/deployment/local_template_deployment.py +360 -0
  328. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +249 -53
  329. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  330. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +8 -7
  331. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  332. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  333. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +7 -5
  334. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  335. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +10 -10
  336. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  337. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  338. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -43
  339. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  340. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  341. claude_mpm/services/agents/deployment/validation/template_validator.py +64 -44
  342. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  343. claude_mpm/services/agents/git_source_manager.py +629 -0
  344. claude_mpm/services/agents/loading/agent_profile_loader.py +10 -9
  345. claude_mpm/services/agents/loading/base_agent_manager.py +16 -6
  346. claude_mpm/services/agents/loading/framework_agent_loader.py +11 -14
  347. claude_mpm/services/agents/local_template_manager.py +784 -0
  348. claude_mpm/services/agents/management/agent_capabilities_generator.py +3 -2
  349. claude_mpm/services/agents/management/agent_management_service.py +5 -5
  350. claude_mpm/services/agents/memory/agent_memory_manager.py +32 -29
  351. claude_mpm/services/agents/memory/content_manager.py +17 -9
  352. claude_mpm/services/agents/memory/memory_categorization_service.py +4 -2
  353. claude_mpm/services/agents/memory/memory_file_service.py +32 -6
  354. claude_mpm/services/agents/memory/memory_format_service.py +6 -4
  355. claude_mpm/services/agents/memory/memory_limits_service.py +4 -2
  356. claude_mpm/services/agents/memory/template_generator.py +3 -3
  357. claude_mpm/services/agents/observers.py +547 -0
  358. claude_mpm/services/agents/recommender.py +615 -0
  359. claude_mpm/services/agents/registry/deployed_agent_discovery.py +3 -3
  360. claude_mpm/services/agents/registry/modification_tracker.py +30 -19
  361. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  362. claude_mpm/services/agents/sources/__init__.py +13 -0
  363. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  364. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  365. claude_mpm/services/agents/startup_sync.py +239 -0
  366. claude_mpm/services/agents/toolchain_detector.py +474 -0
  367. claude_mpm/services/analysis/__init__.py +25 -0
  368. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  369. claude_mpm/services/analysis/postmortem_service.py +765 -0
  370. claude_mpm/services/async_session_logger.py +141 -98
  371. claude_mpm/services/claude_session_logger.py +82 -74
  372. claude_mpm/services/cli/agent_cleanup_service.py +5 -0
  373. claude_mpm/services/cli/agent_listing_service.py +5 -5
  374. claude_mpm/services/cli/agent_validation_service.py +3 -1
  375. claude_mpm/services/cli/memory_crud_service.py +12 -7
  376. claude_mpm/services/cli/memory_output_formatter.py +2 -2
  377. claude_mpm/services/cli/resume_service.py +617 -0
  378. claude_mpm/services/cli/session_manager.py +104 -13
  379. claude_mpm/services/cli/session_pause_manager.py +504 -0
  380. claude_mpm/services/cli/session_resume_helper.py +372 -0
  381. claude_mpm/services/cli/startup_checker.py +13 -10
  382. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  383. claude_mpm/services/command_deployment_service.py +209 -13
  384. claude_mpm/services/command_handler_service.py +11 -5
  385. claude_mpm/services/core/__init__.py +33 -1
  386. claude_mpm/services/core/base.py +31 -11
  387. claude_mpm/services/core/interfaces/__init__.py +88 -3
  388. claude_mpm/services/core/interfaces/agent.py +184 -0
  389. claude_mpm/services/core/interfaces/health.py +169 -0
  390. claude_mpm/services/core/interfaces/model.py +281 -0
  391. claude_mpm/services/core/interfaces/process.py +372 -0
  392. claude_mpm/services/core/interfaces/project.py +121 -0
  393. claude_mpm/services/core/interfaces/restart.py +307 -0
  394. claude_mpm/services/core/interfaces/stability.py +260 -0
  395. claude_mpm/services/core/interfaces.py +56 -1
  396. claude_mpm/services/core/memory_manager.py +92 -47
  397. claude_mpm/services/core/models/__init__.py +70 -0
  398. claude_mpm/services/core/models/agent_config.py +384 -0
  399. claude_mpm/services/core/models/health.py +162 -0
  400. claude_mpm/services/core/models/process.py +239 -0
  401. claude_mpm/services/core/models/restart.py +302 -0
  402. claude_mpm/services/core/models/stability.py +264 -0
  403. claude_mpm/services/core/models/toolchain.py +306 -0
  404. claude_mpm/services/core/path_resolver.py +36 -14
  405. claude_mpm/services/diagnostics/__init__.py +2 -2
  406. claude_mpm/services/diagnostics/checks/__init__.py +8 -2
  407. claude_mpm/services/diagnostics/checks/agent_check.py +30 -34
  408. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  409. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  410. claude_mpm/services/diagnostics/checks/common_issues_check.py +28 -27
  411. claude_mpm/services/diagnostics/checks/configuration_check.py +26 -25
  412. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  413. claude_mpm/services/diagnostics/checks/installation_check.py +165 -60
  414. claude_mpm/services/diagnostics/checks/instructions_check.py +21 -21
  415. claude_mpm/services/diagnostics/checks/mcp_check.py +57 -44
  416. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  417. claude_mpm/services/diagnostics/checks/monitor_check.py +24 -24
  418. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  419. claude_mpm/services/diagnostics/checks/startup_log_check.py +14 -11
  420. claude_mpm/services/diagnostics/diagnostic_runner.py +31 -13
  421. claude_mpm/services/diagnostics/doctor_reporter.py +305 -47
  422. claude_mpm/services/diagnostics/models.py +37 -21
  423. claude_mpm/services/event_aggregator.py +5 -3
  424. claude_mpm/services/event_bus/direct_relay.py +11 -7
  425. claude_mpm/services/event_bus/event_bus.py +51 -9
  426. claude_mpm/services/event_bus/relay.py +33 -14
  427. claude_mpm/services/events/consumers/dead_letter.py +7 -5
  428. claude_mpm/services/events/consumers/logging.py +1 -2
  429. claude_mpm/services/events/core.py +5 -6
  430. claude_mpm/services/events/producers/hook.py +6 -6
  431. claude_mpm/services/events/producers/system.py +8 -8
  432. claude_mpm/services/exceptions.py +5 -5
  433. claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
  434. claude_mpm/services/framework_claude_md_generator/content_assembler.py +5 -5
  435. claude_mpm/services/framework_claude_md_generator/content_validator.py +2 -2
  436. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
  437. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
  438. claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
  439. claude_mpm/services/git/__init__.py +21 -0
  440. claude_mpm/services/git/git_operations_service.py +494 -0
  441. claude_mpm/services/github/__init__.py +21 -0
  442. claude_mpm/services/github/github_cli_service.py +397 -0
  443. claude_mpm/services/hook_installer_service.py +506 -0
  444. claude_mpm/services/hook_service.py +5 -6
  445. claude_mpm/services/infrastructure/context_preservation.py +13 -11
  446. claude_mpm/services/infrastructure/daemon_manager.py +9 -9
  447. claude_mpm/services/infrastructure/logging.py +2 -2
  448. claude_mpm/services/infrastructure/monitoring/__init__.py +2 -6
  449. claude_mpm/services/infrastructure/monitoring/aggregator.py +13 -18
  450. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  451. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  452. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  453. claude_mpm/services/infrastructure/monitoring/resources.py +8 -7
  454. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  455. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  456. claude_mpm/services/instructions/__init__.py +9 -0
  457. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  458. claude_mpm/services/local_ops/__init__.py +155 -0
  459. claude_mpm/services/local_ops/crash_detector.py +257 -0
  460. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  461. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  462. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  463. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  464. claude_mpm/services/local_ops/health_manager.py +427 -0
  465. claude_mpm/services/local_ops/log_monitor.py +396 -0
  466. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  467. claude_mpm/services/local_ops/process_manager.py +595 -0
  468. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  469. claude_mpm/services/local_ops/restart_manager.py +401 -0
  470. claude_mpm/services/local_ops/restart_policy.py +387 -0
  471. claude_mpm/services/local_ops/state_manager.py +372 -0
  472. claude_mpm/services/local_ops/unified_manager.py +600 -0
  473. claude_mpm/services/mcp_config_manager.py +1542 -0
  474. claude_mpm/services/mcp_gateway/__init__.py +97 -93
  475. claude_mpm/services/mcp_gateway/auto_configure.py +43 -38
  476. claude_mpm/services/mcp_gateway/config/config_loader.py +3 -3
  477. claude_mpm/services/mcp_gateway/config/configuration.py +24 -5
  478. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  479. claude_mpm/services/mcp_gateway/core/base.py +20 -33
  480. claude_mpm/services/mcp_gateway/core/process_pool.py +591 -31
  481. claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
  482. claude_mpm/services/mcp_gateway/core/startup_verification.py +3 -3
  483. claude_mpm/services/mcp_gateway/main.py +90 -15
  484. claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
  485. claude_mpm/services/mcp_gateway/registry/tool_registry.py +12 -9
  486. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +5 -10
  487. claude_mpm/services/mcp_gateway/server/stdio_server.py +9 -17
  488. claude_mpm/services/mcp_gateway/tools/__init__.py +14 -2
  489. claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
  490. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +10 -9
  491. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +654 -0
  492. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +36 -34
  493. claude_mpm/services/mcp_gateway/tools/hello_world.py +8 -8
  494. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +555 -0
  495. claude_mpm/services/mcp_gateway/utils/__init__.py +14 -0
  496. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +160 -0
  497. claude_mpm/services/mcp_gateway/utils/update_preferences.py +170 -0
  498. claude_mpm/services/mcp_service_verifier.py +732 -0
  499. claude_mpm/services/memory/builder.py +9 -8
  500. claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
  501. claude_mpm/services/memory/cache/simple_cache.py +2 -2
  502. claude_mpm/services/memory/failure_tracker.py +578 -0
  503. claude_mpm/services/memory/indexed_memory.py +8 -8
  504. claude_mpm/services/memory/optimizer.py +8 -9
  505. claude_mpm/services/memory/router.py +3 -3
  506. claude_mpm/services/memory_hook_service.py +165 -4
  507. claude_mpm/services/model/__init__.py +147 -0
  508. claude_mpm/services/model/base_provider.py +365 -0
  509. claude_mpm/services/model/claude_provider.py +412 -0
  510. claude_mpm/services/model/model_router.py +452 -0
  511. claude_mpm/services/model/ollama_provider.py +415 -0
  512. claude_mpm/services/monitor/__init__.py +20 -0
  513. claude_mpm/services/monitor/daemon.py +691 -0
  514. claude_mpm/services/monitor/daemon_manager.py +1040 -0
  515. claude_mpm/services/monitor/event_emitter.py +350 -0
  516. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  517. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  518. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  519. claude_mpm/services/monitor/handlers/file.py +264 -0
  520. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  521. claude_mpm/services/monitor/management/__init__.py +18 -0
  522. claude_mpm/services/monitor/management/health.py +124 -0
  523. claude_mpm/services/monitor/management/lifecycle.py +724 -0
  524. claude_mpm/services/monitor/server.py +817 -0
  525. claude_mpm/services/monitor_build_service.py +2 -2
  526. claude_mpm/services/native_agent_converter.py +356 -0
  527. claude_mpm/services/orphan_detection.py +786 -0
  528. claude_mpm/services/port_manager.py +3 -3
  529. claude_mpm/services/pr/__init__.py +14 -0
  530. claude_mpm/services/pr/pr_template_service.py +329 -0
  531. claude_mpm/services/project/__init__.py +23 -0
  532. claude_mpm/services/project/analyzer.py +3 -3
  533. claude_mpm/services/project/architecture_analyzer.py +5 -5
  534. claude_mpm/services/project/archive_manager.py +1045 -0
  535. claude_mpm/services/project/dependency_analyzer.py +4 -4
  536. claude_mpm/services/project/detection_strategies.py +719 -0
  537. claude_mpm/services/project/documentation_manager.py +554 -0
  538. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  539. claude_mpm/services/project/metrics_collector.py +4 -4
  540. claude_mpm/services/project/project_organizer.py +1005 -0
  541. claude_mpm/services/project/registry.py +13 -7
  542. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  543. claude_mpm/services/project_port_allocator.py +596 -0
  544. claude_mpm/services/response_tracker.py +21 -10
  545. claude_mpm/services/runner_configuration_service.py +17 -3
  546. claude_mpm/services/self_upgrade_service.py +500 -0
  547. claude_mpm/services/session_management_service.py +23 -9
  548. claude_mpm/services/session_manager.py +380 -0
  549. claude_mpm/services/shared/__init__.py +2 -1
  550. claude_mpm/services/shared/async_service_base.py +16 -27
  551. claude_mpm/services/shared/config_service_base.py +17 -14
  552. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  553. claude_mpm/services/shared/service_factory.py +8 -5
  554. claude_mpm/services/skills/__init__.py +18 -0
  555. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  556. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  557. claude_mpm/services/skills_config.py +547 -0
  558. claude_mpm/services/skills_deployer.py +955 -0
  559. claude_mpm/services/socketio/client_proxy.py +60 -5
  560. claude_mpm/services/socketio/dashboard_server.py +361 -0
  561. claude_mpm/services/socketio/event_normalizer.py +10 -6
  562. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  563. claude_mpm/services/socketio/handlers/base.py +2 -2
  564. claude_mpm/services/socketio/handlers/code_analysis.py +90 -27
  565. claude_mpm/services/socketio/handlers/connection.py +22 -41
  566. claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
  567. claude_mpm/services/socketio/handlers/file.py +46 -10
  568. claude_mpm/services/socketio/handlers/git.py +9 -9
  569. claude_mpm/services/socketio/handlers/hook.py +29 -17
  570. claude_mpm/services/socketio/handlers/registry.py +4 -2
  571. claude_mpm/services/socketio/monitor_client.py +364 -0
  572. claude_mpm/services/socketio/server/broadcaster.py +9 -7
  573. claude_mpm/services/socketio/server/connection_manager.py +2 -2
  574. claude_mpm/services/socketio/server/core.py +142 -8
  575. claude_mpm/services/socketio/server/eventbus_integration.py +20 -14
  576. claude_mpm/services/socketio/server/main.py +24 -24
  577. claude_mpm/services/socketio_client_manager.py +4 -4
  578. claude_mpm/services/subprocess_launcher_service.py +19 -15
  579. claude_mpm/services/system_instructions_service.py +3 -5
  580. claude_mpm/services/ticket_services/formatter_service.py +1 -1
  581. claude_mpm/services/ticket_services/validation_service.py +5 -5
  582. claude_mpm/services/unified/__init__.py +65 -0
  583. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  584. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  585. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  586. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  587. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  588. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  589. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  590. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  591. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  592. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  593. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  594. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  595. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  596. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  597. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  598. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  599. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  600. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  601. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  602. claude_mpm/services/unified/interfaces.py +475 -0
  603. claude_mpm/services/unified/migration.py +509 -0
  604. claude_mpm/services/unified/strategies.py +534 -0
  605. claude_mpm/services/unified/unified_analyzer.py +542 -0
  606. claude_mpm/services/unified/unified_config.py +691 -0
  607. claude_mpm/services/unified/unified_deployment.py +466 -0
  608. claude_mpm/services/utility_service.py +6 -3
  609. claude_mpm/services/version_control/branch_strategy.py +2 -2
  610. claude_mpm/services/version_control/conflict_resolution.py +14 -8
  611. claude_mpm/services/version_control/git_operations.py +26 -24
  612. claude_mpm/services/version_control/semantic_versioning.py +14 -14
  613. claude_mpm/services/version_control/version_parser.py +14 -11
  614. claude_mpm/services/version_service.py +104 -1
  615. claude_mpm/services/visualization/__init__.py +1 -5
  616. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  617. claude_mpm/skills/__init__.py +42 -0
  618. claude_mpm/skills/agent_skills_injector.py +324 -0
  619. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  620. claude_mpm/skills/bundled/__init__.py +6 -0
  621. claude_mpm/skills/bundled/api-documentation.md +393 -0
  622. claude_mpm/skills/bundled/async-testing.md +571 -0
  623. claude_mpm/skills/bundled/code-review.md +143 -0
  624. claude_mpm/skills/bundled/database-migration.md +199 -0
  625. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  626. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  627. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  628. claude_mpm/skills/bundled/git-workflow.md +414 -0
  629. claude_mpm/skills/bundled/imagemagick.md +204 -0
  630. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  631. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  632. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  633. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  634. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  635. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  636. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  637. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  638. claude_mpm/skills/bundled/pdf.md +141 -0
  639. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  640. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  641. claude_mpm/skills/bundled/security-scanning.md +327 -0
  642. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  643. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  644. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  645. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  646. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  647. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  648. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  649. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  650. claude_mpm/skills/bundled/xlsx.md +157 -0
  651. claude_mpm/skills/registry.py +286 -0
  652. claude_mpm/skills/skill_manager.py +310 -0
  653. claude_mpm/skills/skills_registry.py +347 -0
  654. claude_mpm/skills/skills_service.py +739 -0
  655. claude_mpm/storage/state_storage.py +31 -31
  656. claude_mpm/templates/questions/__init__.py +38 -0
  657. claude_mpm/templates/questions/base.py +193 -0
  658. claude_mpm/templates/questions/pr_strategy.py +311 -0
  659. claude_mpm/templates/questions/project_init.py +385 -0
  660. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  661. claude_mpm/tools/__main__.py +9 -9
  662. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  663. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  664. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  665. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  666. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  667. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  668. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  669. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  670. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  671. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  672. claude_mpm/tools/code_tree_builder.py +6 -6
  673. claude_mpm/tools/code_tree_events.py +14 -10
  674. claude_mpm/tools/socketio_debug.py +11 -11
  675. claude_mpm/utils/agent_dependency_loader.py +184 -36
  676. claude_mpm/utils/agent_filters.py +288 -0
  677. claude_mpm/utils/common.py +544 -0
  678. claude_mpm/utils/config_manager.py +12 -6
  679. claude_mpm/utils/database_connector.py +298 -0
  680. claude_mpm/utils/dependency_cache.py +5 -3
  681. claude_mpm/utils/dependency_strategies.py +15 -10
  682. claude_mpm/utils/display_helper.py +260 -0
  683. claude_mpm/utils/environment_context.py +4 -3
  684. claude_mpm/utils/error_handler.py +5 -3
  685. claude_mpm/utils/file_utils.py +13 -14
  686. claude_mpm/utils/git_analyzer.py +407 -0
  687. claude_mpm/utils/gitignore.py +241 -0
  688. claude_mpm/utils/log_cleanup.py +627 -0
  689. claude_mpm/utils/migration.py +372 -0
  690. claude_mpm/utils/path_operations.py +7 -4
  691. claude_mpm/utils/progress.py +387 -0
  692. claude_mpm/utils/robust_installer.py +131 -24
  693. claude_mpm/utils/session_logging.py +2 -2
  694. claude_mpm/utils/structured_questions.py +619 -0
  695. claude_mpm/utils/subprocess_utils.py +9 -8
  696. claude_mpm/validation/agent_validator.py +6 -6
  697. claude_mpm/validation/frontmatter_validator.py +6 -6
  698. claude_mpm-5.0.9.dist-info/METADATA +1028 -0
  699. claude_mpm-5.0.9.dist-info/RECORD +864 -0
  700. {claude_mpm-4.1.26.dist-info → claude_mpm-5.0.9.dist-info}/entry_points.txt +1 -0
  701. claude_mpm/agents/INSTRUCTIONS.md +0 -261
  702. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  703. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  704. claude_mpm/agents/templates/agent-manager.json +0 -270
  705. claude_mpm/agents/templates/agent-manager.md +0 -619
  706. claude_mpm/agents/templates/agentic_coder_optimizer.json +0 -222
  707. claude_mpm/agents/templates/api_qa.json +0 -171
  708. claude_mpm/agents/templates/code_analyzer.json +0 -95
  709. claude_mpm/agents/templates/data_engineer.json +0 -152
  710. claude_mpm/agents/templates/documentation.json +0 -175
  711. claude_mpm/agents/templates/engineer.json +0 -176
  712. claude_mpm/agents/templates/imagemagick.json +0 -261
  713. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  714. claude_mpm/agents/templates/memory_manager.json +0 -155
  715. claude_mpm/agents/templates/ops.json +0 -175
  716. claude_mpm/agents/templates/project_organizer.json +0 -130
  717. claude_mpm/agents/templates/qa.json +0 -223
  718. claude_mpm/agents/templates/refactoring_engineer.json +0 -266
  719. claude_mpm/agents/templates/research.json +0 -163
  720. claude_mpm/agents/templates/security.json +0 -153
  721. claude_mpm/agents/templates/ticketing.json +0 -169
  722. claude_mpm/agents/templates/vercel_ops_agent.json +0 -281
  723. claude_mpm/agents/templates/version_control.json +0 -147
  724. claude_mpm/agents/templates/web_qa.json +0 -254
  725. claude_mpm/agents/templates/web_ui.json +0 -176
  726. claude_mpm/cli/commands/configure_tui.py +0 -1927
  727. claude_mpm/cli/commands/mpm_init.py +0 -594
  728. claude_mpm/cli/commands/socketio_monitor.py +0 -233
  729. claude_mpm/commands/mpm-agents.md +0 -12
  730. claude_mpm/commands/mpm-config.md +0 -18
  731. claude_mpm/commands/mpm-tickets.md +0 -102
  732. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  733. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  734. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  735. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  736. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  737. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  738. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  739. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  740. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  741. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  742. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  743. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  744. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  745. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  746. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  747. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  748. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  749. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  750. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  751. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  752. claude_mpm/dashboard/static/css/code-tree.css +0 -1408
  753. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  754. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  755. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  756. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  757. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  758. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  759. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  760. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  761. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  762. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  763. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  764. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  765. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  766. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  767. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  768. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  769. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  770. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  771. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  772. claude_mpm/dashboard/static/js/components/code-tree.js +0 -3220
  773. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -480
  774. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  775. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1040
  776. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  777. claude_mpm/scripts/socketio_daemon_hardened.py +0 -937
  778. claude_mpm/scripts/socketio_daemon_wrapper.py +0 -78
  779. claude_mpm/scripts/socketio_server_manager.py +0 -349
  780. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  781. claude_mpm/services/cli/dashboard_launcher.py +0 -423
  782. claude_mpm/services/cli/socketio_manager.py +0 -537
  783. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +0 -286
  784. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
  785. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
  786. claude_mpm/services/project/analyzer_refactored.py +0 -450
  787. claude_mpm/tools/code_tree_analyzer.py +0 -1693
  788. claude_mpm-4.1.26.dist-info/METADATA +0 -332
  789. claude_mpm-4.1.26.dist-info/RECORD +0 -606
  790. {claude_mpm-4.1.26.dist-info → claude_mpm-5.0.9.dist-info}/WHEEL +0 -0
  791. {claude_mpm-4.1.26.dist-info → claude_mpm-5.0.9.dist-info}/licenses/LICENSE +0 -0
  792. {claude_mpm-4.1.26.dist-info → claude_mpm-5.0.9.dist-info}/top_level.txt +0 -0
@@ -1,12 +1,12 @@
1
1
  /**
2
2
  * Unified Data Viewer Component
3
- *
3
+ *
4
4
  * Consolidates all data formatting and display logic from event-driven tabs
5
5
  * (Activity, Events, Agents) into a single, reusable component.
6
- *
6
+ *
7
7
  * WHY: Eliminates code duplication across multiple components and provides
8
8
  * consistent data display formatting throughout the dashboard.
9
- *
9
+ *
10
10
  * DESIGN DECISION: Auto-detects data type and applies appropriate formatting,
11
11
  * while allowing manual type specification for edge cases.
12
12
  */
@@ -16,6 +16,26 @@ class UnifiedDataViewer {
16
16
  this.container = document.getElementById(containerId);
17
17
  this.currentData = null;
18
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
+ });
19
39
  }
20
40
 
21
41
  /**
@@ -91,16 +111,16 @@ class UnifiedDataViewer {
91
111
  return 'event';
92
112
  }
93
113
 
94
- // Agent detection
95
- if (data.agent_name || data.agentName ||
114
+ // Agent detection
115
+ if (data.agent_name || data.agentName ||
96
116
  (data.name && (data.status === 'active' || data.status === 'completed'))) {
97
117
  return 'agent';
98
118
  }
99
119
 
100
120
  // Tool detection - PRIORITY: Check if it's a tool first
101
121
  // This includes TodoWrite tools which should always be displayed as tools, not todos
102
- if (data.tool_name || data.name === 'TodoWrite' || data.name === 'Read' ||
103
- data.tool_parameters || (data.params && data.icon) ||
122
+ if (data.tool_name || data.name === 'TodoWrite' || data.name === 'Read' ||
123
+ data.tool_parameters || (data.params && data.icon) ||
104
124
  (data.name && data.type === 'tool')) {
105
125
  return 'tool';
106
126
  }
@@ -131,7 +151,7 @@ class UnifiedDataViewer {
131
151
  }
132
152
 
133
153
  // File tool detection - handle file tools as file operations when they have file_path
134
- if ((data.name === 'Read' || data.name === 'Write' || data.name === 'Edit' ||
154
+ if ((data.name === 'Read' || data.name === 'Write' || data.name === 'Edit' ||
135
155
  data.name === 'MultiEdit' || data.name === 'Grep' || data.name === 'Glob') &&
136
156
  (data.params?.file_path || data.tool_parameters?.file_path)) {
137
157
  // Convert file tool to file operation format for better display
@@ -154,7 +174,7 @@ class UnifiedDataViewer {
154
174
  displayEvent(data) {
155
175
  const eventType = this.formatEventType(data);
156
176
  const timestamp = this.formatTimestamp(data.timestamp);
157
-
177
+
158
178
  let html = `
159
179
  <div class="unified-viewer-header">
160
180
  <h6>${eventType}</h6>
@@ -166,7 +186,7 @@ class UnifiedDataViewer {
166
186
  // PRIMARY DATA: Event-specific key details
167
187
  html += `<div class="primary-data">`;
168
188
  html += this.formatEventDetails(data);
169
-
189
+
170
190
  // Show important tool parameters inline if present
171
191
  if (data.tool_name || data.data?.tool_name) {
172
192
  const toolName = data.tool_name || data.data.tool_name;
@@ -176,7 +196,7 @@ class UnifiedDataViewer {
176
196
  <span class="detail-value">${this.getToolIcon(toolName)} ${toolName}</span>
177
197
  </div>
178
198
  `;
179
-
199
+
180
200
  // Show key parameters for specific tools
181
201
  const params = data.tool_parameters || data.data?.tool_parameters;
182
202
  if (params) {
@@ -216,7 +236,7 @@ class UnifiedDataViewer {
216
236
  const agentIcon = this.getAgentIcon(data.name || data.agentName);
217
237
  const agentName = data.name || data.agentName || 'Unknown Agent';
218
238
  const status = this.formatStatus(data.status);
219
-
239
+
220
240
  let html = `
221
241
  <div class="unified-viewer-header">
222
242
  <h6>${agentIcon} ${agentName}</h6>
@@ -227,7 +247,7 @@ class UnifiedDataViewer {
227
247
 
228
248
  // PRIMARY DATA: Key agent information
229
249
  html += `<div class="primary-data">`;
230
-
250
+
231
251
  // Status with visual indicator
232
252
  html += `
233
253
  <div class="detail-row highlight">
@@ -241,7 +261,7 @@ class UnifiedDataViewer {
241
261
  // Show active tools prominently
242
262
  const activeTools = data.tools.filter(t => t.status === 'in_progress');
243
263
  const completedTools = data.tools.filter(t => t.status === 'completed');
244
-
264
+
245
265
  if (activeTools.length > 0) {
246
266
  html += `
247
267
  <div class="active-tools-section">
@@ -257,7 +277,7 @@ class UnifiedDataViewer {
257
277
  });
258
278
  html += `</div></div>`;
259
279
  }
260
-
280
+
261
281
  html += `
262
282
  <div class="detail-row">
263
283
  <span class="detail-label">Tools Summary:</span>
@@ -277,7 +297,7 @@ class UnifiedDataViewer {
277
297
  </div>
278
298
  `;
279
299
  }
280
-
300
+
281
301
  html += `</div>`;
282
302
 
283
303
  // SECONDARY DATA: Collapsible JSON viewer
@@ -295,13 +315,13 @@ class UnifiedDataViewer {
295
315
  const toolName = data.name || data.tool_name || 'Unknown Tool';
296
316
  const toolIcon = this.getToolIcon(toolName);
297
317
  const status = this.formatStatus(data.status);
298
-
318
+
299
319
  // Special handling for TodoWrite tool
300
320
  if (toolName === 'TodoWrite') {
301
321
  this.displayTodoWriteTool(data);
302
322
  return;
303
323
  }
304
-
324
+
305
325
  let html = `
306
326
  <div class="unified-viewer-header">
307
327
  <h6>${toolIcon} ${toolName}</h6>
@@ -312,7 +332,7 @@ class UnifiedDataViewer {
312
332
 
313
333
  // PRIMARY DATA: Show important tool-specific information first
314
334
  const params = data.params || data.tool_parameters || {};
315
-
335
+
316
336
  // Tool-specific primary data display
317
337
  if (toolName === 'Read' || toolName === 'Edit' || toolName === 'Write') {
318
338
  // File tools - show file path prominently
@@ -415,7 +435,7 @@ class UnifiedDataViewer {
415
435
 
416
436
  // Collapsible JSON viewer for full details
417
437
  html += this.createCollapsibleJSON(data, 'Full Tool Details');
418
-
438
+
419
439
  html += '</div>';
420
440
  this.container.innerHTML = html;
421
441
  }
@@ -427,7 +447,7 @@ class UnifiedDataViewer {
427
447
  const status = this.formatStatus(data.status);
428
448
  const params = data.params || data.tool_parameters || {};
429
449
  const todos = params.todos || [];
430
-
450
+
431
451
  let html = `
432
452
  <div class="unified-viewer-header">
433
453
  <h6>📝 TodoWrite</h6>
@@ -439,7 +459,7 @@ class UnifiedDataViewer {
439
459
  // PRIMARY DATA: Todo list and status summary immediately after title
440
460
  if (todos.length > 0) {
441
461
  const statusCounts = this.getTodoStatusCounts(todos);
442
-
462
+
443
463
  // Status summary - horizontal single line format
444
464
  html += `
445
465
  <div class="todo-status-line">
@@ -453,13 +473,13 @@ class UnifiedDataViewer {
453
473
  html += `
454
474
  <div class="todo-list-primary">
455
475
  `;
456
-
476
+
457
477
  todos.forEach((todo, index) => {
458
478
  const statusIcon = this.getCheckboxIcon(todo.status);
459
- const displayText = todo.status === 'in_progress' ?
479
+ const displayText = todo.status === 'in_progress' ?
460
480
  (todo.activeForm || todo.content) : todo.content;
461
481
  const statusClass = this.formatStatusClass(todo.status);
462
-
482
+
463
483
  html += `
464
484
  <div class="todo-item ${todo.status}">
465
485
  <span class="todo-icon ${statusClass}">${statusIcon}</span>
@@ -468,7 +488,7 @@ class UnifiedDataViewer {
468
488
  </div>
469
489
  `;
470
490
  });
471
-
491
+
472
492
  html += `
473
493
  </div>
474
494
  `;
@@ -492,7 +512,7 @@ class UnifiedDataViewer {
492
512
 
493
513
  // Collapsible JSON viewer for full details
494
514
  html += this.createCollapsibleJSON(data, 'Full Details');
495
-
515
+
496
516
  html += '</div>';
497
517
  this.container.innerHTML = html;
498
518
  }
@@ -504,7 +524,7 @@ class UnifiedDataViewer {
504
524
  // Handle different data structures for standalone todos
505
525
  let todos;
506
526
  let toolName = 'Todo List';
507
-
527
+
508
528
  if (data.todos && Array.isArray(data.todos)) {
509
529
  todos = data.todos;
510
530
  } else if (Array.isArray(data)) {
@@ -514,7 +534,7 @@ class UnifiedDataViewer {
514
534
  } else {
515
535
  todos = [];
516
536
  }
517
-
537
+
518
538
  let html = `
519
539
  <div class="unified-viewer-header">
520
540
  <h6>📋 ${toolName}</h6>
@@ -527,13 +547,13 @@ class UnifiedDataViewer {
527
547
  html += `
528
548
  <div class="todo-list-primary">
529
549
  `;
530
-
550
+
531
551
  todos.forEach((todo) => {
532
552
  const statusIcon = this.getCheckboxIcon(todo.status);
533
- const displayText = todo.status === 'in_progress' ?
553
+ const displayText = todo.status === 'in_progress' ?
534
554
  (todo.activeForm || todo.content) : todo.content;
535
555
  const statusClass = this.formatStatusClass(todo.status);
536
-
556
+
537
557
  html += `
538
558
  <div class="todo-item ${todo.status}">
539
559
  <span class="todo-icon ${statusClass}">${statusIcon}</span>
@@ -542,7 +562,7 @@ class UnifiedDataViewer {
542
562
  </div>
543
563
  `;
544
564
  });
545
-
565
+
546
566
  html += `
547
567
  </div>
548
568
  `;
@@ -571,7 +591,7 @@ class UnifiedDataViewer {
571
591
  </div>
572
592
  <div class="unified-viewer-content">
573
593
  `;
574
-
594
+
575
595
  // PRIMARY DATA: The instruction text itself
576
596
  html += `
577
597
  <div class="primary-data">
@@ -589,7 +609,7 @@ class UnifiedDataViewer {
589
609
  if (Object.keys(data).length > 3) {
590
610
  html += this.createCollapsibleJSON(data, 'Full Instruction Data');
591
611
  }
592
-
612
+
593
613
  html += '</div>';
594
614
  this.container.innerHTML = html;
595
615
  }
@@ -646,35 +666,64 @@ class UnifiedDataViewer {
646
666
  }
647
667
 
648
668
  /**
649
- * Display file operation data with file viewing capabilities
669
+ * Display file operation data with enhanced file viewing capabilities
650
670
  */
651
671
  displayFileOperation(data) {
652
672
  const fileName = data.file_path ? data.file_path.split('/').pop() : 'Unknown File';
653
-
673
+ const isSingleFile = this.isSingleFileOperation(data);
674
+ const fileIcon = this.getFileIcon(data.file_path);
675
+ const fileType = this.getFileType(data.file_path);
676
+
654
677
  let html = `
655
- <div class="unified-viewer-header">
656
- <h6>📄 File: ${fileName}</h6>
678
+ <div class="unified-viewer-header ${isSingleFile ? 'single-file-header' : ''}">
679
+ <h6>${fileIcon} File: ${fileName}</h6>
657
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>` : ''}
658
682
  </div>
659
683
  <div class="unified-viewer-content">
660
684
  <div class="primary-data">
661
685
  <div class="detail-row highlight">
662
686
  <span class="detail-label">📁 File Path:</span>
663
- <span class="detail-value code">${data.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>
664
694
  </div>
665
695
  `;
666
696
 
667
- // Add file viewing button for tracked files
697
+ // Enhanced file viewing for single file operations
668
698
  if (data.file_path) {
699
+ const shouldShowPreview = this.shouldShowInlinePreview(data);
700
+
669
701
  html += `
670
- <div class="file-actions">
671
- <button class="file-action-btn view-file-btn"
702
+ <div class="file-actions ${isSingleFile ? 'single-file-actions' : ''}">
703
+ <button class="file-action-btn view-file-btn ${isSingleFile ? 'primary-action' : ''}"
672
704
  onclick="window.showFileViewerModal && window.showFileViewerModal('${data.file_path}')"
673
705
  title="View file contents with syntax highlighting">
674
- 👁️ View File Contents
706
+ ${fileIcon} View File Contents
675
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
+ ` : ''}
676
715
  </div>
677
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
+ }
678
727
  }
679
728
 
680
729
  html += `</div>`;
@@ -713,7 +762,7 @@ class UnifiedDataViewer {
713
762
  */
714
763
  displayHook(data) {
715
764
  const hookType = data.event_type || data.subtype || 'unknown';
716
-
765
+
717
766
  let html = `
718
767
  <div class="unified-viewer-header">
719
768
  <h6>🔗 Hook: ${hookType}</h6>
@@ -742,14 +791,14 @@ class UnifiedDataViewer {
742
791
  if (typeof data === 'object' && data !== null) {
743
792
  // Display meaningful properties
744
793
  const meaningfulProps = ['id', 'name', 'type', 'status', 'timestamp', 'text', 'content', 'message'];
745
-
794
+
746
795
  for (let prop of meaningfulProps) {
747
796
  if (data[prop] !== undefined) {
748
797
  let value = data[prop];
749
798
  if (typeof value === 'string' && value.length > 200) {
750
799
  value = value.substring(0, 200) + '...';
751
800
  }
752
-
801
+
753
802
  html += `
754
803
  <div class="detail-row">
755
804
  <span class="detail-label">${prop}:</span>
@@ -788,7 +837,7 @@ class UnifiedDataViewer {
788
837
  */
789
838
  formatEventDetails(event) {
790
839
  const data = event.data || {};
791
-
840
+
792
841
  switch (event.type) {
793
842
  case 'hook':
794
843
  return this.formatHookDetails(event);
@@ -809,7 +858,7 @@ class UnifiedDataViewer {
809
858
  formatHookDetails(event) {
810
859
  const data = event.data || {};
811
860
  const hookType = event.subtype || event.event_type || 'unknown';
812
-
861
+
813
862
  let html = `
814
863
  <div class="detail-row">
815
864
  <span class="detail-label">Hook Type:</span>
@@ -999,7 +1048,7 @@ class UnifiedDataViewer {
999
1048
  formatEventData(event) {
1000
1049
  const data = event.data;
1001
1050
  if (!data || Object.keys(data).length === 0) return '';
1002
-
1051
+
1003
1052
  return `
1004
1053
  <div class="detail-section">
1005
1054
  <span class="detail-section-title">Event Data:</span>
@@ -1055,11 +1104,11 @@ class UnifiedDataViewer {
1055
1104
  }
1056
1105
  } else if (typeof value === 'object' && value !== null) {
1057
1106
  // Special handling for todos array - display as formatted list instead of raw JSON
1058
- if (Array.isArray(value) && value.length > 0 &&
1107
+ if (Array.isArray(value) && value.length > 0 &&
1059
1108
  value[0].hasOwnProperty('content') && value[0].hasOwnProperty('status')) {
1060
1109
  return this.formatTodosAsParameter(value);
1061
1110
  }
1062
-
1111
+
1063
1112
  try {
1064
1113
  return `<pre class="param-json">${this.escapeHtml(JSON.stringify(value, null, 2))}</pre>`;
1065
1114
  } catch (e) {
@@ -1075,7 +1124,7 @@ class UnifiedDataViewer {
1075
1124
  */
1076
1125
  formatTodosAsParameter(todos) {
1077
1126
  const statusCounts = this.getTodoStatusCounts(todos);
1078
-
1127
+
1079
1128
  let html = `
1080
1129
  <div class="param-todos">
1081
1130
  <div class="param-todos-header">
@@ -1086,13 +1135,13 @@ class UnifiedDataViewer {
1086
1135
  </div>
1087
1136
  <div class="param-todos-list">
1088
1137
  `;
1089
-
1138
+
1090
1139
  todos.forEach((todo, index) => {
1091
1140
  const statusIcon = this.getCheckboxIcon(todo.status);
1092
- const displayText = todo.status === 'in_progress' ?
1141
+ const displayText = todo.status === 'in_progress' ?
1093
1142
  (todo.activeForm || todo.content) : todo.content;
1094
1143
  const statusClass = this.formatStatusClass(todo.status);
1095
-
1144
+
1096
1145
  html += `
1097
1146
  <div class="param-todo-item ${todo.status}">
1098
1147
  <div class="param-todo-checkbox">
@@ -1105,15 +1154,234 @@ class UnifiedDataViewer {
1105
1154
  </div>
1106
1155
  `;
1107
1156
  });
1108
-
1157
+
1109
1158
  html += `
1110
1159
  </div>
1111
1160
  </div>
1112
1161
  `;
1113
-
1162
+
1114
1163
  return html;
1115
1164
  }
1116
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
+
1117
1385
  // ==================== UTILITY METHODS ====================
1118
1386
 
1119
1387
  /**
@@ -1121,7 +1389,7 @@ class UnifiedDataViewer {
1121
1389
  */
1122
1390
  formatTimestamp(timestamp) {
1123
1391
  if (!timestamp) return 'Unknown time';
1124
-
1392
+
1125
1393
  try {
1126
1394
  const date = new Date(timestamp);
1127
1395
  if (isNaN(date.getTime())) return 'Invalid date';
@@ -1136,16 +1404,16 @@ class UnifiedDataViewer {
1136
1404
  */
1137
1405
  formatStatus(status) {
1138
1406
  if (!status) return 'unknown';
1139
-
1407
+
1140
1408
  const statusMap = {
1141
1409
  'active': '🟢 Active',
1142
- 'completed': '✅ Completed',
1410
+ 'completed': '✅ Completed',
1143
1411
  'in_progress': '🔄 In Progress',
1144
1412
  'pending': '⏳ Pending',
1145
1413
  'error': '❌ Error',
1146
1414
  'failed': '❌ Failed'
1147
1415
  };
1148
-
1416
+
1149
1417
  return statusMap[status] || status;
1150
1418
  }
1151
1419
 
@@ -1182,7 +1450,7 @@ class UnifiedDataViewer {
1182
1450
  getToolIcon(toolName) {
1183
1451
  const icons = {
1184
1452
  'Read': '👁️',
1185
- 'Write': '✍️',
1453
+ 'Write': '✍️',
1186
1454
  'Edit': '✏️',
1187
1455
  'MultiEdit': '📝',
1188
1456
  'Bash': '💻',
@@ -1233,7 +1501,7 @@ class UnifiedDataViewer {
1233
1501
  convertToolToFileOperation(toolData) {
1234
1502
  const params = toolData.params || toolData.tool_parameters || {};
1235
1503
  const filePath = params.file_path || params.path || params.notebook_path;
1236
-
1504
+
1237
1505
  if (!filePath) {
1238
1506
  return toolData; // Return original if no file path
1239
1507
  }
@@ -1265,13 +1533,13 @@ class UnifiedDataViewer {
1265
1533
  */
1266
1534
  getTodoStatusCounts(todos) {
1267
1535
  const counts = { completed: 0, in_progress: 0, pending: 0 };
1268
-
1536
+
1269
1537
  todos.forEach(todo => {
1270
1538
  if (counts.hasOwnProperty(todo.status)) {
1271
1539
  counts[todo.status]++;
1272
1540
  }
1273
1541
  });
1274
-
1542
+
1275
1543
  return counts;
1276
1544
  }
1277
1545
 
@@ -1280,12 +1548,118 @@ class UnifiedDataViewer {
1280
1548
  */
1281
1549
  escapeHtml(text) {
1282
1550
  if (typeof text !== 'string') return '';
1283
-
1551
+
1284
1552
  const div = document.createElement('div');
1285
1553
  div.textContent = text;
1286
1554
  return div.innerHTML;
1287
1555
  }
1288
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
+
1289
1663
  /**
1290
1664
  * Create a collapsible JSON viewer for secondary details
1291
1665
  * Provides a clean way to show full data without cluttering the main view
@@ -1293,26 +1667,32 @@ class UnifiedDataViewer {
1293
1667
  createCollapsibleJSON(data, title = 'Full Details') {
1294
1668
  // Generate unique ID for this collapsible section
1295
1669
  const sectionId = `json-details-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
1296
-
1670
+
1297
1671
  // Filter out sensitive or overly verbose properties
1298
1672
  const cleanData = this.cleanDataForDisplay(data);
1299
-
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
+
1300
1687
  return `
1301
1688
  <div class="collapsible-json-section">
1302
- <button class="collapsible-json-toggle" onclick="
1303
- const content = document.getElementById('${sectionId}');
1304
- const button = this;
1305
- if (content.style.display === 'none' || content.style.display === '') {
1306
- content.style.display = 'block';
1307
- button.classList.add('expanded');
1308
- button.innerHTML = ' ${title}';
1309
- } else {
1310
- content.style.display = 'none';
1311
- button.classList.remove('expanded');
1312
- button.innerHTML = '▶ ${title}';
1313
- }
1314
- ">▶ ${title}</button>
1315
- <div id="${sectionId}" class="collapsible-json-content" style="display: none;">
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};">
1316
1696
  <pre class="json-viewer">${this.escapeHtml(JSON.stringify(cleanData, null, 2))}</pre>
1317
1697
  </div>
1318
1698
  </div>
@@ -1325,7 +1705,7 @@ class UnifiedDataViewer {
1325
1705
  */
1326
1706
  cleanDataForDisplay(data) {
1327
1707
  const seen = new WeakSet();
1328
-
1708
+
1329
1709
  return JSON.parse(JSON.stringify(data, (key, value) => {
1330
1710
  // Handle circular references
1331
1711
  if (typeof value === 'object' && value !== null) {
@@ -1334,17 +1714,17 @@ class UnifiedDataViewer {
1334
1714
  }
1335
1715
  seen.add(value);
1336
1716
  }
1337
-
1717
+
1338
1718
  // Truncate very long strings
1339
1719
  if (typeof value === 'string' && value.length > 1000) {
1340
1720
  return value.substring(0, 1000) + '... [truncated]';
1341
1721
  }
1342
-
1722
+
1343
1723
  // Handle functions
1344
1724
  if (typeof value === 'function') {
1345
1725
  return '[Function]';
1346
1726
  }
1347
-
1727
+
1348
1728
  return value;
1349
1729
  }));
1350
1730
  }
@@ -1389,4 +1769,56 @@ export { UnifiedDataViewer };
1389
1769
  export default UnifiedDataViewer;
1390
1770
 
1391
1771
  // Make globally available for non-module usage
1392
- window.UnifiedDataViewer = UnifiedDataViewer;
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
+ }