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.
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,233 +0,0 @@
1
- """Socket.IO monitoring functionality for run commands.
2
-
3
- This module provides Socket.IO server management and monitoring dashboard functionality.
4
- Extracted from run.py to reduce complexity and improve maintainability.
5
- """
6
-
7
- import os
8
- import subprocess
9
- import sys
10
- import webbrowser
11
-
12
- from ...core.unified_paths import get_package_root
13
- from ...services.port_manager import PortManager
14
-
15
-
16
- class SocketIOMonitor:
17
- """Handles Socket.IO monitoring and server management."""
18
-
19
- def __init__(self, logger):
20
- """Initialize the Socket.IO monitor."""
21
- self.logger = logger
22
-
23
- def launch_monitor(self, port):
24
- """
25
- Launch the Socket.IO monitoring dashboard using static HTML file.
26
-
27
- Returns:
28
- tuple: (success: bool, browser_opened: bool)
29
- """
30
- try:
31
- # Verify Socket.IO dependencies are available
32
- try:
33
- import aiohttp
34
- import engineio
35
- import socketio
36
-
37
- self.logger.debug("Socket.IO dependencies verified")
38
- except ImportError as e:
39
- self.logger.error(f"Socket.IO dependencies not available: {e}")
40
- print(f"❌ Socket.IO dependencies missing: {e}")
41
- print(" This is unexpected - dependency installation may have failed.")
42
- return False, False
43
-
44
- print("🚀 Setting up Socket.IO monitor...")
45
- self.logger.info(f"Launching Socket.IO monitor (requested port: {port})")
46
-
47
- # First, check if there's already a running SocketIO server
48
- port_manager = PortManager()
49
- port_manager.cleanup_dead_instances()
50
- active_instances = port_manager.list_active_instances()
51
-
52
- if active_instances:
53
- # Use the first active instance (prefer port 8765 if available)
54
- socketio_port = None
55
- for instance in active_instances:
56
- if instance.get("port") == 8765:
57
- socketio_port = 8765
58
- break
59
- if not socketio_port:
60
- socketio_port = active_instances[0].get("port")
61
-
62
- print(f"🔍 Found existing SocketIO server on port {socketio_port}")
63
- server_running = True
64
- else:
65
- # No existing server, use requested port
66
- socketio_port = port
67
- server_running = self.check_server_running(socketio_port)
68
-
69
- # Use HTTP URL to access dashboard from Socket.IO server
70
- dashboard_url = f"http://localhost:{socketio_port}"
71
-
72
- if server_running:
73
- print(f"✅ Socket.IO server already running on port {socketio_port}")
74
- print(f"📊 Dashboard: {dashboard_url}")
75
-
76
- # Open browser with static HTML file
77
- try:
78
- # Check if we should suppress browser opening (for tests)
79
- if os.environ.get("CLAUDE_MPM_NO_BROWSER") != "1":
80
- print("🌐 Opening dashboard in browser...")
81
- self.open_in_browser_tab(dashboard_url)
82
- self.logger.info(f"Socket.IO dashboard opened: {dashboard_url}")
83
- else:
84
- print("🌐 Browser opening suppressed (CLAUDE_MPM_NO_BROWSER=1)")
85
- self.logger.info(
86
- "Browser opening suppressed by environment variable"
87
- )
88
- return True, True
89
- except Exception as e:
90
- self.logger.warning(f"Failed to open browser: {e}")
91
- print("⚠️ Could not open browser automatically")
92
- print(f"📊 Please open manually: {dashboard_url}")
93
- return True, False
94
- else:
95
- # Start standalone Socket.IO server
96
- print("🔧 Starting Socket.IO server...")
97
- server_started = self.start_standalone_server(socketio_port)
98
-
99
- if server_started:
100
- print("✅ Socket.IO server started successfully")
101
- print(f"📊 Dashboard: {dashboard_url}")
102
-
103
- # Open browser
104
- try:
105
- if os.environ.get("CLAUDE_MPM_NO_BROWSER") != "1":
106
- print("🌐 Opening dashboard in browser...")
107
- self.open_in_browser_tab(dashboard_url)
108
- self.logger.info(
109
- f"Socket.IO dashboard opened: {dashboard_url}"
110
- )
111
- else:
112
- print(
113
- "🌐 Browser opening suppressed (CLAUDE_MPM_NO_BROWSER=1)"
114
- )
115
- return True, True
116
- except Exception as e:
117
- self.logger.warning(f"Failed to open browser: {e}")
118
- print("⚠️ Could not open browser automatically")
119
- print(f"📊 Please open manually: {dashboard_url}")
120
- return True, False
121
- else:
122
- print("❌ Failed to start Socket.IO server")
123
- print("💡 Troubleshooting tips:")
124
- print(f" - Check if port {socketio_port} is already in use")
125
- print(
126
- " - Verify Socket.IO dependencies: pip install python-socketio aiohttp"
127
- )
128
- print(" - Try a different port with --websocket-port")
129
- return False, False
130
-
131
- except Exception as e:
132
- self.logger.error(f"Failed to launch Socket.IO monitor: {e}")
133
- print(f"❌ Failed to launch Socket.IO monitor: {e}")
134
- return False, False
135
-
136
- def check_server_running(self, port):
137
- """Check if a Socket.IO server is running on the specified port."""
138
- try:
139
- import socket
140
- import urllib.error
141
- import urllib.request
142
-
143
- # First, do a basic TCP connection check
144
- try:
145
- with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
146
- s.settimeout(2.0)
147
- result = s.connect_ex(("127.0.0.1", port))
148
- if result != 0:
149
- self.logger.debug(f"TCP connection to port {port} failed")
150
- return False
151
- except Exception as e:
152
- self.logger.debug(f"TCP socket check failed for port {port}: {e}")
153
- return False
154
-
155
- # If TCP connection succeeds, try HTTP health check
156
- try:
157
- response = urllib.request.urlopen(
158
- f"http://localhost:{port}/status", timeout=5
159
- )
160
- if response.getcode() == 200:
161
- self.logger.debug(
162
- f"✅ Socket.IO server health check passed on port {port}"
163
- )
164
- return True
165
- except Exception as e:
166
- self.logger.debug(f"HTTP health check failed for port {port}: {e}")
167
-
168
- except Exception as e:
169
- self.logger.debug(
170
- f"❌ Unexpected error checking Socket.IO server on port {port}: {e}"
171
- )
172
-
173
- return False
174
-
175
- def start_standalone_server(self, port):
176
- """Start a standalone Socket.IO server using the Python daemon."""
177
- try:
178
- daemon_script = get_package_root() / "scripts" / "socketio_daemon.py"
179
- if not daemon_script.exists():
180
- self.logger.error(f"Daemon script not found: {daemon_script}")
181
- return False
182
-
183
- # Start the daemon
184
- result = subprocess.run(
185
- [sys.executable, str(daemon_script), "start", "--port", str(port)],
186
- capture_output=True,
187
- text=True,
188
- timeout=30,
189
- check=False,
190
- )
191
-
192
- if result.returncode == 0:
193
- self.logger.info(
194
- f"Socket.IO daemon started successfully on port {port}"
195
- )
196
- return True
197
- self.logger.error(f"Failed to start Socket.IO daemon: {result.stderr}")
198
- return False
199
-
200
- except Exception as e:
201
- self.logger.error(f"Failed to start standalone Socket.IO server: {e}")
202
- return False
203
-
204
- def open_in_browser_tab(self, url):
205
- """Open URL in browser, attempting to reuse existing tabs when possible."""
206
- try:
207
- # Try different methods based on platform
208
- import platform
209
-
210
- system = platform.system().lower()
211
-
212
- if system == "darwin": # macOS
213
- try:
214
- # Try to open in existing tab
215
- subprocess.run(["open", "-g", url], check=True, timeout=5)
216
- return
217
- except Exception:
218
- pass
219
- elif system == "linux":
220
- try:
221
- # Try xdg-open
222
- subprocess.run(["xdg-open", url], check=True, timeout=5)
223
- return
224
- except Exception:
225
- pass
226
-
227
- # Fallback to standard webbrowser
228
- webbrowser.open(url)
229
-
230
- except Exception as e:
231
- self.logger.warning(f"Browser opening failed: {e}")
232
- # Final fallback
233
- webbrowser.open(url)
@@ -1,12 +0,0 @@
1
- # Show available agents and their versions
2
-
3
- Show all available Claude MPM agents with their versions and deployment status.
4
-
5
- This command displays:
6
- - Agent names and descriptions
7
- - Version information
8
- - Tool availability
9
- - Model preferences
10
- - Deployment status
11
-
12
- Usage: /mpm-agents
@@ -1,18 +0,0 @@
1
- # View or modify claude-mpm configuration
2
-
3
- Manage Claude MPM configuration settings.
4
-
5
- Usage: /mpm-config [key] [value]
6
-
7
- Examples:
8
- - /mpm-config - Show all configuration
9
- - /mpm-config list - List all configuration keys
10
- - /mpm-config set logging debug - Set logging level to debug
11
- - /mpm-config get websocket-port - Get WebSocket port setting
12
-
13
- Configuration categories:
14
- - logging: Logging levels and output
15
- - websocket: WebSocket server settings
16
- - hooks: Hook service configuration
17
- - memory: Memory system settings
18
- - agents: Agent deployment options
@@ -1,102 +0,0 @@
1
- # mpm-tickets
2
-
3
- Create and manage tickets using aitrackdown
4
-
5
- ## Usage
6
-
7
- Use this command to create and manage tickets (epics, issues, tasks) through aitrackdown CLI integration.
8
-
9
- ## Commands
10
-
11
- ### Create tickets
12
- ```bash
13
- # Create an epic
14
- aitrackdown create epic "Title" --description "Description"
15
-
16
- # Create an issue
17
- aitrackdown create issue "Title" --description "Description"
18
-
19
- # Create a task
20
- aitrackdown create task "Title" --description "Description"
21
-
22
- # Create task under an issue
23
- aitrackdown create task "Title" --issue ISS-0001
24
- ```
25
-
26
- ### View tickets
27
- ```bash
28
- # Show all tasks
29
- aitrackdown status tasks
30
-
31
- # Show specific ticket
32
- aitrackdown show ISS-0001
33
- ```
34
-
35
- ### Update tickets
36
- ```bash
37
- # Change status
38
- aitrackdown transition ISS-0001 in-progress
39
- aitrackdown transition ISS-0001 done
40
-
41
- # Add comment
42
- aitrackdown comment ISS-0001 "Your comment"
43
- ```
44
-
45
- ### Search tickets
46
- ```bash
47
- aitrackdown search tasks "keyword"
48
- ```
49
-
50
- ## Ticket Types
51
-
52
- - **EP-XXXX**: Epics (major initiatives)
53
- - **ISS-XXXX**: Issues (bugs, features, user requests)
54
- - **TSK-XXXX**: Tasks (individual work items)
55
-
56
- ## Workflow States
57
-
58
- Valid transitions:
59
- - `open` → `in-progress` → `ready` → `tested` → `done`
60
- - Any state → `waiting` (when blocked)
61
- - Any state → `closed` (to close)
62
-
63
- ## Examples
64
-
65
- ### Bug Report Flow
66
- ```bash
67
- # Create issue for bug
68
- aitrackdown create issue "Login bug" --description "Users can't login" --severity high
69
-
70
- # Create investigation task
71
- aitrackdown create task "Investigate login bug" --issue ISS-0001
72
-
73
- # Update status
74
- aitrackdown transition TSK-0001 in-progress
75
- aitrackdown comment TSK-0001 "Found the issue"
76
-
77
- # Complete
78
- aitrackdown transition TSK-0001 done
79
- aitrackdown transition ISS-0001 done
80
- ```
81
-
82
- ### Feature Implementation
83
- ```bash
84
- # Create epic
85
- aitrackdown create epic "OAuth2 Support"
86
-
87
- # Create issues
88
- aitrackdown create issue "Google OAuth2" --description "Add Google auth"
89
- aitrackdown create issue "GitHub OAuth2" --description "Add GitHub auth"
90
-
91
- # Create tasks
92
- aitrackdown create task "Design OAuth flow" --issue ISS-0001
93
- aitrackdown create task "Implement Google client" --issue ISS-0001
94
- ```
95
-
96
- ## Tips
97
-
98
- - Always use aitrackdown directly (not claude-mpm tickets)
99
- - Check ticket exists with `show` before updating
100
- - Add comments to document progress
101
- - Use `--severity` for bugs, `--priority` for features
102
- - Associate tasks with issues using `--issue`
@@ -1,2 +0,0 @@
1
- import{U as e}from"./unified-data-viewer.js";class t{constructor(){this.container=null,this.events=[],this.processedEventIds=new Set,this.sessions=new Map,this.currentSession=null,this.selectedSessionFilter="all",this.timeRange="30min",this.searchTerm="",this.initialized=!1,this.expandedSessions=new Set,this.expandedAgents=new Set,this.expandedTools=new Set,this.selectedItem=null,this.renderTreeDebounced=this.debounce(()=>this.renderTree(),100)}debounce(e,t){let s;return function(...n){clearTimeout(s),s=setTimeout(()=>{clearTimeout(s),e(...n)},t)}}initialize(){if(console.log("ActivityTree.initialize() called, initialized:",this.initialized),this.initialized)return void console.log("Activity tree already initialized, skipping");if(this.container=document.getElementById("activity-tree-container"),!this.container&&(this.container=document.getElementById("activity-tree"),!this.container))return void console.error("Activity tree container not found in DOM");const e=document.getElementById("activity-tab");if(e){if(!e.classList.contains("active"))return console.log("Activity tab not active, initializing but deferring render"),this.setupControls(),this.subscribeToEvents(),void(this.initialized=!0);this.setupControls(),this.createLinearTreeView(),this.subscribeToEvents(),this.initialized=!0,console.log("Activity tree initialization complete")}else console.error("Activity tab panel (#activity-tab) not found in DOM")}forceShow(){console.log("ActivityTree.forceShow() called"),this.container||(this.container=document.getElementById("activity-tree-container")||document.getElementById("activity-tree"),this.container)?(this.createLinearTreeView(),this.renderTree()):console.error("Cannot find activity tree container")}renderWhenVisible(){if(console.log("ActivityTree.renderWhenVisible() called"),!this.initialized)return console.log("Not initialized yet, calling initialize..."),void this.initialize();this.createLinearTreeView(),this.renderTree()}setupControls(){const e=document.getElementById("time-range");e&&e.addEventListener("change",e=>{this.timeRange=e.target.value,console.log(`ActivityTree: Time range changed to: ${this.timeRange}`),this.renderTree()}),document.addEventListener("sessionFilterChanged",e=>{this.selectedSessionFilter=e.detail.sessionId||"all",console.log(`ActivityTree: Session filter changed to: ${this.selectedSessionFilter} (from SessionManager)`),this.renderTree()}),document.addEventListener("sessionChanged",e=>{this.selectedSessionFilter=e.detail.sessionId||"all",console.log(`ActivityTree: Session changed to: ${this.selectedSessionFilter} (from SessionManager - backward compat)`),this.renderTree()}),setTimeout(()=>{if(window.sessionManager){const e=window.sessionManager.getCurrentFilter();e!==this.selectedSessionFilter&&(this.selectedSessionFilter=e||"all",console.log(`ActivityTree: Initialized with current session filter: ${this.selectedSessionFilter}`),this.renderTree())}},100);const t=document.getElementById("expand-all");t&&t.addEventListener("click",()=>this.expandAllSessions());const s=document.getElementById("collapse-all");s&&s.addEventListener("click",()=>this.collapseAllSessions());const n=document.getElementById("reset-zoom");n&&(n.style.display="inline-block",n.addEventListener("click",()=>this.resetZoom()));const o=document.getElementById("activity-search");o&&o.addEventListener("input",e=>{this.searchTerm=e.target.value.toLowerCase(),this.renderTree()})}createLinearTreeView(){console.log("Creating linear tree view"),this.container.innerHTML="";const e=document.createElement("div");e.id="linear-tree",e.className="linear-tree",this.container.appendChild(e),console.log("Linear tree view created")}subscribeToEvents(){if(!window.socketClient)return console.warn("Socket client not available for activity tree"),void setTimeout(()=>this.subscribeToEvents(),1e3);console.log("ActivityTree: Setting up event subscription"),window.socketClient.onEventUpdate((e,t)=>{console.log(`ActivityTree: onEventUpdate called with ${e.length} total events and ${t.size} sessions`);for(const[n,o]of t.entries())if(this.sessions.has(n)){const e=this.sessions.get(n);e.timestamp=new Date(o.lastActivity||o.startTime||e.timestamp),e.eventCount=o.eventCount,e.status=o.status||e.status,e.working_directory=o.working_directory||e.working_directory,e.git_branch=o.git_branch||e.git_branch}else{const e={id:n,timestamp:new Date(o.lastActivity||o.startTime||new Date),expanded:this.expandedSessions.has(n)||!0,agents:new Map,todos:[],userInstructions:[],tools:[],toolsMap:new Map,status:"active",currentTodoTool:null,working_directory:o.working_directory,git_branch:o.git_branch,eventCount:o.eventCount};this.sessions.set(n,e)}const s=e.filter(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;return!this.processedEventIds.has(t)});s.length>0&&(console.log(`ActivityTree: Processing ${s.length} new events`,s),s.forEach(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;this.processedEventIds.add(t),this.processEvent(e)})),this.events=[...e],this.renderTreeDebounced(),console.log("ActivityTree: Sessions after sync with socket client:",Array.from(this.sessions.entries()))});const e=window.socketClient?.getState();if(e&&e.events.length>0){console.log(`ActivityTree: Loading existing data - ${e.events.length} events, ${e.sessions.size} sessions`);for(const[s,n]of e.sessions.entries())if(!this.sessions.has(s)){const e={id:s,timestamp:new Date(n.lastActivity||n.startTime||new Date),expanded:this.expandedSessions.has(s)||!0,agents:new Map,todos:[],userInstructions:[],tools:[],toolsMap:new Map,status:"active",currentTodoTool:null,working_directory:n.working_directory,git_branch:n.git_branch,eventCount:n.eventCount};this.sessions.set(s,e)}const t=e.events.filter(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;return!this.processedEventIds.has(t)});t.length>0&&(console.log(`ActivityTree: Processing ${t.length} unprocessed events from initial load`),t.forEach(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;this.processedEventIds.add(t),this.processEvent(e)})),this.events=[...e.events],this.renderTree(),console.log("ActivityTree: Initial sessions state:",Array.from(this.sessions.entries()))}else console.log("ActivityTree: No existing events found"),this.events=[],this.sessions.clear(),this.renderTree()}processEvent(e){if(!e)return void console.log("ActivityTree: Ignoring null event");let t,s=this.getEventType(e);if(!s)return;console.log(`ActivityTree: Processing event: ${s}`,e),e.timestamp?(t=new Date(e.timestamp),isNaN(t.getTime())&&(console.warn("ActivityTree: Invalid timestamp, using current time:",e.timestamp),t=new Date)):(console.warn("ActivityTree: No timestamp found, using current time"),t=new Date);const n=e.session_id||e.data?.session_id;if(!n)return void console.log(`ActivityTree: Skipping event without session_id: ${s}`);if(!this.sessions.has(n))return void console.warn(`ActivityTree: Session ${n} not found in authoritative sessions - skipping event`);const o=this.sessions.get(n);switch(s){case"Start":this.currentSession=o;break;case"user_prompt":this.processUserInstruction(e,o);break;case"TodoWrite":break;case"SubagentStart":this.processSubagentStart(e,o);break;case"SubagentStop":this.processSubagentStop(e,o);break;case"PreToolUse":this.processToolUse(e,o);break;case"PostToolUse":this.updateToolStatus(e,o,"completed")}this.updateStats()}getEventType(e){if(e.hook_event_name)return e.hook_event_name;if("hook"===e.type&&e.subtype){return{pre_tool:"PreToolUse",post_tool:"PostToolUse",subagent_start:"SubagentStart",subagent_stop:"SubagentStop",todo_write:"TodoWrite"}[e.subtype]}if("todo"===e.type&&"updated"===e.subtype)return"TodoWrite";if("subagent"===e.type){if("started"===e.subtype)return"SubagentStart";if("stopped"===e.subtype)return"SubagentStop"}return"start"===e.type?"Start":"user_prompt"===e.type||"user_prompt"===e.subtype?"user_prompt":null}processUserInstruction(e,t){const s=e.prompt_text||e.data?.prompt_text||e.prompt||"";if(!s)return;const n={id:`instruction-${t.id}-${Date.now()}`,text:s,preview:s.length>100?s.substring(0,100)+"...":s,timestamp:e.timestamp||(new Date).toISOString(),type:"user_instruction"};if(t.agents.size>0){console.log("ActivityTree: New user prompt detected, collapsing previous agents");for(let e of t.agents.values())"active"===e.status&&(e.status="completed"),this.expandedAgents.delete(e.id)}t.currentActiveAgent=null,t.userInstructions.push(n),t.userInstructions.length>5&&(t.userInstructions=t.userInstructions.slice(-5))}processTodoWrite(e,t){let s=e.todos||e.data?.todos||e.data||[];if(s&&"object"==typeof s&&s.todos&&(s=s.todos),!Array.isArray(s)||0===s.length)return;t.currentTodos=s.map(t=>({content:t.content,activeForm:t.activeForm,status:t.status,timestamp:e.timestamp}));let n=t.currentActiveAgent;if(!n){const e=this.getAllAgents(t).filter(e=>"active"===e.status||"in_progress"===e.status).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));if(e.length>0)n=e[0];else{const e=this.getAllAgents(t),s=e.find(e=>e.isPM);s?n=s:e.length>0&&(n=e[0])}}if(n){n.todoWritesMap||(n.todoWritesMap=new Map),n.todoWrites||(n.todoWrites=[]);const t=n.todoWritesMap.get("TodoWrite");if(t)t.todos=s,t.timestamp=e.timestamp,t.updateCount=(t.updateCount||1)+1;else{const t={id:`todowrite-${n.id}-${Date.now()}`,name:"TodoWrite",type:"todowrite",icon:"📝",timestamp:e.timestamp,status:"completed",todos:s,params:{todos:s},updateCount:1};n.todoWritesMap.set("TodoWrite",t),n.todoWrites=[t]}n.currentTodos=s}else{t.todoWrites||(t.todoWrites=[]),t.todoWritesMap||(t.todoWritesMap=new Map);const n=t.todoWritesMap.get("TodoWrite");if(n)n.todos=s,n.timestamp=e.timestamp,n.updateCount=(n.updateCount||1)+1;else{const n={id:`todowrite-session-${Date.now()}`,name:"TodoWrite",type:"todowrite",icon:"📝",timestamp:e.timestamp,status:"completed",todos:s,updateCount:1};t.todoWritesMap.set("TodoWrite",n),t.todoWrites=[n]}}}processSubagentStart(e,t){const s=e.agent_name||e.data?.agent_name||e.data?.agent_type||e.agent_type||e.agent||"unknown",n=e.session_id||e.data?.session_id,o=e.parent_agent||e.data?.parent_agent,i=`${s}-${n||"no-session"}`;let a=null;let r;if(a=this.getAllAgents(t).find(e=>e.name===s&&e.sessionId===n&&"active"===e.status),a)r=a,r.timestamp=e.timestamp,r.instanceCount=(r.instanceCount||1)+1,this.expandedAgents.add(r.id);else{if(r={id:`agent-${i}-${Date.now()}`,name:s,type:"agent",icon:this.getAgentIcon(s),timestamp:e.timestamp,status:"active",tools:[],subagents:new Map,sessionId:n,parentAgent:o,isPM:"pm"===s.toLowerCase()||s.toLowerCase().includes("project manager"),instanceCount:1,toolsMap:new Map},o){let e=null;for(let[s,n]of t.agents.entries())if(n.sessionId===o||n.name===o){e=n;break}e?(e.subagents||(e.subagents=new Map),e.subagents.set(r.id,r)):t.agents.set(r.id,r)}else t.agents.set(r.id,r);this.expandedAgents.add(r.id)}t.currentActiveAgent=r}processSubagentStop(e,t){const s=e.session_id||e.data?.session_id;if(s&&t.agents.has(s)){t.agents.get(s).status="completed"}}processToolUse(e,t){const s=e.tool_name||e.data?.tool_name||e.tool||e.data?.tool||"unknown",n=e.tool_parameters||e.data?.tool_parameters||e.parameters||e.data?.parameters||{},o=e.session_id||e.data?.session_id;let i=t.currentActiveAgent;if(!i){const e=this.getAllAgents(t);i=e.find(e=>e.sessionId===o)||e.find(e=>"active"===e.status)||e[0]}if(i){i.toolsMap||(i.toolsMap=new Map),i.tools||(i.tools=[]);const t=this.getToolKey(s,n);let o=i.toolsMap.get(t);if(o)o.params=n,o.timestamp=e.timestamp,o.status="in_progress",o.eventId=e.id,o.callCount=(o.callCount||1)+1,i.currentTool=o;else{const o={id:`tool-${i.id}-${s}-${Date.now()}`,name:s,type:"tool",icon:this.getToolIcon(s),timestamp:e.timestamp,status:"in_progress",params:n,eventId:e.id,callCount:1,createdAt:e.timestamp};"Task"===s&&n.subagent_type&&(o.isSubagentTask=!0,o.subagentType=n.subagent_type),i.toolsMap.set(t,o),"TodoWrite"===s?i.tools.unshift(o):i.tools.push(o),i.currentTool=o}}else{t.tools||(t.tools=[]),t.toolsMap||(t.toolsMap=new Map);const o=this.getToolKey(s,n);let i=t.toolsMap.get(o);if(i)i.params=n,i.timestamp=e.timestamp,i.status="in_progress",i.eventId=e.id,i.callCount=(i.callCount||1)+1,t.currentTool=i;else{const i={id:`tool-session-${s}-${Date.now()}`,name:s,type:"tool",icon:this.getToolIcon(s),timestamp:e.timestamp,status:"in_progress",params:n,eventId:e.id,callCount:1,createdAt:e.timestamp};t.toolsMap.set(o,i),"TodoWrite"===s?t.tools.unshift(i):t.tools.push(i),t.currentTool=i}}}getToolKey(e,t){if("TodoWrite"===e)return"TodoWrite";let s=e;return"Edit"!==e&&"Write"!==e&&"Read"!==e||t.file_path&&(s+=`-${t.file_path}`),"Grep"!==e&&"Glob"!==e||!t.pattern||(s+=`-${t.pattern.substring(0,20)}`),s}updateToolStatus(e,t,s){const n=e.tool_name||e.data?.tool_name||e.tool||"unknown",o=e.tool_parameters||e.data?.tool_parameters||e.parameters||e.data?.parameters||{},i=e.session_id||e.data?.session_id,a=this.getToolKey(n,o);let r=t.currentActiveAgent;if(!r){const e=this.getAllAgents(t);r=e.find(e=>e.sessionId===i)||e.find(e=>"active"===e.status)}if(r&&r.toolsMap){const t=r.toolsMap.get(a);if(t)return t.status=s,t.completedAt=e.timestamp,(e.data?.result||e.result)&&(t.result=e.data?.result||e.result),void(e.data?.duration_ms&&(t.duration=e.data.duration_ms))}if(t.toolsMap){const n=t.toolsMap.get(a);if(n)return n.status=s,n.completedAt=e.timestamp,(e.data?.result||e.result)&&(n.result=e.data?.result||e.result),void(e.data?.duration_ms&&(n.duration=e.data.duration_ms))}console.log(`ActivityTree: Could not find tool to update status for ${n} with key ${a} (event ${e.id})`)}renderTree(){const e=document.getElementById("linear-tree");if(!e)return;e.innerHTML="";const t=Array.from(this.sessions.values()).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));for(let s of t){if("all"!==this.selectedSessionFilter&&this.selectedSessionFilter!==s.id)continue;const t=this.createSessionElement(s);e.appendChild(t)}}createSessionElement(e){const t=this.expandedSessions.has(e.id)||e.expanded;let s;try{const t=e.timestamp instanceof Date?e.timestamp:new Date(e.timestamp);isNaN(t.getTime())?(s="Invalid Date",console.warn("ActivityTree: Invalid session timestamp:",e.timestamp)):s=t.toLocaleString()}catch(l){s="Invalid Date",console.error("ActivityTree: Error formatting session timestamp:",l,e.timestamp)}const n=document.createElement("div");n.className="tree-node session",n.dataset.sessionId=e.id;const o=t?"▼":"▶",i=this.getAllAgents(e).length,a=e.currentTodos?e.currentTodos.length:0,r=e.userInstructions?e.userInstructions.length:0;return console.log(`ActivityTree: Rendering session ${e.id}: ${i} agents, ${r} instructions, ${a} todos at ${s}`),n.innerHTML=`\n <div class="tree-node-content" onclick="window.activityTreeInstance.toggleSession('${e.id}')">\n <span class="tree-expand-icon">${o}</span>\n <span class="tree-icon">🎯</span>\n <span class="tree-label">PM Session</span>\n <span class="tree-meta">${s} • ${i} agent(s) • ${r} instruction(s) • ${a} todo(s)</span>\n </div>\n <div class="tree-children" style="display: ${t?"block":"none"}">\n ${this.renderSessionContent(e)}\n </div>\n `,n}renderSessionContent(e){let t="";if(e.userInstructions&&e.userInstructions.length>0)for(let n of e.userInstructions.slice(-3))t+=this.renderUserInstructionElement(n,1);if(e.tools&&e.tools.length>0)for(let n of e.tools)t+=this.renderToolElement(n,1);const s=Array.from(e.agents.values()).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));for(let n of s)t+=this.renderAgentElement(n,1);return t}renderUserInstructionElement(e,t){return`\n <div class="tree-node user-instruction ${this.selectedItem&&"instruction"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":""}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">💬</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'instruction', event)">User: "${this.escapeHtml(e.preview)}"</span>\n <span class="tree-status status-active">instruction</span>\n </div>\n </div>\n `}renderTodoChecklistElement(e,t){const s=`checklist-${Date.now()}`,n=!1!==this.expandedTools.has(s),o=n?"▼":"▶";let i=0,a=0;e.forEach(e=>{"completed"===e.status?i++:"in_progress"===e.status&&a++});let r="";r=a>0?`${a} in progress, ${i} completed`:i===e.length&&e.length>0?`All ${e.length} completed`:`${e.length} todo(s)`;let l=`\n <div class="tree-node todo-checklist" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">☑️</span>\n <span class="tree-label">TODOs</span>\n <span class="tree-params">${r}</span>\n <span class="tree-status status-active">checklist</span>\n </div>\n `;if(n){l+='<div class="tree-children">';for(let s of e){const e=this.getCheckboxIcon(s.status),n=`status-${s.status}`,o="in_progress"===s.status?s.activeForm:s.content;l+=`\n <div class="tree-node todo-item ${n}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${e}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${s.status.replace("_"," ")}</span>\n </div>\n </div>\n `}l+="</div>"}return l+="</div>",l}renderAgentElement(e,t){const s="active"===e.status?"status-active":"status-completed",n=this.expandedAgents.has(e.id),o=e.tools&&e.tools.length>0,i=e.subagents&&e.subagents.size>0,a=o||i,r=a?n?"▼":"▶":"",l=this.selectedItem&&"agent"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":"",c=e.instanceCount>1?` (${e.instanceCount}x)`:"";let d="";if(!n&&a){const t=[];if(e.currentTodos&&e.currentTodos.length>0){const s=e.currentTodos.find(e=>"in_progress"===e.status);s&&t.push(`📝 ${s.activeForm||s.content}`)}e.currentTool&&t.push(`${e.currentTool.icon} ${e.currentTool.name}`),t.length>0&&(d=` • ${t.join(" • ")}`)}let p=`\n <div class="tree-node agent ${s} ${l}" data-level="${t}">\n <div class="tree-node-content">\n ${r?`<span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleAgent('${e.id}'); event.stopPropagation();">${r}</span>`:'<span class="tree-expand-icon"></span>'}\n <span class="tree-icon">${e.icon}</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'agent', event)">${e.name}${c}${d}</span>\n <span class="tree-status ${s}">${e.status}</span>\n </div>\n `;if(a&&n){if(p+='<div class="tree-children">',o)for(let s of e.tools)p+=this.renderToolElement(s,t+1);if(i){const s=Array.from(e.subagents.values());for(let e of s)p+=this.renderAgentElement(e,t+1)}p+="</div>"}return p+="</div>",p}renderToolElement(e,t){const s=`status-${e.status}`,n=this.getToolParams(e),o=this.selectedItem&&"tool"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":"",i=this.getToolStatusIcon(e.status),a=this.getToolStatusLabel(e.status),r=e.callCount>1?` (${e.callCount} calls)`:"";return`\n <div class="tree-node tool ${s} ${o}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${e.icon}</span>\n <span class="tree-status-icon">${i}</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'tool', event)">${e.name}${r}</span>\n <span class="tree-params">${n}</span>\n <span class="tree-status ${s}">${a}</span>\n </div>\n </div>\n `}getToolParams(e){if(!e.params)return"";if("Read"===e.name&&e.params.file_path)return e.params.file_path;if("Edit"===e.name&&e.params.file_path)return e.params.file_path;if("Write"===e.name&&e.params.file_path)return e.params.file_path;if("Bash"===e.name&&e.params.command){const t=e.params.command;return t.length>50?t.substring(0,50)+"...":t}return"WebFetch"===e.name&&e.params.url?e.params.url:""}getStatusIcon(e){return{pending:"⏸️",in_progress:"🔄",completed:"✅"}[e]||"❓"}getCheckboxIcon(e){return{pending:"⏳",in_progress:"🔄",completed:"✅"}[e]||"❓"}getAgentIcon(e){return{engineer:"👷",research:"🔬",qa:"🧪",ops:"⚙️",pm:"📊",architect:"🏗️","project manager":"📊"}[e.toLowerCase()]||"🤖"}getAllAgents(e){const t=[],s=e=>{if(e)for(let n of e.values())t.push(n),n.subagents&&n.subagents.size>0&&s(n.subagents)};return s(e.agents),t}renderTodoWriteElement(e,t){const s=e.id,n=this.expandedTools.has(s),o=n?"▼":"▶",i=e.todos||[];let a=0,r=0;i.forEach(e=>{"completed"===e.status?a++:"in_progress"===e.status&&r++});const l=i.find(e=>"in_progress"===e.status),c=l?` • 🔄 ${l.activeForm||l.content}`:"";let d="";d=r>0?`${r} in progress, ${a}/${i.length} done`:a===i.length&&i.length>0?`All ${i.length} completed ✅`:`${a}/${i.length} done`;let p=`\n <div class="tree-node todowrite ${l?"has-active":""}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoWrite('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">📝</span>\n <span class="tree-label">TodoWrite${e.updateCount>1?` (${e.updateCount} updates)`:""}${n?"":c}</span>\n <span class="tree-params">${d}</span>\n <span class="tree-status status-active">todos</span>\n </div>\n `;if(n&&i.length>0){p+='<div class="tree-children">';for(let e of i){const s=this.getCheckboxIcon(e.status),n=`status-${e.status}`,o="in_progress"===e.status?e.activeForm:e.content;p+=`\n <div class="tree-node todo-item ${n} ${e===l?"current-active":""}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${s}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${e.status.replace("_"," ")}</span>\n </div>\n </div>\n `}p+="</div>"}return p+="</div>",p}toggleTodoWrite(e){this.expandedTools.has(e)?this.expandedTools.delete(e):this.expandedTools.add(e),this.renderTree()}getToolIcon(e){return{read:"👁️",write:"✍️",edit:"✏️",bash:"💻",webfetch:"🌐",grep:"🔍",glob:"📂",todowrite:"📝"}[e.toLowerCase()]||"🔧"}getToolStatusIcon(e){return{in_progress:"⏳",completed:"✅",failed:"❌",error:"❌",pending:"⏸️",active:"🔄"}[e]||"❓"}getToolStatusLabel(e){return{in_progress:"in progress",completed:"completed",failed:"failed",error:"error",pending:"pending",active:"active"}[e]||e}toggleSession(e){this.expandedSessions.has(e)?this.expandedSessions.delete(e):this.expandedSessions.add(e);const t=this.sessions.get(e);t&&(t.expanded=this.expandedSessions.has(e)),this.renderTree()}expandAllSessions(){for(let e of this.sessions.keys()){this.expandedSessions.add(e);const t=this.sessions.get(e);t&&(t.expanded=!0)}this.renderTree()}collapseAllSessions(){this.expandedSessions.clear();for(let e of this.sessions.values())e.expanded=!1;this.renderTree()}updateStats(){const e=this.countTotalNodes(),t=this.countActiveNodes(),s=this.calculateMaxDepth(),n=document.getElementById("node-count"),o=document.getElementById("active-count"),i=document.getElementById("tree-depth");n&&(n.textContent=e),o&&(o.textContent=t),i&&(i.textContent=s),console.log(`ActivityTree: Stats updated - Nodes: ${e}, Active: ${t}, Depth: ${s}`)}countTotalNodes(){let e=0;for(let t of this.sessions.values()){e+=1,e+=t.agents.size,t.userInstructions&&(e+=t.userInstructions.length),t.todos&&(e+=t.todos.length),t.tools&&(e+=t.tools.length);for(let s of t.agents.values())s.tools&&(e+=s.tools.length)}return e}countActiveNodes(){let e=0;for(let t of this.sessions.values()){if("active"===t.status&&e++,t.todos)for(let s of t.todos)"in_progress"===s.status&&e++;if(t.tools)for(let s of t.tools)"in_progress"===s.status&&e++;for(let s of t.agents.values())if("active"===s.status&&e++,s.tools)for(let t of s.tools)"in_progress"===t.status&&e++}return e}calculateMaxDepth(){let e=0;for(let t of this.sessions.values()){let s=1;t.userInstructions&&t.userInstructions.length>0&&(s=Math.max(s,2)),t.todos&&t.todos.length>0&&(s=Math.max(s,3)),t.tools&&t.tools.length>0&&(s=Math.max(s,2));for(let e of t.agents.values())e.tools&&e.tools.length>0&&(s=Math.max(s,3));e=Math.max(e,s)}return e}toggleAgent(e){this.expandedAgents.has(e)?this.expandedAgents.delete(e):this.expandedAgents.add(e),this.renderTree()}toggleTool(e){console.log("Tool expansion is disabled. Tools now show data in the left pane when clicked.")}toggleTodoChecklist(e){this.expandedTools.has(e)?this.expandedTools.delete(e):this.expandedTools.add(e),this.renderTree()}renderPinnedTodosElement(e,t){const s=`pinned-todos-${Date.now()}`,n=!1!==this.expandedTools.has(s),o=n?"▼":"▶",i=e.todos||[];let a=0,r=0;i.forEach(e=>{"completed"===e.status?a++:"in_progress"===e.status&&r++});let l="";l=r>0?`${r} in progress, ${a} completed`:a===i.length&&i.length>0?`All ${i.length} completed`:`${i.length} todo(s)`;let c=`\n <div class="tree-node pinned-todos" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">📌</span>\n <span class="tree-label">Pinned TODOs</span>\n <span class="tree-params">${l}</span>\n <span class="tree-status status-active">pinned</span>\n </div>\n `;if(n){c+='<div class="tree-children">';for(let e of i){const s=this.getCheckboxIcon(e.status),n=`status-${e.status}`,o="in_progress"===e.status?e.activeForm:e.content;c+=`\n <div class="tree-node todo-item ${n}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${s}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${e.status.replace("_"," ")}</span>\n </div>\n </div>\n `}c+="</div>"}return c+="</div>",c}selectItem(e,t,s){s&&s.stopPropagation(),this.selectedItem={data:e,type:t},this.displayItemData(e,t),this.renderTree()}displayItemData(t,s){this.unifiedViewer||(this.unifiedViewer=new e("module-data-content")),this.unifiedViewer.display(t,s);const n=document.querySelector(".module-data-header h5");if(n){const e={agent:"🤖",tool:"🔧",instruction:"💬",session:"🎯",todo:"📝"}[s]||"📊",o=t.name||t.agentName||t.tool_name||"Item";n.textContent=`${e} ${s}: ${o}`}}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}resetZoom(){this.svg&&this.zoom&&this.svg.transition().duration(this.duration).call(this.zoom.transform,d3.zoomIdentity)}escapeJson(e){return JSON.stringify(e).replace(/'/g,"&apos;").replace(/"/g,"&quot;")}}window.ActivityTree=t;const s=()=>{let e=null;const s=()=>{e||(console.log("Creating new Activity Tree instance..."),e=new t,window.activityTreeInstance=e,window.activityTree=()=>e),setTimeout(()=>{console.log("Attempting to initialize Activity Tree visualization..."),e.initialize()},100)};document.querySelectorAll(".tab-button").forEach(t=>{t.addEventListener("click",t=>{"activity"===t.target.getAttribute("data-tab")&&(console.log("Activity tab button clicked, initializing tree..."),s(),e&&setTimeout(()=>{e.renderWhenVisible(),e.forceShow()},150))})}),document.addEventListener("tabChanged",t=>{t.detail&&"activity"===t.detail.newTab&&(console.log("Tab changed to activity, initializing tree..."),s(),e&&setTimeout(()=>{e.renderWhenVisible(),e.forceShow()},150))});const n=document.querySelector(".tab-button.active");n&&"activity"===n.getAttribute("data-tab")&&(console.log("Activity tab is active on load, initializing tree..."),s());const o=document.getElementById("activity-tab");o&&o.classList.contains("active")&&(console.log("Activity panel is active on load, initializing tree..."),e||s())};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",s):s();
2
- //# sourceMappingURL=activity-tree.js.map
@@ -1,2 +0,0 @@
1
- class e{constructor(e){this.eventViewer=e,this.state={currentDelegation:null,sessionAgents:new Map,eventAgentMap:new Map,pmDelegations:new Map,agentToDelegation:new Map,orphanSubagents:new Map,subagentStartEvents:new Map},console.log("Agent inference system initialized")}initialize(){this.state={currentDelegation:null,sessionAgents:new Map,eventAgentMap:new Map,pmDelegations:new Map,agentToDelegation:new Map,orphanSubagents:new Map,subagentStartEvents:new Map}}inferAgentFromEvent(e){const t=e.data||{},n=e.session_id||t.session_id||"unknown",a=e.hook_event_name||t.hook_event_name||e.type||"",s=e.subtype||t.subtype||"",i=e.tool_name||t.tool_name||"";if(Math.random()<.1&&console.log("Agent inference debug:",{eventType:a,toolName:i,hasData:!!e.data,dataKeys:Object.keys(t),eventKeys:Object.keys(e),agentType:e.agent_type||t.agent_type,subagentType:e.subagent_type||t.subagent_type}),"SubagentStop"===a||"subagent_stop"===s){const i=this.extractAgentNameFromEvent(e);return console.log("SubagentStop event detected:",{agentName:i,sessionId:n,eventType:a,subtype:s,rawAgentType:e.agent_type||t.agent_type}),{type:"subagent",confidence:"definitive",agentName:i,reason:"SubagentStop event"}}if("Stop"===a||"stop"===s)return{type:"main_agent",confidence:"definitive",agentName:"PM",reason:"Stop event"};if("Task"===i){const t=this.extractSubagentTypeFromTask(e);if(t)return console.log("Task delegation detected:",{agentName:t,sessionId:n,eventType:a}),{type:"subagent",confidence:"high",agentName:t,reason:"Task tool with subagent_type"}}if("PreToolUse"===a&&"Task"===i){const t=this.extractSubagentTypeFromTask(e);if(t)return{type:"subagent",confidence:"high",agentName:t,reason:"PreToolUse Task delegation"}}{const e=n.toLowerCase();if(["subagent","task","agent-"].some(t=>e.includes(t)))return{type:"subagent",confidence:"medium",agentName:"Subagent",reason:"Session ID pattern"}}const o=e.agent_type||t.agent_type||e.agent_id||t.agent_id,g=e.subagent_type||t.subagent_type;if(g&&"unknown"!==g)return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(g),reason:"subagent_type field"};if(o&&"unknown"!==o&&"main"!==o)return{type:"subagent",confidence:"medium",agentName:this.normalizeAgentName(o),reason:"agent_type field"};if(t.delegation_details?.agent_type)return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(t.delegation_details.agent_type),reason:"delegation_details"};if(e.type&&e.type.startsWith("hook.")){const a=e.type.replace("hook.","");if("subagent_start"===a||"SubagentStart"===t.hook_event_name){const e=t.agent_type||t.agent_id||"Subagent";return console.log("SubagentStart event from Socket.IO:",{agentName:e,sessionId:n,hookType:a}),{type:"subagent",confidence:"definitive",agentName:this.normalizeAgentName(e),reason:"Socket.IO hook SubagentStart"}}if("subagent_stop"===a||"SubagentStop"===t.hook_event_name){const e=t.agent_type||t.agent_id||"Subagent";return{type:"subagent",confidence:"high",agentName:this.normalizeAgentName(e),reason:"Socket.IO hook SubagentStop"}}}return{type:"main_agent",confidence:"default",agentName:"PM",reason:"default classification"}}normalizeAgentName(e){if(!e)return"Unknown";const t={engineer:"Engineer Agent",research:"Research Agent",qa:"QA Agent",documentation:"Documentation Agent",security:"Security Agent",ops:"Ops Agent",version_control:"Version Control Agent",data_engineer:"Data Engineer Agent",test_integration:"Test Integration Agent",pm:"PM Agent"}[e.toLowerCase()];if(t)return t;let n=e.replace(/_/g," ").split(" ").map(e=>e.charAt(0).toUpperCase()+e.slice(1).toLowerCase()).join(" ");return n.toLowerCase().includes("agent")||(n+=" Agent"),n}extractSubagentTypeFromTask(e){let t=null;return e.tool_parameters?.subagent_type?t=e.tool_parameters.subagent_type:e.data?.tool_parameters?.subagent_type?t=e.data.tool_parameters.subagent_type:e.data?.delegation_details?.agent_type?t=e.data.delegation_details.agent_type:e.tool_input?.subagent_type&&(t=e.tool_input.subagent_type),t?this.normalizeAgentName(t):null}extractAgentNameFromEvent(e){const t=e.data||{};if("Task"===e.tool_name||"Task"===t.tool_name){const t=this.extractSubagentTypeFromTask(e);if(t)return t}return e.subagent_type&&"unknown"!==e.subagent_type?this.normalizeAgentName(e.subagent_type):t.subagent_type&&"unknown"!==t.subagent_type?this.normalizeAgentName(t.subagent_type):t.delegation_details?.agent_type&&"unknown"!==t.delegation_details.agent_type?this.normalizeAgentName(t.delegation_details.agent_type):e.agent_type&&!["main","unknown"].includes(e.agent_type)?this.normalizeAgentName(e.agent_type):t.agent_type&&!["main","unknown"].includes(t.agent_type)?this.normalizeAgentName(t.agent_type):e.agent_id&&!["main","unknown"].includes(e.agent_id)?this.normalizeAgentName(e.agent_id):t.agent_id&&!["main","unknown"].includes(t.agent_id)?this.normalizeAgentName(t.agent_id):e.agent&&"unknown"!==e.agent?this.normalizeAgentName(e.agent):e.name&&"unknown"!==e.name?this.normalizeAgentName(e.name):"Unknown"}processAgentInference(){const e=this.eventViewer.events;this.state.currentDelegation=null,this.state.sessionAgents.clear(),this.state.eventAgentMap.clear(),this.state.pmDelegations.clear(),this.state.agentToDelegation.clear(),this.state.orphanSubagents.clear(),this.state.subagentStartEvents.clear(),console.log("Processing agent inference for",e.length,"events"),e&&0!==e.length?(e.forEach((e,t)=>{let n;try{const a=this.inferAgentFromEvent(e),s=e.session_id||e.data?.session_id||"default";n=a,this.state.currentDelegation&&"default"===a.confidence&&s===this.state.currentDelegation.sessionId&&(n={type:"subagent",confidence:"inherited",agentName:this.state.currentDelegation.agentName,reason:"inherited from delegation context"});const i=e.hook_event_name||e.data?.hook_event_name||"";if(("SubagentStart"===i||"hook.subagent_start"===e.type||"subagent_start"===e.subtype)&&"subagent"===a.type&&(this.state.subagentStartEvents.has(a.agentName)||this.state.subagentStartEvents.set(a.agentName,[]),this.state.subagentStartEvents.get(a.agentName).push({eventIndex:t,event:e,timestamp:e.timestamp,sessionId:s})),"Task"===e.tool_name&&"subagent"===a.type){const n=`pm_${s}_${t}_${a.agentName}`,i={id:n,agentName:a.agentName,sessionId:s,startIndex:t,endIndex:null,pmCall:e,timestamp:e.timestamp,agentEvents:[]};this.state.pmDelegations.set(n,i),this.state.agentToDelegation.set(a.agentName,n),this.state.currentDelegation={agentName:a.agentName,sessionId:s,startIndex:t,endIndex:null,delegationId:n},console.log("Delegation started:",this.state.currentDelegation)}else if("definitive"===a.confidence&&"SubagentStop event"===a.reason&&this.state.currentDelegation){this.state.currentDelegation.endIndex=t;const e=this.state.pmDelegations.get(this.state.currentDelegation.delegationId);e&&(e.endIndex=t),console.log("Delegation ended:",this.state.currentDelegation),this.state.currentDelegation=null}if(this.state.currentDelegation&&"subagent"===n.type){const a=this.state.pmDelegations.get(this.state.currentDelegation.delegationId);a&&a.agentEvents.push({eventIndex:t,event:e,inference:n})}this.state.eventAgentMap.set(t,n),this.state.sessionAgents.set(s,n),t<5&&console.log(`Event ${t} agent inference:`,{event_type:e.type||e.hook_event_name,subtype:e.subtype,tool_name:e.tool_name,inference:n,hasData:!!e.data,agentType:e.agent_type||e.data?.agent_type})}catch(a){console.error(`Error processing event ${t} for agent inference:`,a),n||(n={type:"main_agent",confidence:"error",agentName:"PM",reason:"error during processing"}),this.state.eventAgentMap.set(t,n)}}),this.identifyOrphanSubagents(e),console.log("Agent inference processing complete. Results:",{total_events:e.length,inferred_agents:this.state.eventAgentMap.size,unique_sessions:this.state.sessionAgents.size,pm_delegations:this.state.pmDelegations.size,agent_to_delegation_mappings:this.state.agentToDelegation.size,orphan_subagents:this.state.orphanSubagents.size})):console.log("No events to process for agent inference")}getInferredAgent(e){return this.state.eventAgentMap.get(e)||null}getInferredAgentForEvent(e){const t=this.eventViewer.events;let n=t.indexOf(e);if(-1===n&&e.timestamp&&(n=t.findIndex(t=>t.timestamp===e.timestamp&&t.session_id===e.session_id)),-1===n)return console.log("Agent inference: Could not find event in events array, performing inline inference"),this.inferAgentFromEvent(e);let a=this.getInferredAgent(n);return a||(a=this.inferAgentFromEvent(e),this.state.eventAgentMap.set(n,a)),a}getCurrentDelegation(){return this.state.currentDelegation}getSessionAgents(){return this.state.sessionAgents}getEventAgentMap(){return this.state.eventAgentMap}getPMDelegations(){return this.state.pmDelegations}getAgentToDelegationMap(){return this.state.agentToDelegation}buildDelegationHierarchy(){const e=this.getPMDelegations(),t=this.eventViewer.events,n={mainPM:{type:"pm",name:"PM",delegations:[],ownEvents:[],totalEvents:0},impliedPM:{type:"pm_implied",name:"Implied PM",delegations:[],ownEvents:[],totalEvents:0}};for(const[s,i]of e)n.mainPM.delegations.push({id:s,agentName:i.agentName,taskContext:this.extractTaskContext(i.pmCall),events:i.agentEvents,startTime:i.timestamp,endTime:i.endIndex?t[i.endIndex]?.timestamp:null,status:i.endIndex?"completed":"active"}),n.mainPM.totalEvents+=i.agentEvents.length;t.forEach((e,t)=>{const a=this.getInferredAgent(t);a&&"main_agent"===a.type&&(n.mainPM.ownEvents.push({eventIndex:t,event:e}),n.mainPM.totalEvents++)});const a=new Map;t.forEach((t,n)=>{const s=this.getInferredAgent(n);if(s&&"subagent"===s.type){let i=!0;for(const[t,a]of e)if(a.agentEvents.some(e=>e.eventIndex===n)){i=!1;break}if(i){const e=s.agentName;a.has(e)||a.set(e,[]),a.get(e).push({eventIndex:n,event:t,inference:s})}}});for(const[s,i]of a)n.impliedPM.delegations.push({id:`implied_${s}`,agentName:s,taskContext:"No explicit PM delegation",events:i,startTime:i[0].event.timestamp,endTime:i[i.length-1].event.timestamp,status:"completed"}),n.impliedPM.totalEvents+=i.length;return n}extractTaskContext(e){if(!e)return"Unknown task";const t=e.tool_parameters||e.data?.tool_parameters||{};return t.task||t.request||t.description||"Task delegation"}identifyOrphanSubagents(e){for(const[t,n]of this.state.subagentStartEvents)for(const a of n){const n=a.eventIndex,s=new Date(a.timestamp).getTime();let i=!1;for(let a=Math.max(0,n-20);a<n;a++){const n=e[a];if(!n)continue;const o=s-new Date(n.timestamp).getTime();if("Task"===n.tool_name&&o>=0&&o<1e4){const e=this.state.eventAgentMap.get(a);if(e&&e.agentName===t){i=!0;break}}}i||this.state.orphanSubagents.set(n,{agentName:t,timestamp:a.timestamp,sessionId:a.sessionId,event:a.event,groupingKey:null})}this.groupOrphanSubagents(5e3)}groupOrphanSubagents(e){const t=Array.from(this.state.orphanSubagents.values()).sort((e,t)=>new Date(e.timestamp)-new Date(t.timestamp));let n=null,a=null;for(const s of t){const t=new Date(s.timestamp).getTime();(!n||a&&t-a>e)&&(n=`implied_pm_${s.sessionId}_${t}`),s.groupingKey=n,a=t}}isOrphanSubagent(e){return this.state.orphanSubagents.has(e)}getOrphanContext(e){return this.state.orphanSubagents.get(e)||null}getOrphanGroups(){const e=new Map;for(const t of this.state.orphanSubagents.values()){const n=t.groupingKey;e.has(n)||e.set(n,[]),e.get(n).push(t)}return e}getUniqueAgentInstances(){const e=new Map;for(const[a,s]of this.state.pmDelegations){const t=s.agentName;e.has(t)||e.set(t,{id:`consolidated_${t}`,type:"consolidated_agent",agentName:t,delegations:[],pmCalls:[],allEvents:[],firstTimestamp:s.timestamp,lastTimestamp:s.timestamp,totalEventCount:s.agentEvents.length,delegationCount:1});const n=e.get(t);n.delegations.push({id:a,pmCall:s.pmCall,timestamp:s.timestamp,eventCount:s.agentEvents.length,startIndex:s.startIndex,endIndex:s.endIndex,events:s.agentEvents}),s.pmCall&&n.pmCalls.push(s.pmCall),n.allEvents=n.allEvents.concat(s.agentEvents),new Date(s.timestamp)<new Date(n.firstTimestamp)&&(n.firstTimestamp=s.timestamp),new Date(s.timestamp)>new Date(n.lastTimestamp)&&(n.lastTimestamp=s.timestamp),n.totalEventCount+=s.agentEvents.length,n.delegationCount++}const t=this.eventViewer.events;for(let a=0;a<t.length;a++){const n=this.getInferredAgent(a);n&&"subagent"===n.type&&!e.has(n.agentName)&&e.set(n.agentName,{id:`consolidated_${n.agentName}`,type:"consolidated_agent",agentName:n.agentName,delegations:[{id:`implied_pm_${n.agentName}_${a}`,pmCall:null,timestamp:t[a].timestamp,eventCount:1,startIndex:a,endIndex:null,events:[{eventIndex:a,event:t[a],inference:n}]}],pmCalls:[],allEvents:[{eventIndex:a,event:t[a],inference:n}],firstTimestamp:t[a].timestamp,lastTimestamp:t[a].timestamp,totalEventCount:1,delegationCount:1,isImplied:!0})}const n=Array.from(e.values()).sort((e,t)=>new Date(e.firstTimestamp)-new Date(t.firstTimestamp));return console.log("Consolidated unique agents:",{total_unique_agents:n.length,agents:n.map(e=>({name:e.agentName,delegations:e.delegationCount,totalEvents:e.totalEventCount}))}),n}}export{e as A};
2
- //# sourceMappingURL=agent-inference.js.map
@@ -1,2 +0,0 @@
1
- class t{constructor(){this.container=null,this.svg=null,this.treeData=null,this.root=null,this.treeLayout=null,this.treeGroup=null,this.nodes=new Map,this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.isRadialLayout=!0,this.margin={top:20,right:20,bottom:20,left:20},this.width=960-this.margin.left-this.margin.right,this.height=600-this.margin.top-this.margin.bottom,this.radius=Math.min(this.width,this.height)/2,this.nodeId=0,this.duration=750,this.languageFilter="all",this.searchTerm="",this.tooltip=null,this.initialized=!1,this.analyzing=!1,this.selectedNode=null,this.socket=null,this.autoDiscovered=!1,this.zoom=null,this.activeNode=null,this.loadingNodes=new Set,this.bulkLoadMode=!1,this.expandedPaths=new Set}initialize(){if(this.initialized)return;if(this.container=document.getElementById("code-tree-container"),!this.container)return void console.error("Code tree container not found");const t=document.getElementById("code-tab");if(!t)return void console.error("Code tab panel not found");const e=this.getWorkingDirectory();if(!e||"Loading..."===e||"Not selected"===e)return this.showNoWorkingDirectoryMessage(),void(this.initialized=!0);this.setupControls(),this.initializeTreeData(),this.subscribeToEvents();document.getElementById("breadcrumb-content")&&!this.analyzing&&this.updateActivityTicker("Loading project structure...","info"),t.classList.contains("active")&&(this.createVisualization(),this.root&&this.svg&&this.update(this.root),this.autoDiscoverRootLevel()),this.initialized=!0}renderWhenVisible(){const t=this.getWorkingDirectory();t&&"Loading..."!==t&&"Not selected"!==t?(this.removeNoWorkingDirectoryMessage(),this.initialized?(this.svg?this.root&&this.svg&&this.update(this.root):(this.createVisualization(),this.svg&&this.treeGroup&&this.update(this.root)),this.autoDiscovered||this.autoDiscoverRootLevel()):this.initialize()):this.showNoWorkingDirectoryMessage()}setupControls(){const t=document.getElementById("language-filter");t&&t.addEventListener("change",t=>{this.languageFilter=t.target.value,this.filterTree()});const e=document.getElementById("code-search");e&&e.addEventListener("input",t=>{this.searchTerm=t.target.value.toLowerCase(),this.filterTree()});const i=document.getElementById("code-expand-all");i&&i.addEventListener("click",()=>this.expandAll());const o=document.getElementById("code-collapse-all");o&&o.addEventListener("click",()=>this.collapseAll());const s=document.getElementById("code-reset-zoom");s&&s.addEventListener("click",()=>this.resetZoom());const a=document.getElementById("code-toggle-legend");a&&a.addEventListener("click",()=>this.toggleLegend()),document.addEventListener("workingDirectoryChanged",t=>{this.onWorkingDirectoryChanged(t.detail.directory)})}onWorkingDirectoryChanged(t){if(!t||"Loading..."===t||"Not selected"===t)return this.showNoWorkingDirectoryMessage(),this.autoDiscovered=!1,this.analyzing=!1,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},void this.updateStats();this.removeNoWorkingDirectoryMessage(),this.autoDiscovered=!1,this.analyzing=!1,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.initializeTreeData(),this.svg&&this.update(this.root);const e=document.getElementById("code-tab");e&&e.classList.contains("active")&&this.autoDiscoverRootLevel(),this.updateStats()}showLoading(){let t=document.getElementById("code-tree-loading");if(!t){const e=document.getElementById("code-tree-container");e&&(t=document.createElement("div"),t.id="code-tree-loading",t.innerHTML='\n <div class="code-tree-spinner"></div>\n <div class="code-tree-loading-text">Analyzing code structure...</div>\n ',e.appendChild(t))}t&&t.classList.remove("hidden")}hideLoading(){const t=document.getElementById("code-tree-loading");t&&t.classList.add("hidden")}createVisualization(){if("undefined"==typeof d3)return void console.error("D3.js is not loaded");const t=d3.select("#code-tree-container");if(t.selectAll("*").remove(),this.addTreeControls(),this.addBreadcrumb(),!t||!t.node())return void console.error("Code tree container not found");const e=t.node(),i=e.clientWidth||960,o=e.clientHeight||600;this.width=i-this.margin.left-this.margin.right,this.height=o-this.margin.top-this.margin.bottom,this.radius=Math.min(this.width,this.height)/2,this.svg=t.append("svg").attr("width",i).attr("height",o);const s=i/2,a=o/2;this.isRadialLayout?this.treeGroup=this.svg.append("g").attr("transform",`translate(${s},${a})`):this.treeGroup=this.svg.append("g").attr("transform",`translate(${this.margin.left+100},${a})`),this.isRadialLayout?this.treeLayout=d3.cluster().size([2*Math.PI,this.radius-100]).separation((t,e)=>{if(t.parent==e.parent){const e=Math.max(1,4-t.depth),i=t.parent&&t.parent.children?.length||1,o=i>5?2:i>3?1.5:1,s=1+.2*t.depth;return e*o/(t.depth||1)*s}return 4/(t.depth||1)}):this.treeLayout=d3.tree().nodeSize([30,200]).separation((t,e)=>t.parent==e.parent?1:1.5),this.zoom=null,console.log("[CodeTree] All zoom and pan behavior disabled - tree is now completely stationary"),this.addVisualizationControls(),this.tooltip=d3.select("body").append("div").attr("class","code-tree-tooltip").style("opacity",0).style("position","absolute").style("background","rgba(0, 0, 0, 0.8)").style("color","white").style("padding","8px").style("border-radius","4px").style("font-size","12px").style("pointer-events","none")}clearD3Visualization(){this.treeGroup&&(this.treeGroup.selectAll("g.node").remove(),this.treeGroup.selectAll("path.link").remove()),this.nodeId=0}initializeTreeData(){const t=this.getWorkingDirectory(),e=t&&t.split("/").pop()||"Project Root";this.treeData={name:e,path:".",type:"root",children:[],loaded:!1,expanded:!0},"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0)}subscribeToEvents(){this.socket||(window.socket?(this.socket=window.socket,this.setupEventHandlers()):window.dashboard?.socketClient?.socket?(this.socket=window.dashboard.socketClient.socket,this.setupEventHandlers()):window.socketClient?.socket&&(this.socket=window.socketClient.socket,this.setupEventHandlers()))}autoDiscoverRootLevel(){if(this.autoDiscovered||this.analyzing)return;this.updateActivityTicker("🔍 Discovering project structure...","info");const t=this.getWorkingDirectory();if(!t||"Loading..."===t||"Not selected"===t)return console.warn("Cannot auto-discover: no working directory set"),void this.showNoWorkingDirectoryMessage();if(!t.startsWith("/")&&!t.match(/^[A-Z]:\\/))return console.error("Working directory is not absolute:",t),void this.showNotification("Invalid working directory path","error");this.autoDiscovered=!0,this.analyzing=!0,this.nodes.clear(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.socket&&!this.socket.hasListeners("code:node:found")&&this.setupEventHandlers();const e=t.split("/").pop()||"Project Root";this.treeData={name:e,path:".",type:"root",children:[],loaded:!1,expanded:!0},"undefined"!=typeof d3&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0),this.showLoading(),this.updateBreadcrumb(`Discovering structure in ${e}...`,"info");const i=[];document.querySelectorAll(".language-checkbox:checked").forEach(t=>{i.push(t.value)});const o=document.getElementById("ignore-patterns")?.value||"",s={path:t,depth:"top_level",languages:i,ignore_patterns:o,request_id:`discover_${Date.now()}`};this.socket&&this.socket.emit("code:discover:top_level",s),this.updateStats()}analyzeCode(){this.analyzing||this.autoDiscoverRootLevel()}cancelAnalysis(){this.analyzing=!1,this.hideLoading(),this.socket&&this.socket.emit("code:analysis:cancel")}addTreeControls(){const t=d3.select("#code-tree-container");t.select(".tree-controls-toolbar").remove();const e=t.append("div").attr("class","tree-controls-toolbar");e.append("button").attr("class","tree-control-btn").attr("title","Expand all loaded directories").text("⊞").on("click",()=>this.expandAll()),e.append("button").attr("class","tree-control-btn").attr("title","Collapse all directories").text("⊟").on("click",()=>this.collapseAll()),e.append("button").attr("class","tree-control-btn").attr("id","bulk-load-toggle").attr("title","Toggle bulk loading (load 2 levels at once)").text("↕").on("click",()=>this.toggleBulkLoad()),e.append("button").attr("class","tree-control-btn").attr("title","Toggle between radial and linear layouts").text("◎").on("click",()=>this.toggleLayout()),e.append("input").attr("class","tree-control-btn").attr("type","text").attr("placeholder","Search...").attr("title","Search for files and directories").style("width","120px").style("text-align","left").on("input",t=>this.searchTree(t.target.value)).on("keydown",t=>{"Escape"===t.key&&(t.target.value="",this.searchTree(""))})}addBreadcrumb(){const t=d3.select("#code-tree-container");t.select(".tree-breadcrumb").remove();t.append("div").attr("class","tree-breadcrumb").append("div").attr("class","breadcrumb-path").attr("id","tree-breadcrumb-path"),this.updateBreadcrumbPath("/")}updateBreadcrumbPath(t){const e=d3.select("#tree-breadcrumb-path");e.selectAll("*").remove();const i=this.getWorkingDirectory();if(!i||"Loading..."===i||"Not selected"===i)return void e.text("No project selected");const o="/"===t?[i.split("/").pop()||"Root"]:t.split("/").filter(t=>t.length>0);o.forEach((t,i)=>{i>0&&e.append("span").attr("class","breadcrumb-separator").text("/"),e.append("span").attr("class",i===o.length-1?"breadcrumb-segment current":"breadcrumb-segment").text(t).on("click",()=>{if(i<o.length-1){const t=o.slice(0,i+1).join("/");this.navigateToPath(t)}})})}expandAll(){if(!this.root)return;const t=e=>{"directory"===e.data.type&&!0===e.data.loaded&&e._children&&(e.children=e._children,e._children=null,e.data.expanded=!0),e.children&&e.children.forEach(t)};t(this.root),this.update(this.root),this.showNotification("Expanded all loaded directories","success")}collapseAll(){if(!this.root)return;const t=e=>{"directory"===e.data.type&&e.children&&(e._children=e.children,e.children=null,e.data.expanded=!1),e._children&&e._children.forEach(t)};t(this.root),this.update(this.root),this.showNotification("Collapsed all directories","info")}toggleBulkLoad(){this.bulkLoadMode=!this.bulkLoadMode;const t=d3.select("#bulk-load-toggle");this.bulkLoadMode?(t.classed("active",!0),this.showNotification("Bulk load enabled - will load 2 levels deep","info")):(t.classed("active",!1),this.showNotification("Bulk load disabled - load 1 level at a time","info"))}navigateToPath(t){this.updateBreadcrumbPath(t),this.showNotification(`Navigating to: ${t}`,"info")}searchTree(t){if(!this.root||!this.treeGroup)return;const e=t.toLowerCase().trim();if(this.treeGroup.selectAll(".code-node").classed("search-match",!1),!e)return;const i=[],o=t=>{const s=(t.data.name||"").toLowerCase(),a=(t.data.path||"").toLowerCase();(s.includes(e)||a.includes(e))&&i.push(t),t.children&&t.children.forEach(o),t._children&&t._children.forEach(o)};o(this.root),i.length>0?(this.treeGroup.selectAll(".code-node").data(),i.forEach(t=>{this.treeGroup.selectAll(".code-node").filter(e=>e.data.path===t.data.path).classed("search-match",!0),this.expandPathToNode(t)}),this.showNotification(`Found ${i.length} matches`,"success")):this.showNotification("No matches found","info")}expandPathToNode(t){const e=[];let i=t.parent;for(;i&&i!==this.root;)e.unshift(i),i=i.parent;e.forEach(t=>{"directory"===t.data.type&&t._children&&(t.children=t._children,t._children=null,t.data.expanded=!0)}),e.length>0&&this.update(this.root)}createEventsDisplay(){let t=document.getElementById("analysis-events");if(!t){const e=document.getElementById("code-tree-container");e&&(t=document.createElement("div"),t.id="analysis-events",t.className="analysis-events",t.style.display="none",e.appendChild(t))}}clearEventsDisplay(){const t=document.getElementById("analysis-events");t&&(t.innerHTML="",t.style.display="block")}addEventToDisplay(t,e="info"){const i=document.getElementById("analysis-events");if(i){const o=document.createElement("div");o.className="analysis-event",o.style.borderLeftColor="warning"===e?"#f59e0b":"error"===e?"#ef4444":"#3b82f6";const s=(new Date).toLocaleTimeString();o.innerHTML=`<span style="color: #718096;">[${s}]</span> ${t}`,i.appendChild(o),i.scrollTop=i.scrollHeight}}setupEventHandlers(){this.socket&&(this.socket.on("code:analysis:accepted",t=>this.onAnalysisAccepted(t)),this.socket.on("code:analysis:queued",t=>this.onAnalysisQueued(t)),this.socket.on("code:analysis:start",t=>this.onAnalysisStart(t)),this.socket.on("code:analysis:complete",t=>this.onAnalysisComplete(t)),this.socket.on("code:analysis:cancelled",t=>this.onAnalysisCancelled(t)),this.socket.on("code:analysis:error",t=>this.onAnalysisError(t)),this.socket.on("code:top_level:discovered",t=>this.onTopLevelDiscovered(t)),this.socket.on("code:directory:discovered",t=>this.onDirectoryDiscovered(t)),this.socket.on("code:file:discovered",t=>this.onFileDiscovered(t)),this.socket.on("code:file:analyzed",t=>this.onFileAnalyzed(t)),this.socket.on("code:node:found",t=>this.onNodeFound(t)),this.socket.on("code:analysis:progress",t=>this.onProgressUpdate(t)),this.socket.on("code:directory:contents",t=>{if(t.path){let e=t.path;const i=this.getWorkingDirectory();i&&e.startsWith(i)&&(e=e.substring(i.length).replace(/^\//,""),e||(e="."));const o=this.findNodeByPath(e);if(o&&t.children){const i=this.findD3NodeByPath(e);if(i&&this.loadingNodes.has(e)&&(this.removeLoadingPulse(i),this.loadingNodes.delete(e),console.log("🎯 [SUBDIRECTORY LOADING] Successfully completed and removed from loading set:",e)),o.children=t.children.map(t=>{let i;if("."===e||""===e)i=t.name||t.path;else{const o=t.name||t.path;i=`${e}/${o}`}return{...t,path:i,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:[]}}),o.loaded=!0,o.expanded=!0,this.root&&this.svg){const t=this.root;this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.preserveExpansionState(t,this.root);const i=this.findD3NodeByPath(e);i&&(i.children=i._children||i.children,i._children=null,i.data.expanded=!0),this.update(this.root)}t.stats&&(this.stats.files+=t.stats.files||0,this.stats.directories+=t.stats.directories||0,this.updateStats()),this.updateBreadcrumb(`Loaded ${t.path}`,"success"),this.hideLoading()}}}),this.socket.on("code:top_level:discovered",t=>{t.items&&Array.isArray(t.items)&&(this.treeData.children=t.items.map(t=>({name:t.name,path:t.path,type:t.type,language:"file"===t.type?this.detectLanguage(t.path):void 0,size:t.size,lines:t.lines,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:[]})),this.treeData.loaded=!0,t.stats&&(this.stats={...this.stats,...t.stats},this.updateStats()),"undefined"!=typeof d3&&(this.clearD3Visualization(),this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.svg&&this.update(this.root)),this.analyzing=!1,this.hideLoading(),this.updateBreadcrumb(`Discovered ${t.items.length} root items`,"success"),this.showNotification(`Found ${t.items.length} items in project root`,"success"))}))}onAnalysisStart(t){this.analyzing=!0;const e=t.message||"Starting code analysis...";this.updateActivityTicker("🚀 Starting analysis...","info"),this.updateBreadcrumb(e,"info"),this.addEventToDisplay(`🚀 ${e}`,"info"),this.treeData&&0!==this.treeData.children.length||this.initializeTreeData(),this.stats={files:0,classes:0,functions:0,methods:0,lines:0},this.updateStats()}onTopLevelDiscovered(t){this.updateActivityTicker(`📁 Discovered ${(t.items||[]).length} top-level items`,"success"),this.addEventToDisplay(`📁 Found ${(t.items||[]).length} top-level items in project root`,"info");const e=this.findNodeByPath(".");console.log('🔎 Looking for root node with path ".", found:',e?{name:e.name,path:e.path,currentChildren:e.children?e.children.length:0}:"NOT FOUND"),e&&t.items?(console.log("🌳 Populating root node with children"),e.children=t.items.map(t=>{const e=t.name;return console.log(` Adding child: ${t.name} with path: ${e}`),{name:t.name,path:e,type:t.type,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:"directory"===t.type?[]:void 0,size:t.size,has_code:t.has_code}}),e.loaded=!0,e.expanded=!0,this.root&&this.svg&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.update(this.root)),this.hideLoading(),this.updateBreadcrumb(`Discovered ${t.items.length} items`,"success"),this.showNotification(`Found ${t.items.length} top-level items`,"success")):(console.error("❌ Could not find root node to populate"),this.showNotification("Failed to populate root directory","error")),this.analyzing=!1}onDirectoryDiscovered(t){this.updateActivityTicker(`📁 Discovered: ${t.name||"directory"}`),this.addEventToDisplay(`📁 Found ${(t.children||[]).length} items in: ${t.name||t.path}`,"info"),console.log("✅ [SUBDIRECTORY LOADING] Received directory discovery response:",{path:t.path,name:t.name,childrenCount:(t.children||[]).length,children:(t.children||[]).map(t=>({name:t.name,type:t.type})),workingDir:this.getWorkingDirectory(),fullEventData:t});let e=t.path;const i=this.getWorkingDirectory();i&&e.startsWith(i)&&(e=e.substring(i.length).replace(/^\//,""),e||(e=".")),console.log("🔎 Searching for node with path:",e);const o=this.findNodeByPath(e);if(o&&t.children){o.children=t.children.map(t=>{let i;if("."===e||""===e)i=t.name||t.path;else{const o=t.name||t.path;i=`${e}/${o}`}return{name:t.name,path:i,type:t.type,loaded:"directory"!==t.type&&void 0,analyzed:"file"!==t.type&&void 0,expanded:!1,children:"directory"===t.type?[]:void 0,size:t.size,has_code:t.has_code}}),o.loaded=!0,o.expanded=!0;const i=this.findD3NodeByPath(e);if(i&&this.loadingNodes.has(e)&&(this.removeLoadingPulse(i),this.loadingNodes.delete(e),console.log("🎯 [SUBDIRECTORY LOADING] Successfully completed and removed from loading set (hierarchy update):",e)),this.root&&this.svg){const t=this.root;this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,this.preserveExpansionState(t,this.root);const i=this.findD3NodeByPath(e);i&&i.data.children&&i.data.children.length>0&&(i.children=i._children||i.children,i._children=null,i.data.expanded=!0),this.update(this.root)}0===o.children.length?(this.updateBreadcrumb(`Empty directory: ${o.name}`,"info"),this.showNotification(`Directory "${o.name}" is empty`,"info")):(this.updateBreadcrumb(`Loaded ${o.children.length} items from ${o.name}`,"success"),this.showNotification(`Loaded ${o.children.length} items from "${o.name}"`,"success")),this.updateStats()}else if(o){if(o&&!t.children){console.warn("⚠️ [SUBDIRECTORY LOADING] Directory response has no children:",{path:t.path,searchPath:e,nodeExists:!!o,dataKeys:Object.keys(t),fullData:t});const i=t.path?t.path.split("/").filter(t=>t):[];if(1===i.length||t.forceAdd){const e={name:t.name||i[i.length-1]||"Unknown",path:t.path,type:"directory",children:[],loaded:!1,expanded:!1,stats:t.stats||{}};this.addNodeToTree(e,t.parent||""),this.updateBreadcrumb(`Discovered: ${t.path}`,"info")}}}else console.error("❌ [SUBDIRECTORY LOADING] Node not found for path:",{searchPath:e,originalPath:t.path,workingDir:this.getWorkingDirectory(),allTreePaths:this.getAllTreePaths(this.treeData)}),this.showNotification(`Could not find directory "${e}" in tree`,"error"),this.logAllPaths(this.treeData)}onFileDiscovered(t){const e=t.name||(t.path?t.path.split("/").pop():"file");this.updateActivityTicker(`📄 Found: ${e}`),this.addEventToDisplay(`📄 Discovered: ${t.path||"Unknown file"}`,"info");const i=t.path?t.path.split("/").filter(t=>t):[],o=i.slice(0,-1).join("/"),s={name:t.name||i[i.length-1]||"Unknown",path:t.path,type:"file",language:t.language||this.detectLanguage(t.path),size:t.size||0,lines:t.lines||0,children:[],analyzed:!1};this.addNodeToTree(s,o),this.stats.files++,this.updateStats(),this.updateBreadcrumb(`Found: ${t.path}`,"info")}onFileAnalyzed(t){const e=this.findD3NodeByPath(t.path);if(e&&this.loadingNodes.has(t.path)&&(this.removeLoadingPulse(e),this.loadingNodes.delete(t.path)),t.path){const e=t.path.split("/").pop();this.updateActivityTicker(`🔍 Analyzed: ${e}`)}const i=this.findNodeByPath(t.path);i&&(i.analyzed=!0,i.complexity=t.complexity||0,i.lines=t.lines||0,t.elements&&Array.isArray(t.elements)&&(i.children=t.elements.map(e=>({name:e.name,type:e.type.toLowerCase(),path:`${t.path}#${e.name}`,line:e.line,complexity:e.complexity||1,docstring:e.docstring||"",children:e.methods?e.methods.map(i=>({name:i.name,type:"method",path:`${t.path}#${e.name}.${i.name}`,line:i.line,complexity:i.complexity||1,docstring:i.docstring||""})):[]}))),t.stats&&(this.stats.classes+=t.stats.classes||0,this.stats.functions+=t.stats.functions||0,this.stats.methods+=t.stats.methods||0,this.stats.lines+=t.stats.lines||0),this.updateStats(),this.root&&this.update(this.root),this.updateBreadcrumb(`Analyzed: ${t.path}`,"success"))}onNodeFound(t){const e="class"===t.type?"🏛️":"function"===t.type?"⚡":"method"===t.type?"🔧":"📦";this.addEventToDisplay(`${e} Found ${t.type||"node"}: ${t.name||"Unknown"}`);const i={name:t.name||"Unknown",type:(t.type||"unknown").toLowerCase(),path:t.path||"",line:t.line||0,complexity:t.complexity||1,docstring:t.docstring||""};i.type={class:"class",function:"function",method:"method",module:"module",file:"file",directory:"directory"}[i.type]||i.type;let o="";if(t.parent_path)o=t.parent_path;else if(t.file_path)o=t.file_path;else if(i.path.includes("/")){const t=i.path.split("/");t.pop(),o=t.join("/")}switch(i.type){case"class":this.stats.classes++;break;case"function":this.stats.functions++;break;case"method":this.stats.methods++;break;case"file":this.stats.files++}this.addNodeToTree(i,o),this.updateStats();const s=i.type.charAt(0).toUpperCase()+i.type.slice(1);this.updateBreadcrumb(`Found ${s}: ${i.name}`,"info")}onProgressUpdate(t){const e=t.progress||0,i=t.message||`Processing... ${e}%`;this.updateBreadcrumb(i,"info");const o=document.querySelector(".code-tree-progress");o&&(o.style.width=`${e}%`)}onAnalysisComplete(t){this.analyzing=!1,this.hideLoading(),this.updateActivityTicker("✅ Ready","success"),this.addEventToDisplay("✅ Analysis complete!","success"),this.root&&this.svg&&this.update(this.root),t.stats&&(this.stats={...this.stats,...t.stats},this.updateStats());const e=t.message||`Analysis complete: ${this.stats.files} files, ${this.stats.classes} classes, ${this.stats.functions} functions`;this.updateBreadcrumb(e,"success"),this.showNotification(e,"success")}onAnalysisError(t){this.analyzing=!1,this.hideLoading();const e=t.message||t.error||"Analysis failed";this.updateBreadcrumb(e,"error"),this.showNotification(e,"error")}onAnalysisAccepted(t){const e=t.message||"Analysis request accepted";this.updateBreadcrumb(e,"info")}onAnalysisQueued(t){const e=`Analysis queued (position ${t.position||0})`;this.updateBreadcrumb(e,"warning"),this.showNotification(e,"info")}onInfoEvent(t){t.type&&t.type.startsWith("discovery.")?"discovery.start"===t.type?this.updateBreadcrumb(t.message,"info"):"discovery.complete"===t.type?(this.updateBreadcrumb(t.message,"success"),t.stats):"discovery.directory"!==t.type&&"discovery.file"!==t.type||this.updateBreadcrumb(t.message,"info"):t.type&&t.type.startsWith("analysis.")?"analysis.start"===t.type?this.updateBreadcrumb(t.message,"info"):"analysis.complete"===t.type?(this.updateBreadcrumb(t.message,"success"),t.stats&&(t.stats.classes,t.stats.functions,t.stats.methods)):("analysis.class"===t.type||"analysis.function"===t.type||"analysis.method"===t.type||"analysis.parse"===t.type)&&this.updateBreadcrumb(t.message,"info"):t.type&&t.type.startsWith("filter.")?(window.debugMode||this.showFilterEvents)&&(console.debug("[FILTER]",t.type,t.path,t.reason),this.showFilterEvents&&this.updateBreadcrumb(t.message,"warning")):t.type&&t.type.startsWith("cache.")&&("cache.hit"===t.type?(console.debug("[CACHE HIT]",t.file),this.showCacheEvents&&this.updateBreadcrumb(t.message,"info")):"cache.miss"===t.type&&console.debug("[CACHE MISS]",t.file)),this.eventLogEnabled&&t.message&&this.addEventToDisplay(t)}addEventToDisplay(t){this.recentEvents||(this.recentEvents=[]),this.recentEvents.unshift({timestamp:t.timestamp||(new Date).toISOString(),type:t.type,message:t.message,data:t}),this.recentEvents.length>100&&this.recentEvents.pop()}onAnalysisCancelled(t){this.analyzing=!1,this.hideLoading();const e=t.message||"Analysis cancelled";this.updateBreadcrumb(e,"warning")}showNotification(t,e="info"){const i=document.createElement("div");i.className=`code-tree-notification ${e}`,i.textContent=t;const o=document.getElementById("code-tree-container");o&&(i.style.position="absolute",i.style.top="10px",i.style.right="10px",i.style.zIndex="1000",o.style.position&&"static"!==o.style.position||(o.style.position="relative"),o.appendChild(i),setTimeout(()=>{i.style.animation="slideOutRight 0.3s ease",setTimeout(()=>i.remove(),300)},3e3))}addNodeToTree(t,e=""){if(t.path&&t.path.startsWith("/"))return void console.error("Absolute path detected in node, skipping:",t.path);if(e&&e.startsWith("/"))return void console.error("Absolute path detected in parent, skipping:",e);let i=this.treeData;if(e&&(i=this.findNodeByPath(e),!i))return console.warn("Parent node not found, skipping node creation:",e),void console.warn("Attempted to add node:",t);const o=i.children?.find(e=>e.path===t.path||e.name===t.name&&e.type===t.type);o?Object.assign(o,t):(i.children||(i.children=[]),t.children||(t.children=[]),i.children.push(t),this.nodes.set(t.path,t),this.root&&this.svg&&(this.root=d3.hierarchy(this.treeData),this.root.x0=this.height/2,this.root.y0=0,(this.nodes.size<1e3||this.nodes.size%100==0)&&this.update(this.root)))}findNodeByPath(t,e=null){if(e||(e=this.treeData,console.log("🔍 [SUBDIRECTORY LOADING] Starting search for path:",t)),e.path===t)return console.log("✅ [SUBDIRECTORY LOADING] Found node for path:",t),e;if(e.children)for(const i of e.children){const e=this.findNodeByPath(t,i);if(e)return e}return e.parent||e!==this.treeData||console.warn("❌ [SUBDIRECTORY LOADING] Path not found in tree:",t),null}logAllPaths(t,e=""){if(console.log(`${e}${t.path} (${t.name})`),t.children)for(const i of t.children)this.logAllPaths(i,e+" ")}getAllTreePaths(t){const e=[t.path];if(t.children)for(const i of t.children)e.push(...this.getAllTreePaths(i));return e}findD3NodeByPath(t){return this.root?this.root.descendants().find(e=>e.data.path===t):null}preserveExpansionState(t,e){if(!t||!e)return;const i=new Map;t.descendants().forEach(t=>{(t.data.expanded||t.children&&!t._children)&&i.set(t.data.path,!0)}),e.descendants().forEach(t=>{i.has(t.data.path)&&(t.children=t._children||t.children,t._children=null,t.data.expanded=!0)})}updateStats(){const t={"file-count":this.stats.files,"class-count":this.stats.classes,"function-count":this.stats.functions,"line-count":this.stats.lines};for(const[i,o]of Object.entries(t)){const t=document.getElementById(i);t&&(t.textContent=o.toLocaleString())}const e=document.getElementById("code-progress-text");if(e){const t=this.analyzing?`Analyzing... ${this.stats.files} files processed`:`Ready - ${this.stats.files} files in tree`;e.textContent=t}}updateBreadcrumb(t,e="info"){const i=document.getElementById("breadcrumb-content");i&&(i.textContent=t,i.className=`breadcrumb-${e}`)}detectLanguage(t){return{py:"python",js:"javascript",ts:"typescript",jsx:"javascript",tsx:"typescript",java:"java",cpp:"cpp",c:"c",cs:"csharp",rb:"ruby",go:"go",rs:"rust",php:"php",swift:"swift",kt:"kotlin",scala:"scala",r:"r",sh:"bash",ps1:"powershell"}[t.split(".").pop().toLowerCase()]||"unknown"}addVisualizationControls(){const t=this.svg.append("g").attr("class","viz-controls").attr("transform","translate(10, 10)").append("g").attr("class","layout-toggle").style("cursor","pointer").on("click",()=>this.toggleLayout());t.append("rect").attr("width",120).attr("height",30).attr("rx",5).attr("fill","#3b82f6").attr("opacity",.8),t.append("text").attr("x",60).attr("y",20).attr("text-anchor","middle").attr("fill","white").style("font-size","12px").text(this.isRadialLayout?"Switch to Linear":"Switch to Radial")}toggleLayout(){this.isRadialLayout=!this.isRadialLayout,this.createVisualization(),this.root&&this.update(this.root),this.showNotification(this.isRadialLayout?"Switched to radial layout":"Switched to linear layout","info")}radialPoint(t,e){return[(e=+e)*Math.cos(t-=Math.PI/2),e*Math.sin(t)]}update(t){if(!this.treeLayout||!this.treeGroup||!t)return;const e=this.treeLayout(this.root),i=e.descendants(),o=e.descendants().slice(1);this.isRadialLayout&&i.forEach(t=>{void 0===t.x0&&(t.x0=t.x,t.y0=t.y)});const s=this.treeGroup.selectAll("g.node").data(i,t=>t.id||(t.id=++this.nodeId)),a=s.enter().append("g").attr("class",t=>{let e=["node","code-node"];return"directory"===t.data.type?(e.push("directory"),!0===t.data.loaded&&t.children&&e.push("expanded"),"loading"===t.data.loaded&&e.push("loading"),t.data.children&&0===t.data.children.length&&e.push("empty")):"file"===t.data.type&&e.push("file"),e.join(" ")}).attr("transform",e=>{if(this.isRadialLayout){const[e,i]=this.radialPoint(t.x0||0,t.y0||0);return`translate(${e},${i})`}return`translate(${t.y0},${t.x0})`}).on("click",(t,e)=>this.onNodeClick(t,e));a.append("circle").attr("class","node-circle").attr("r",1e-6).style("fill",t=>this.getNodeColor(t)).style("stroke",t=>this.getNodeStrokeColor(t)).style("stroke-width",t=>"directory"===t.data.type?2:1.5).style("cursor","pointer").on("click",(t,e)=>this.onNodeClick(t,e)).on("mouseover",(t,e)=>this.showTooltip(t,e)).on("mouseout",()=>this.hideTooltip()),a.filter(t=>"directory"===t.data.type).append("text").attr("class","expand-icon").attr("x",0).attr("y",0).attr("text-anchor","middle").attr("dominant-baseline","central").text(t=>"loading"===t.data.loaded?"⟳":!0===t.data.loaded&&t.children?"▼":"▶").style("font-size","10px").style("pointer-events","none"),a.append("text").attr("class","node-label").attr("dy",".35em").attr("x",t=>this.isRadialLayout?0:t.children||t._children?-13:13).attr("text-anchor",t=>this.isRadialLayout?"start":t.children||t._children?"end":"start").text(t=>{const e=t.data.name||"";return e.length>20?e.substring(0,17)+"...":e}).style("fill-opacity",1e-6).style("font-size","12px").style("font-family",'-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif').style("text-shadow","1px 1px 2px rgba(255,255,255,0.8), -1px -1px 2px rgba(255,255,255,0.8)").on("click",(t,e)=>this.onNodeClick(t,e)).style("cursor","pointer"),a.filter(t=>"directory"!==t.data.type).append("text").attr("class","node-icon").attr("dy",".35em").attr("x",0).attr("text-anchor","middle").text(t=>this.getNodeIcon(t)).style("font-size","10px").style("fill","white").on("click",(t,e)=>this.onNodeClick(t,e)).style("cursor","pointer"),a.filter(t=>"directory"===t.data.type&&t.data.children).append("text").attr("class","item-count-badge").attr("x",12).attr("y",-8).attr("text-anchor","middle").text(t=>{const e=t.data.children?t.data.children.length:0;return e>0?e:""}).style("font-size","9px").style("opacity",.7).on("click",(t,e)=>this.onNodeClick(t,e)).style("cursor","pointer");const n=a.merge(s);n.on("click",(t,e)=>this.onNodeClick(t,e)),n.transition().duration(this.duration).attr("transform",t=>{if(this.isRadialLayout){const[e,i]=this.radialPoint(t.x,t.y);return`translate(${e},${i})`}return`translate(${t.y},${t.x})`}),n.attr("class",t=>{let e=["node","code-node"];return"directory"===t.data.type?(e.push("directory"),!0===t.data.loaded&&t.children&&e.push("expanded"),"loading"===t.data.loaded&&e.push("loading"),t.data.children&&0===t.data.children.length&&e.push("empty")):"file"===t.data.type&&e.push("file"),e.join(" ")}),n.select("circle.node-circle").attr("r",t=>"directory"===t.data.type?10:8).style("fill",t=>this.getNodeColor(t)),n.select(".expand-icon").text(t=>"loading"===t.data.loaded?"⟳":!0===t.data.loaded&&t.children?"▼":"▶"),n.select(".item-count-badge").text(t=>{if("directory"!==t.data.type)return"";const e=t.data.children?t.data.children.length:0;return e>0?e:""}).style("stroke",t=>this.getNodeStrokeColor(t)).attr("cursor","pointer");const r=this.isRadialLayout;n.select("text.node-label").style("fill-opacity",1).style("fill","#333").each(function(t){const e=d3.select(this);if(r){const i=180*t.x/Math.PI-90;i>90||i<-90?e.attr("transform",`rotate(${i+180})`).attr("x",-15).attr("text-anchor","end").attr("dy",".35em"):e.attr("transform",`rotate(${i})`).attr("x",15).attr("text-anchor","start").attr("dy",".35em")}else e.attr("transform",null).attr("x",t.children||t._children?-13:13).attr("text-anchor",t.children||t._children?"end":"start").attr("dy",".35em")});const d=s.exit().transition().duration(this.duration).attr("transform",e=>{if(this.isRadialLayout){const[e,i]=this.radialPoint(t.x,t.y);return`translate(${e},${i})`}return`translate(${t.y},${t.x})`}).remove();d.select("circle").attr("r",1e-6),d.select("text.node-label").style("fill-opacity",1e-6),d.select("text.node-icon").style("fill-opacity",1e-6);const l=this.treeGroup.selectAll("path.link").data(o,t=>t.id);l.enter().insert("path","g").attr("class","link").attr("d",e=>{const i={x:t.x0,y:t.y0};return this.isRadialLayout?this.radialDiagonal(i,i):this.diagonal(i,i)}).style("fill","none").style("stroke","#ccc").style("stroke-width",2).merge(l).transition().duration(this.duration).attr("d",t=>this.isRadialLayout?this.radialDiagonal(t,t.parent):this.diagonal(t,t.parent)),l.exit().transition().duration(this.duration).attr("d",e=>{const i={x:t.x,y:t.y};return this.isRadialLayout?this.radialDiagonal(i,i):this.diagonal(i,i)}).remove(),i.forEach(t=>{t.x0=t.x,t.y0=t.y})}centerOnNode(t){console.log("[CodeTree] centerOnNode called but disabled - no centering will occur")}centerOnNodeRadial(t){console.log("[CodeTree] centerOnNodeRadial called but disabled - no centering will occur")}highlightActiveNode(t){const e=this.treeGroup.selectAll("circle.node-circle");e.classed("active",!1).classed("parent-context",!1),e.transition().duration(300).attr("r",8).style("stroke",null).style("stroke-width",null).style("opacity",null),this.treeGroup.selectAll("text.node-label").style("font-weight","normal").style("font-size","12px");const i=this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle");i.classed("active",!0),i.transition().duration(300).attr("r",20).style("stroke","#3b82f6").style("stroke-width",5).style("filter","drop-shadow(0 0 15px rgba(59, 130, 246, 0.6))"),this.treeGroup.selectAll("g.node").filter(e=>e===t).select("text.node-label").style("font-weight","bold").style("font-size","14px"),this.activeNode=t}addLoadingPulse(t){const e=this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle");this.loadingNodes.add(t.data.path),e.classed("loading-pulse",!0),e.style("fill","#fb923c");const i=()=>{this.loadingNodes.has(t.data.path)&&e.transition().duration(600).attr("r",14).style("opacity",.6).transition().duration(600).attr("r",10).style("opacity",1).on("end",()=>{this.loadingNodes.has(t.data.path)&&i()})};i()}removeLoadingPulse(t){this.loadingNodes.delete(t.data.path);const e=this.treeGroup.selectAll("g.node").filter(e=>e===t).select("circle.node-circle");e.classed("loading-pulse",!1),e.interrupt().transition().duration(300).attr("r",this.activeNode===t?20:8).style("opacity",1).style("fill",t=>this.getNodeColor(t))}showWithParent(t){if(!t.parent)return;const e=this.treeGroup.selectAll("g.node").filter(e=>e===t.parent).select("circle.node-circle");e.classed("parent-context",!0),e.style("stroke","#10b981").style("stroke-width",3).style("opacity",.8)}onNodeClick(t,e){if(t)try{"function"==typeof t.stopPropagation&&t.stopPropagation()}catch(a){console.error("[CodeTree] ERROR calling stopPropagation:",a)}if(!e)return void console.error("[CodeTree] ERROR: d is null/undefined, cannot continue");if(!e.data)return void console.error("[CodeTree] ERROR: d.data is null/undefined, cannot continue");try{"function"==typeof this.highlightActiveNode?this.highlightActiveNode(e):console.error("[CodeTree] highlightActiveNode is not a function!")}catch(a){console.error("[CodeTree] ERROR during highlightActiveNode:",a,a.stack)}try{"function"==typeof this.showWithParent?this.showWithParent(e):console.error("[CodeTree] showWithParent is not a function!")}catch(a){console.error("[CodeTree] ERROR during showWithParent:",a,a.stack)}if("directory"===e.data.type&&!e.data.loaded)try{"function"==typeof this.addLoadingPulse?this.addLoadingPulse(e):console.error("[CodeTree] addLoadingPulse is not a function!")}catch(a){console.error("[CodeTree] ERROR during addLoadingPulse:",a,a.stack)}const i=[];document.querySelectorAll(".language-checkbox:checked").forEach(t=>{i.push(t.value)});const o=document.getElementById("ignore-patterns"),s=o?.value||"";if("directory"!==e.data.type||e.data.loaded)if("file"!==e.data.type||e.data.analyzed)if("directory"===e.data.type&&!0===e.data.loaded){if(e.children)e._children=e.children,e.children=null,e.data.expanded=!1;else if(e._children)e.children=e._children,e._children=null,e.data.expanded=!0;else if(e.data.children&&e.data.children.length>0){this.root=d3.hierarchy(this.treeData);const t=this.findD3NodeByPath(e.data.path);t&&(t.children=t._children||t.children,t._children=null,t.data.expanded=!0)}this.update(this.root)}else(e.children||e._children)&&(e.children?(e._children=e.children,e.children=null,e.data.expanded=!1):(e.children=e._children,e._children=null,e.data.expanded=!0),this.update(e));else{const t=this.detectLanguage(e.data.path);if(!i.includes(t)&&"unknown"!==t)return void this.showNotification(`Skipping ${e.data.name} - ${t} not selected`,"warning");this.addLoadingPulse(e),e.data.analyzed="loading";const o=this.ensureFullPath(e.data.path);setTimeout(()=>{this.socket&&(this.socket.emit("code:analyze:file",{path:o}),this.updateBreadcrumb(`Analyzing ${e.data.name}...`,"info"),this.showNotification(`Analyzing: ${e.data.name}`,"info"))},100)}else{if(this.loadingNodes.has(e.data.path))return void this.showNotification(`Already loading: ${e.data.name}`,"warning");e.data.loaded="loading",this.loadingNodes.add(e.data.path);const t=this.ensureFullPath(e.data.path);console.log("🚀 [SUBDIRECTORY LOADING] Attempting to load:",{originalPath:e.data.path,fullPath:t,nodeType:e.data.type,loaded:e.data.loaded,hasSocket:!!this.socket,workingDir:this.getWorkingDirectory()}),setTimeout(()=>{this.socket?(console.log("📡 [SUBDIRECTORY LOADING] Emitting WebSocket request:",{event:"code:discover:directory",data:{path:t,depth:this.bulkLoadMode?2:1,languages:i,ignore_patterns:s}}),this.socket.emit("code:discover:directory",{path:t,depth:this.bulkLoadMode?2:1,languages:i,ignore_patterns:s}),this.updateBreadcrumb(`Loading ${e.data.name}...`,"info"),this.showNotification(`Loading directory: ${e.data.name}`,"info")):(console.error("❌ [SUBDIRECTORY LOADING] No WebSocket connection available!"),this.showNotification("Cannot load directory: No connection","error"))},100)}this.selectedNode=e;try{this.highlightNode(e)}catch(a){console.error("[CodeTree] ERROR during highlightNode:",a)}}ensureFullPath(t){if(console.log("🔗 ensureFullPath called with:",t),!t)return t;if(t.startsWith("/"))return console.log(" → Already absolute, returning:",t),t;const e=this.getWorkingDirectory();if(console.log(" → Working directory:",e),!e)return console.log(" → No working directory, returning original:",t),t;if("."===t)return console.log(" → Root path detected, returning working dir:",e),e;if(t===e)return console.log(" → Path equals working directory, returning:",e),e;const i=`${e}/${t}`.replace(/\/+/g,"/");return console.log(" → Combining with working dir, result:",i),i}highlightNode(t){this.treeGroup.selectAll("circle.node-circle").style("stroke-width",2).classed("selected",!1),this.treeGroup.selectAll("circle.node-circle").filter(e=>e===t).style("stroke-width",4).classed("selected",!0)}diagonal(t,e){return`M ${t.y} ${t.x}\n C ${(t.y+e.y)/2} ${t.x},\n ${(t.y+e.y)/2} ${e.x},\n ${e.y} ${e.x}`}radialDiagonal(t,e){return d3.linkRadial().angle(t=>t.x).radius(t=>t.y)({source:t,target:e})}getNodeColor(t){const e=t.data.type,i=t.data.complexity||1,o={root:"#6B7280",directory:"#3B82F6",file:"#10B981",module:"#8B5CF6",class:"#F59E0B",function:"#EF4444",method:"#EC4899"}[e]||"#6B7280";return i>10?d3.color(o).darker(.5):i>5?d3.color(o).darker(.25):o}getNodeStrokeColor(t){return"loading"===t.data.loaded||"loading"===t.data.analyzed?"#FCD34D":"directory"!==t.data.type||t.data.loaded?"file"!==t.data.type||t.data.analyzed?this.getNodeColor(t):"#CBD5E1":"#94A3B8"}getNodeIcon(t){return{root:"📦",directory:"📁",file:"📄",module:"📦",class:"C",function:"ƒ",method:"m"}[t.data.type]||"•"}showTooltip(t,e){if(!this.tooltip)return;const i=[];i.push(`<strong>${e.data.name}</strong>`),i.push(`Type: ${e.data.type}`),e.data.language&&i.push(`Language: ${e.data.language}`),e.data.complexity&&i.push(`Complexity: ${e.data.complexity}`),e.data.lines&&i.push(`Lines: ${e.data.lines}`),e.data.path&&i.push(`Path: ${e.data.path}`),"directory"!==e.data.type||e.data.loaded?"file"!==e.data.type||e.data.analyzed||i.push("<em>Click to analyze file</em>"):i.push("<em>Click to explore contents</em>"),this.tooltip.transition().duration(200).style("opacity",.9),this.tooltip.html(i.join("<br>")).style("left",t.pageX+10+"px").style("top",t.pageY-28+"px")}hideTooltip(){this.tooltip&&this.tooltip.transition().duration(500).style("opacity",0)}filterTree(){this.root&&(this.root.descendants().forEach(t=>{t.data._hidden=!1,"all"!==this.languageFilter&&"file"===t.data.type&&t.data.language!==this.languageFilter&&(t.data._hidden=!0),this.searchTerm&&(t.data.name.toLowerCase().includes(this.searchTerm)||(t.data._hidden=!0))}),this.update(this.root))}expandAll(){if(!this.root)return;const t=e=>{e._children&&(e.children=e._children,e._children=null),e.children&&e.children.forEach(t)};t(this.root),this.update(this.root),this.showNotification("All nodes expanded","info")}collapseAll(){if(!this.root)return;const t=e=>{e.children&&(e._children=e.children,e.children=null),e._children&&e._children.forEach(t)};this.root.children?.forEach(t),this.update(this.root),this.showNotification("All nodes collapsed","info")}resetZoom(){console.log("[CodeTree] resetZoom called but disabled - no zoom reset will occur"),this.showNotification("Zoom reset disabled - tree remains stationary","info")}focusOnNode(t){console.log("[CodeTree] focusOnNode called but disabled - no focusing will occur")}getNodePath(t){const e=[];let i=t;for(;i;)i.data&&i.data.name&&e.unshift(i.data.name),i=i.parent;return e.join(" / ")}toggleLegend(){const t=document.getElementById("tree-legend");t&&("none"===t.style.display?t.style.display="block":t.style.display="none")}getWorkingDirectory(){if(window.dashboard&&window.dashboard.workingDirectoryManager)return window.dashboard.workingDirectoryManager.getCurrentWorkingDir();const t=document.getElementById("working-dir-path");if(t){const e=t.textContent.trim();if(e&&"Loading..."!==e&&"Not selected"!==e)return e}return null}showNoWorkingDirectoryMessage(){const t=document.getElementById("code-tree-container");if(!t)return;this.removeNoWorkingDirectoryMessage(),this.hideLoading();const e=document.createElement("div");e.id="no-working-dir-message",e.className="no-working-dir-message",e.innerHTML='\n <div class="message-icon">📁</div>\n <h3>No Working Directory Selected</h3>\n <p>Please select a working directory from the top menu to analyze code.</p>\n <button id="select-working-dir-btn" class="btn btn-primary">\n Select Working Directory\n </button>\n ',e.style.cssText="\n text-align: center;\n padding: 40px;\n color: #666;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n ";const i=e.querySelector(".message-icon");i&&(i.style.cssText="font-size: 48px; margin-bottom: 16px; opacity: 0.5;");const o=e.querySelector("h3");o&&(o.style.cssText="margin: 16px 0; color: #333; font-size: 20px;");const s=e.querySelector("p");s&&(s.style.cssText="margin: 16px 0; color: #666; font-size: 14px;");const a=e.querySelector("button");a&&(a.style.cssText="\n margin-top: 20px;\n padding: 10px 20px;\n background: #3b82f6;\n color: white;\n border: none;\n border-radius: 6px;\n cursor: pointer;\n font-size: 14px;\n transition: background 0.2s;\n ",a.addEventListener("mouseenter",()=>{a.style.background="#2563eb"}),a.addEventListener("mouseleave",()=>{a.style.background="#3b82f6"}),a.addEventListener("click",()=>{const t=document.getElementById("change-dir-btn");t?t.click():window.dashboard&&window.dashboard.workingDirectoryManager&&window.dashboard.workingDirectoryManager.showChangeDirDialog()})),t.appendChild(e),this.updateBreadcrumb("Please select a working directory","warning")}removeNoWorkingDirectoryMessage(){const t=document.getElementById("no-working-dir-message");t&&t.remove()}exportTree(){const t={timestamp:(new Date).toISOString(),workingDirectory:this.getWorkingDirectory(),stats:this.stats,tree:this.treeData},e=new Blob([JSON.stringify(t,null,2)],{type:"application/json"}),i=URL.createObjectURL(e),o=document.createElement("a");o.href=i,o.download=`code-tree-${Date.now()}.json`,o.click(),URL.revokeObjectURL(i),this.showNotification("Tree exported successfully","success")}updateActivityTicker(t,e="info"){const i=document.getElementById("breadcrumb-content");if(i){const o="info"===e&&t.includes("...")?"⟳ ":"";i.innerHTML=`${o}${t}`,i.className=`breadcrumb-${e}`}}updateTicker(t,e="info"){const i=document.getElementById("code-tree-ticker");i&&(i.textContent=t,i.className=`ticker ticker-${e}`,"error"!==e&&setTimeout(()=>{i.style.opacity="0",setTimeout(()=>{i.style.opacity="1",i.textContent=""},300)},5e3))}}window.CodeTree=t,document.addEventListener("DOMContentLoaded",()=>{document.getElementById("code-tree-container")&&(window.codeTree=new t,document.addEventListener("click",t=>{t.target.matches('[data-tab="code"]')&&setTimeout(()=>{window.codeTree&&!window.codeTree.initialized?window.codeTree.initialize():window.codeTree&&window.codeTree.renderWhenVisible()},100)}))});
2
- //# sourceMappingURL=code-tree.js.map