claude-mpm 4.24.0__py3-none-any.whl → 5.4.41__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


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

Files changed (623) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/__init__.py +4 -0
  3. claude_mpm/agents/BASE_AGENT.md +164 -0
  4. claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
  5. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
  6. claude_mpm/agents/MEMORY.md +1 -1
  7. claude_mpm/agents/PM_INSTRUCTIONS.md +735 -925
  8. claude_mpm/agents/WORKFLOW.md +5 -254
  9. claude_mpm/agents/__init__.py +6 -0
  10. claude_mpm/agents/agent_loader.py +14 -48
  11. claude_mpm/agents/base_agent.json +7 -4
  12. claude_mpm/agents/frontmatter_validator.py +71 -3
  13. claude_mpm/agents/templates/circuit-breakers.md +1391 -0
  14. claude_mpm/agents/templates/context-management-examples.md +544 -0
  15. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +48 -0
  16. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  17. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  18. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  19. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  20. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  21. claude_mpm/cli/__init__.py +37 -2
  22. claude_mpm/cli/__main__.py +4 -0
  23. claude_mpm/cli/chrome_devtools_installer.py +175 -0
  24. claude_mpm/cli/commands/__init__.py +2 -0
  25. claude_mpm/cli/commands/agent_source.py +774 -0
  26. claude_mpm/cli/commands/agent_state_manager.py +180 -31
  27. claude_mpm/cli/commands/agents.py +1116 -55
  28. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  29. claude_mpm/cli/commands/agents_discover.py +338 -0
  30. claude_mpm/cli/commands/aggregate.py +1 -1
  31. claude_mpm/cli/commands/analyze.py +3 -3
  32. claude_mpm/cli/commands/auto_configure.py +725 -242
  33. claude_mpm/cli/commands/config.py +95 -6
  34. claude_mpm/cli/commands/configure.py +1875 -46
  35. claude_mpm/cli/commands/configure_agent_display.py +29 -10
  36. claude_mpm/cli/commands/configure_navigation.py +63 -46
  37. claude_mpm/cli/commands/debug.py +12 -12
  38. claude_mpm/cli/commands/doctor.py +10 -2
  39. claude_mpm/cli/commands/hook_errors.py +277 -0
  40. claude_mpm/cli/commands/local_deploy.py +1 -4
  41. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  42. claude_mpm/cli/commands/mpm_init/core.py +229 -2
  43. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  44. claude_mpm/cli/commands/mpm_init/knowledge_extractor.py +481 -0
  45. claude_mpm/cli/commands/mpm_init/prompts.py +286 -6
  46. claude_mpm/cli/commands/postmortem.py +401 -0
  47. claude_mpm/cli/commands/profile.py +277 -0
  48. claude_mpm/cli/commands/run.py +123 -165
  49. claude_mpm/cli/commands/skill_source.py +694 -0
  50. claude_mpm/cli/commands/skills.py +782 -20
  51. claude_mpm/cli/commands/summarize.py +413 -0
  52. claude_mpm/cli/executor.py +96 -3
  53. claude_mpm/cli/interactive/agent_wizard.py +1030 -45
  54. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  55. claude_mpm/cli/parsers/agents_parser.py +307 -10
  56. claude_mpm/cli/parsers/auto_configure_parser.py +13 -138
  57. claude_mpm/cli/parsers/base_parser.py +65 -0
  58. claude_mpm/cli/parsers/config_parser.py +162 -39
  59. claude_mpm/cli/parsers/profile_parser.py +148 -0
  60. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  61. claude_mpm/cli/parsers/skills_parser.py +146 -0
  62. claude_mpm/cli/parsers/source_parser.py +138 -0
  63. claude_mpm/cli/startup.py +1280 -118
  64. claude_mpm/cli/startup_display.py +480 -0
  65. claude_mpm/cli/utils.py +1 -1
  66. claude_mpm/cli_module/commands.py +1 -1
  67. claude_mpm/commands/mpm-config.md +21 -134
  68. claude_mpm/commands/mpm-doctor.md +16 -20
  69. claude_mpm/commands/mpm-help.md +13 -283
  70. claude_mpm/commands/mpm-init.md +88 -489
  71. claude_mpm/commands/mpm-monitor.md +23 -401
  72. claude_mpm/commands/mpm-organize.md +72 -247
  73. claude_mpm/commands/mpm-postmortem.md +21 -0
  74. claude_mpm/commands/mpm-session-resume.md +30 -0
  75. claude_mpm/commands/mpm-status.md +13 -68
  76. claude_mpm/commands/mpm-ticket-view.md +109 -0
  77. claude_mpm/commands/mpm-version.md +13 -106
  78. claude_mpm/commands/mpm.md +10 -0
  79. claude_mpm/config/agent_presets.py +488 -0
  80. claude_mpm/config/agent_sources.py +352 -0
  81. claude_mpm/config/skill_presets.py +392 -0
  82. claude_mpm/config/skill_sources.py +590 -0
  83. claude_mpm/constants.py +13 -0
  84. claude_mpm/core/claude_runner.py +5 -34
  85. claude_mpm/core/config.py +15 -1
  86. claude_mpm/core/constants.py +1 -1
  87. claude_mpm/core/framework/__init__.py +3 -16
  88. claude_mpm/core/framework/formatters/content_formatter.py +3 -13
  89. claude_mpm/core/framework/loaders/agent_loader.py +8 -5
  90. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  91. claude_mpm/core/framework/loaders/instruction_loader.py +66 -5
  92. claude_mpm/core/framework_loader.py +4 -2
  93. claude_mpm/core/hook_error_memory.py +381 -0
  94. claude_mpm/core/hook_manager.py +41 -2
  95. claude_mpm/core/interactive_session.py +91 -10
  96. claude_mpm/core/logger.py +16 -1
  97. claude_mpm/core/oneshot_session.py +71 -8
  98. claude_mpm/core/optimized_startup.py +59 -0
  99. claude_mpm/core/output_style_manager.py +173 -43
  100. claude_mpm/core/protocols/__init__.py +23 -0
  101. claude_mpm/core/protocols/runner_protocol.py +103 -0
  102. claude_mpm/core/protocols/session_protocol.py +131 -0
  103. claude_mpm/core/shared/config_loader.py +1 -1
  104. claude_mpm/core/shared/singleton_manager.py +11 -4
  105. claude_mpm/core/socketio_pool.py +3 -3
  106. claude_mpm/core/system_context.py +38 -0
  107. claude_mpm/core/unified_agent_registry.py +134 -16
  108. claude_mpm/core/unified_config.py +22 -0
  109. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  110. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +1 -0
  111. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +1 -0
  112. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +1 -0
  113. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +1 -0
  114. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWc5urbQ.js +1 -0
  115. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +2 -0
  116. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DjhvlsAc.js +1 -0
  117. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/N4qtv3Hx.js +2 -0
  118. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uj46x2Wr.js +1 -0
  119. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +2 -0
  120. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +1 -0
  121. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.CAGBuiOw.js +1 -0
  122. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +1 -0
  123. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +10 -0
  124. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  125. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  126. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  127. claude_mpm/experimental/cli_enhancements.py +1 -5
  128. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  129. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  130. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  131. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  132. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  133. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  134. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  135. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  136. claude_mpm/hooks/claude_hooks/correlation_manager.py +60 -0
  137. claude_mpm/hooks/claude_hooks/event_handlers.py +214 -79
  138. claude_mpm/hooks/claude_hooks/hook_handler.py +155 -1
  139. claude_mpm/hooks/claude_hooks/installer.py +33 -10
  140. claude_mpm/hooks/claude_hooks/memory_integration.py +28 -0
  141. claude_mpm/hooks/claude_hooks/response_tracking.py +2 -3
  142. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  143. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  144. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  145. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  146. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  147. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  148. claude_mpm/hooks/claude_hooks/services/connection_manager.py +30 -6
  149. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  150. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  151. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  152. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  153. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  154. claude_mpm/hooks/memory_integration_hook.py +46 -1
  155. claude_mpm/init.py +63 -19
  156. claude_mpm/models/agent_definition.py +7 -0
  157. claude_mpm/models/git_repository.py +198 -0
  158. claude_mpm/scripts/claude-hook-handler.sh +60 -20
  159. claude_mpm/scripts/launch_monitor.py +93 -13
  160. claude_mpm/scripts/start_activity_logging.py +3 -1
  161. claude_mpm/services/agents/agent_builder.py +48 -12
  162. claude_mpm/services/agents/agent_preset_service.py +238 -0
  163. claude_mpm/services/agents/agent_recommendation_service.py +278 -0
  164. claude_mpm/services/agents/agent_review_service.py +280 -0
  165. claude_mpm/services/agents/agent_selection_service.py +484 -0
  166. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  167. claude_mpm/services/agents/cache_git_manager.py +621 -0
  168. claude_mpm/services/agents/deployment/agent_deployment.py +148 -2
  169. claude_mpm/services/agents/deployment/agent_discovery_service.py +104 -73
  170. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  171. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  172. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  173. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  174. claude_mpm/services/agents/deployment/agent_template_builder.py +238 -15
  175. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  176. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  177. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  178. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +422 -31
  179. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  180. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  181. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +841 -0
  182. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  183. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  184. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  185. claude_mpm/services/agents/git_source_manager.py +663 -0
  186. claude_mpm/services/agents/loading/base_agent_manager.py +1 -13
  187. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  188. claude_mpm/services/agents/local_template_manager.py +50 -10
  189. claude_mpm/services/agents/recommender.py +5 -3
  190. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  191. claude_mpm/services/agents/sources/__init__.py +13 -0
  192. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  193. claude_mpm/services/agents/sources/git_source_sync_service.py +1094 -0
  194. claude_mpm/services/agents/startup_sync.py +259 -0
  195. claude_mpm/services/agents/toolchain_detector.py +478 -0
  196. claude_mpm/services/analysis/__init__.py +35 -0
  197. claude_mpm/services/analysis/clone_detector.py +1030 -0
  198. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  199. claude_mpm/services/analysis/postmortem_service.py +765 -0
  200. claude_mpm/services/cli/session_pause_manager.py +1 -1
  201. claude_mpm/services/command_deployment_service.py +271 -6
  202. claude_mpm/services/core/base.py +7 -2
  203. claude_mpm/services/core/interfaces/__init__.py +1 -3
  204. claude_mpm/services/core/interfaces/health.py +1 -4
  205. claude_mpm/services/core/models/__init__.py +2 -11
  206. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  207. claude_mpm/services/diagnostics/checks/agent_check.py +2 -4
  208. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  209. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  210. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  211. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  212. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  213. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  214. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  215. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  216. claude_mpm/services/event_bus/config.py +3 -1
  217. claude_mpm/services/event_bus/direct_relay.py +3 -3
  218. claude_mpm/services/events/consumers/logging.py +1 -2
  219. claude_mpm/services/git/__init__.py +21 -0
  220. claude_mpm/services/git/git_operations_service.py +579 -0
  221. claude_mpm/services/github/__init__.py +21 -0
  222. claude_mpm/services/github/github_cli_service.py +397 -0
  223. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  224. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  225. claude_mpm/services/instructions/__init__.py +9 -0
  226. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  227. claude_mpm/services/local_ops/__init__.py +3 -13
  228. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  229. claude_mpm/services/local_ops/health_manager.py +1 -4
  230. claude_mpm/services/local_ops/resource_monitor.py +1 -1
  231. claude_mpm/services/mcp_config_manager.py +75 -145
  232. claude_mpm/services/mcp_service_verifier.py +6 -3
  233. claude_mpm/services/model/model_router.py +1 -2
  234. claude_mpm/services/monitor/daemon.py +38 -11
  235. claude_mpm/services/monitor/daemon_manager.py +134 -21
  236. claude_mpm/services/monitor/management/lifecycle.py +8 -1
  237. claude_mpm/services/monitor/server.py +700 -24
  238. claude_mpm/services/pm_skills_deployer.py +676 -0
  239. claude_mpm/services/port_manager.py +1 -1
  240. claude_mpm/services/pr/__init__.py +14 -0
  241. claude_mpm/services/pr/pr_template_service.py +329 -0
  242. claude_mpm/services/profile_manager.py +331 -0
  243. claude_mpm/services/project/documentation_manager.py +2 -1
  244. claude_mpm/services/project/project_organizer.py +4 -0
  245. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  246. claude_mpm/services/runner_configuration_service.py +16 -3
  247. claude_mpm/services/self_upgrade_service.py +120 -12
  248. claude_mpm/services/session_management_service.py +16 -4
  249. claude_mpm/services/skills/__init__.py +21 -0
  250. claude_mpm/services/skills/git_skill_source_manager.py +1297 -0
  251. claude_mpm/services/skills/selective_skill_deployer.py +704 -0
  252. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  253. claude_mpm/services/skills/skill_to_agent_mapper.py +406 -0
  254. claude_mpm/services/skills_config.py +547 -0
  255. claude_mpm/services/skills_deployer.py +1072 -0
  256. claude_mpm/services/socketio/dashboard_server.py +1 -0
  257. claude_mpm/services/socketio/event_normalizer.py +51 -6
  258. claude_mpm/services/socketio/handlers/connection.py +1 -1
  259. claude_mpm/services/socketio/handlers/git.py +1 -1
  260. claude_mpm/services/socketio/server/core.py +387 -112
  261. claude_mpm/services/socketio/server/main.py +1 -3
  262. claude_mpm/services/system_instructions_service.py +1 -3
  263. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  264. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  265. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  266. claude_mpm/services/unified/unified_deployment.py +1 -5
  267. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  268. claude_mpm/services/version_control/git_operations.py +103 -0
  269. claude_mpm/services/visualization/__init__.py +1 -5
  270. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  271. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  272. claude_mpm/skills/skill_manager.py +92 -3
  273. claude_mpm/skills/skills_registry.py +0 -1
  274. claude_mpm/templates/questions/__init__.py +38 -0
  275. claude_mpm/templates/questions/base.py +193 -0
  276. claude_mpm/templates/questions/pr_strategy.py +311 -0
  277. claude_mpm/templates/questions/project_init.py +385 -0
  278. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  279. claude_mpm/tools/__main__.py +8 -8
  280. claude_mpm/utils/agent_dependency_loader.py +91 -12
  281. claude_mpm/utils/agent_filters.py +261 -0
  282. claude_mpm/utils/dependency_cache.py +3 -1
  283. claude_mpm/utils/gitignore.py +244 -0
  284. claude_mpm/utils/migration.py +372 -0
  285. claude_mpm/utils/progress.py +387 -0
  286. claude_mpm/utils/robust_installer.py +49 -7
  287. claude_mpm/utils/structured_questions.py +619 -0
  288. {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/METADATA +445 -122
  289. {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/RECORD +298 -503
  290. claude_mpm-5.4.41.dist-info/entry_points.txt +5 -0
  291. claude_mpm-5.4.41.dist-info/licenses/LICENSE +94 -0
  292. claude_mpm-5.4.41.dist-info/licenses/LICENSE-FAQ.md +153 -0
  293. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +0 -292
  294. claude_mpm/agents/BASE_DOCUMENTATION.md +0 -53
  295. claude_mpm/agents/BASE_OPS.md +0 -219
  296. claude_mpm/agents/BASE_PM.md +0 -468
  297. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +0 -787
  298. claude_mpm/agents/BASE_QA.md +0 -167
  299. claude_mpm/agents/BASE_RESEARCH.md +0 -53
  300. claude_mpm/agents/base_agent_loader.py +0 -626
  301. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  302. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  303. claude_mpm/agents/templates/agent-manager.json +0 -273
  304. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  305. claude_mpm/agents/templates/api_qa.json +0 -183
  306. claude_mpm/agents/templates/circuit_breakers.md +0 -638
  307. claude_mpm/agents/templates/clerk-ops.json +0 -235
  308. claude_mpm/agents/templates/code_analyzer.json +0 -101
  309. claude_mpm/agents/templates/content-agent.json +0 -358
  310. claude_mpm/agents/templates/dart_engineer.json +0 -307
  311. claude_mpm/agents/templates/data_engineer.json +0 -225
  312. claude_mpm/agents/templates/documentation.json +0 -238
  313. claude_mpm/agents/templates/engineer.json +0 -210
  314. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  315. claude_mpm/agents/templates/golang_engineer.json +0 -270
  316. claude_mpm/agents/templates/imagemagick.json +0 -264
  317. claude_mpm/agents/templates/java_engineer.json +0 -346
  318. claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
  319. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  320. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  321. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  322. claude_mpm/agents/templates/memory_manager.json +0 -158
  323. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  324. claude_mpm/agents/templates/ops.json +0 -185
  325. claude_mpm/agents/templates/php-engineer.json +0 -287
  326. claude_mpm/agents/templates/product_owner.json +0 -338
  327. claude_mpm/agents/templates/project_organizer.json +0 -144
  328. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  329. claude_mpm/agents/templates/python_engineer.json +0 -387
  330. claude_mpm/agents/templates/qa.json +0 -243
  331. claude_mpm/agents/templates/react_engineer.json +0 -239
  332. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  333. claude_mpm/agents/templates/research.json +0 -188
  334. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  335. claude_mpm/agents/templates/rust_engineer.json +0 -275
  336. claude_mpm/agents/templates/security.json +0 -202
  337. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  338. claude_mpm/agents/templates/tauri_engineer.json +0 -274
  339. claude_mpm/agents/templates/ticketing.json +0 -178
  340. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  341. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  342. claude_mpm/agents/templates/version_control.json +0 -159
  343. claude_mpm/agents/templates/web_qa.json +0 -400
  344. claude_mpm/agents/templates/web_ui.json +0 -189
  345. claude_mpm/cli/commands/agents_detect.py +0 -380
  346. claude_mpm/cli/commands/agents_recommend.py +0 -309
  347. claude_mpm/cli/ticket_cli.py +0 -35
  348. claude_mpm/commands/mpm-agents-detect.md +0 -168
  349. claude_mpm/commands/mpm-agents-recommend.md +0 -214
  350. claude_mpm/commands/mpm-agents.md +0 -122
  351. claude_mpm/commands/mpm-auto-configure.md +0 -269
  352. claude_mpm/commands/mpm-resume.md +0 -372
  353. claude_mpm/commands/mpm-tickets.md +0 -151
  354. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  355. claude_mpm/dashboard/analysis_runner.py +0 -455
  356. claude_mpm/dashboard/index.html +0 -13
  357. claude_mpm/dashboard/open_dashboard.py +0 -66
  358. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  359. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  360. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  361. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  362. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  363. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  364. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  365. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  366. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  367. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  368. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  369. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  370. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  371. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  372. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  373. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  374. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  375. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  376. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  377. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  378. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  379. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  380. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  381. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  382. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  383. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  384. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  385. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  386. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  387. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  388. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  389. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  390. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  391. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  392. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  393. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  394. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  395. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  396. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  397. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  398. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  399. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  400. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  401. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  402. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  403. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  404. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  405. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  406. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  407. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  408. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  409. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  410. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  411. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  412. claude_mpm/dashboard/static/built/react/events.js +0 -30
  413. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  414. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  415. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  416. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  417. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  418. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  419. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  420. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  421. claude_mpm/dashboard/static/css/activity.css +0 -1958
  422. claude_mpm/dashboard/static/css/connection-status.css +0 -370
  423. claude_mpm/dashboard/static/css/dashboard.css +0 -4701
  424. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  425. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  426. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  427. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  428. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  429. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  430. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  431. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  432. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  433. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  434. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  435. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  436. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  437. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  438. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  439. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  440. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  441. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  442. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  443. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  444. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  445. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  446. claude_mpm/dashboard/static/events.html +0 -607
  447. claude_mpm/dashboard/static/index.html +0 -635
  448. claude_mpm/dashboard/static/js/components/activity-tree.js +0 -1871
  449. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +0 -777
  450. claude_mpm/dashboard/static/js/components/agent-inference.js +0 -956
  451. claude_mpm/dashboard/static/js/components/build-tracker.js +0 -333
  452. claude_mpm/dashboard/static/js/components/code-simple.js +0 -857
  453. claude_mpm/dashboard/static/js/components/connection-debug.js +0 -654
  454. claude_mpm/dashboard/static/js/components/diff-viewer.js +0 -891
  455. claude_mpm/dashboard/static/js/components/event-processor.js +0 -542
  456. claude_mpm/dashboard/static/js/components/event-viewer.js +0 -1155
  457. claude_mpm/dashboard/static/js/components/export-manager.js +0 -368
  458. claude_mpm/dashboard/static/js/components/file-change-tracker.js +0 -443
  459. claude_mpm/dashboard/static/js/components/file-change-viewer.js +0 -690
  460. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +0 -724
  461. claude_mpm/dashboard/static/js/components/file-viewer.js +0 -580
  462. claude_mpm/dashboard/static/js/components/hud-library-loader.js +0 -211
  463. claude_mpm/dashboard/static/js/components/hud-manager.js +0 -671
  464. claude_mpm/dashboard/static/js/components/hud-visualizer.js +0 -1718
  465. claude_mpm/dashboard/static/js/components/module-viewer.js +0 -2764
  466. claude_mpm/dashboard/static/js/components/session-manager.js +0 -579
  467. claude_mpm/dashboard/static/js/components/socket-manager.js +0 -368
  468. claude_mpm/dashboard/static/js/components/ui-state-manager.js +0 -749
  469. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +0 -1824
  470. claude_mpm/dashboard/static/js/components/working-directory.js +0 -920
  471. claude_mpm/dashboard/static/js/connection-manager.js +0 -536
  472. claude_mpm/dashboard/static/js/dashboard.js +0 -1896
  473. claude_mpm/dashboard/static/js/extension-error-handler.js +0 -164
  474. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  475. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  476. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  477. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  478. claude_mpm/dashboard/static/js/socket-client.js +0 -1457
  479. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  480. claude_mpm/dashboard/static/js/tab-isolation-fix.js +0 -185
  481. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  482. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  483. claude_mpm/dashboard/static/legacy/files.html +0 -747
  484. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  485. claude_mpm/dashboard/static/monitors.html +0 -431
  486. claude_mpm/dashboard/static/production/events.html +0 -659
  487. claude_mpm/dashboard/static/production/main.html +0 -698
  488. claude_mpm/dashboard/static/production/monitors.html +0 -483
  489. claude_mpm/dashboard/static/socket.io.min.js +0 -7
  490. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +0 -7
  491. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  492. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  493. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  494. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  495. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  496. claude_mpm/dashboard/templates/code_simple.html +0 -153
  497. claude_mpm/dashboard/templates/index.html +0 -606
  498. claude_mpm/dashboard/test_dashboard.html +0 -372
  499. claude_mpm/scripts/mcp_server.py +0 -75
  500. claude_mpm/scripts/mcp_wrapper.py +0 -39
  501. claude_mpm/services/mcp_gateway/__init__.py +0 -159
  502. claude_mpm/services/mcp_gateway/auto_configure.py +0 -369
  503. claude_mpm/services/mcp_gateway/config/__init__.py +0 -17
  504. claude_mpm/services/mcp_gateway/config/config_loader.py +0 -296
  505. claude_mpm/services/mcp_gateway/config/config_schema.py +0 -243
  506. claude_mpm/services/mcp_gateway/config/configuration.py +0 -429
  507. claude_mpm/services/mcp_gateway/core/__init__.py +0 -43
  508. claude_mpm/services/mcp_gateway/core/base.py +0 -312
  509. claude_mpm/services/mcp_gateway/core/exceptions.py +0 -253
  510. claude_mpm/services/mcp_gateway/core/interfaces.py +0 -443
  511. claude_mpm/services/mcp_gateway/core/process_pool.py +0 -971
  512. claude_mpm/services/mcp_gateway/core/singleton_manager.py +0 -315
  513. claude_mpm/services/mcp_gateway/core/startup_verification.py +0 -316
  514. claude_mpm/services/mcp_gateway/main.py +0 -589
  515. claude_mpm/services/mcp_gateway/registry/__init__.py +0 -12
  516. claude_mpm/services/mcp_gateway/registry/service_registry.py +0 -412
  517. claude_mpm/services/mcp_gateway/registry/tool_registry.py +0 -489
  518. claude_mpm/services/mcp_gateway/server/__init__.py +0 -15
  519. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +0 -419
  520. claude_mpm/services/mcp_gateway/server/stdio_handler.py +0 -372
  521. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -714
  522. claude_mpm/services/mcp_gateway/tools/__init__.py +0 -36
  523. claude_mpm/services/mcp_gateway/tools/base_adapter.py +0 -485
  524. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +0 -789
  525. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +0 -654
  526. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +0 -456
  527. claude_mpm/services/mcp_gateway/tools/hello_world.py +0 -551
  528. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +0 -551
  529. claude_mpm/services/mcp_gateway/utils/__init__.py +0 -14
  530. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +0 -160
  531. claude_mpm/services/mcp_gateway/utils/update_preferences.py +0 -170
  532. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  533. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  534. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  535. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  536. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  537. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  538. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  539. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  540. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  541. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  542. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  543. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  544. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  545. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  546. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  547. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  548. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  549. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  550. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  551. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  552. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  553. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  554. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  555. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  556. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  557. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  558. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  559. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  560. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  561. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  562. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  563. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  564. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  565. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  566. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  567. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  568. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  569. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  570. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  571. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  572. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  573. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  574. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  575. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  576. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  577. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  578. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  579. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  580. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  581. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  582. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  583. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  584. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  585. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  586. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  587. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  588. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  589. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  590. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  591. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  592. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  593. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  594. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  595. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  596. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  597. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  598. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  599. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  600. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  601. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  602. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  603. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  604. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  605. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  606. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  607. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  608. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  609. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  610. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  611. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  612. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  613. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  614. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  615. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  616. claude_mpm-4.24.0.dist-info/entry_points.txt +0 -10
  617. claude_mpm-4.24.0.dist-info/licenses/LICENSE +0 -21
  618. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  619. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  620. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  621. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  622. {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/WHEEL +0 -0
  623. {claude_mpm-4.24.0.dist-info → claude_mpm-5.4.41.dist-info}/top_level.txt +0 -0
@@ -1,1871 +0,0 @@
1
- /**
2
- * Activity Tree Component - Linear Tree View
3
- *
4
- * HTML/CSS-based linear tree visualization for showing PM activity hierarchy.
5
- * Replaces D3.js with simpler, cleaner linear tree structure.
6
- * Uses UnifiedDataViewer for consistent data display with Tools viewer.
7
- */
8
-
9
- // Import UnifiedDataViewer for consistent data display
10
- import { UnifiedDataViewer } from './unified-data-viewer.js';
11
-
12
- class ActivityTree {
13
- constructor() {
14
- this.container = null;
15
- this.events = [];
16
- this.processedEventIds = new Set(); // Track which events we've already processed
17
- this.sessions = new Map();
18
- this.currentSession = null;
19
- this.selectedSessionFilter = 'all';
20
- this.timeRange = '30min';
21
- this.searchTerm = '';
22
- this.initialized = false;
23
- this.expandedSessions = new Set();
24
- this.expandedAgents = new Set();
25
- this.expandedTools = new Set();
26
- this.selectedItem = null;
27
- this.sessionFilterInitialized = false; // Flag to prevent initialization loop
28
-
29
- // Add debounce for renderTree to prevent excessive DOM rebuilds
30
- this.renderTreeDebounced = this.debounce(() => this.renderTree(), 100);
31
- }
32
-
33
- /**
34
- * Debounce helper to prevent excessive DOM updates
35
- */
36
- debounce(func, wait) {
37
- let timeout;
38
- return function executedFunction(...args) {
39
- const later = () => {
40
- clearTimeout(timeout);
41
- func(...args);
42
- };
43
- clearTimeout(timeout);
44
- timeout = setTimeout(later, wait);
45
- };
46
- }
47
-
48
- /**
49
- * Initialize the activity tree
50
- */
51
- initialize() {
52
- console.log('ActivityTree.initialize() called, initialized:', this.initialized);
53
-
54
- if (this.initialized) {
55
- console.log('Activity tree already initialized, skipping');
56
- return;
57
- }
58
-
59
- this.container = document.getElementById('activity-tree-container');
60
- if (!this.container) {
61
- this.container = document.getElementById('activity-tree');
62
- if (!this.container) {
63
- console.error('Activity tree container not found in DOM');
64
- return;
65
- }
66
- }
67
-
68
- // Check if the container is visible before initializing
69
- const tabPanel = document.getElementById('activity-tab');
70
- if (!tabPanel) {
71
- console.error('Activity tab panel (#activity-tab) not found in DOM');
72
- return;
73
- }
74
-
75
- // Initialize even if tab is not active
76
- if (!tabPanel.classList.contains('active')) {
77
- console.log('Activity tab not active, initializing but deferring render');
78
- this.setupControls();
79
- this.subscribeToEvents();
80
- this.initialized = true;
81
- return;
82
- }
83
-
84
- this.setupControls();
85
- this.createLinearTreeView();
86
- this.subscribeToEvents();
87
-
88
- this.initialized = true;
89
- console.log('Activity tree initialization complete');
90
- }
91
-
92
- /**
93
- * Force show the tree visualization
94
- */
95
- forceShow() {
96
- console.log('ActivityTree.forceShow() called');
97
-
98
- if (!this.container) {
99
- this.container = document.getElementById('activity-tree-container') || document.getElementById('activity-tree');
100
- if (!this.container) {
101
- console.error('Cannot find activity tree container');
102
- return;
103
- }
104
- }
105
-
106
- this.createLinearTreeView();
107
- this.renderTree();
108
- }
109
-
110
- /**
111
- * Render the visualization when tab becomes visible
112
- */
113
- renderWhenVisible() {
114
- console.log('ActivityTree.renderWhenVisible() called');
115
-
116
- if (!this.initialized) {
117
- console.log('Not initialized yet, calling initialize...');
118
- this.initialize();
119
- return;
120
- }
121
-
122
- this.createLinearTreeView();
123
- this.renderTree();
124
- }
125
-
126
- /**
127
- * Setup control handlers
128
- */
129
- setupControls() {
130
- // Time range filter dropdown
131
- const timeRangeSelect = document.getElementById('time-range');
132
- if (timeRangeSelect) {
133
- timeRangeSelect.addEventListener('change', (e) => {
134
- this.timeRange = e.target.value;
135
- console.log(`ActivityTree: Time range changed to: ${this.timeRange}`);
136
- this.renderTree();
137
- });
138
- }
139
-
140
- // Listen for session filter changes from SessionManager
141
- document.addEventListener('sessionFilterChanged', (e) => {
142
- this.selectedSessionFilter = e.detail.sessionId || 'all';
143
- console.log(`ActivityTree: Session filter changed to: ${this.selectedSessionFilter} (from SessionManager)`);
144
- this.renderTree();
145
- });
146
-
147
- // Also listen for sessionChanged for backward compatibility
148
- document.addEventListener('sessionChanged', (e) => {
149
- this.selectedSessionFilter = e.detail.sessionId || 'all';
150
- console.log(`ActivityTree: Session changed to: ${this.selectedSessionFilter} (from SessionManager - backward compat)`);
151
- this.renderTree();
152
- });
153
-
154
- // Initialize with current session filter from SessionManager (prevent loop)
155
- setTimeout(() => {
156
- if (window.sessionManager && !this.sessionFilterInitialized) {
157
- const currentFilter = window.sessionManager.getCurrentFilter();
158
- if (currentFilter !== this.selectedSessionFilter) {
159
- this.selectedSessionFilter = currentFilter || 'all';
160
- console.log(`ActivityTree: Initialized with current session filter: ${this.selectedSessionFilter}`);
161
- this.sessionFilterInitialized = true; // Prevent re-initialization
162
- this.renderTree();
163
- }
164
- }
165
- }, 100); // Small delay to ensure SessionManager is initialized
166
-
167
- // Expand all button - expand all sessions
168
- const expandAllBtn = document.getElementById('expand-all');
169
- if (expandAllBtn) {
170
- expandAllBtn.addEventListener('click', () => this.expandAllSessions());
171
- }
172
-
173
- // Collapse all button - collapse all sessions
174
- const collapseAllBtn = document.getElementById('collapse-all');
175
- if (collapseAllBtn) {
176
- collapseAllBtn.addEventListener('click', () => this.collapseAllSessions());
177
- }
178
-
179
- // Reset zoom button functionality
180
- const resetZoomBtn = document.getElementById('reset-zoom');
181
- if (resetZoomBtn) {
182
- resetZoomBtn.style.display = 'inline-block';
183
- resetZoomBtn.addEventListener('click', () => this.resetZoom());
184
- }
185
-
186
- // Search input
187
- const searchInput = document.getElementById('activity-search');
188
- if (searchInput) {
189
- searchInput.addEventListener('input', (e) => {
190
- this.searchTerm = e.target.value.toLowerCase();
191
- this.renderTree();
192
- });
193
- }
194
- }
195
-
196
- /**
197
- * Create the linear tree view container
198
- */
199
- createLinearTreeView() {
200
- console.log('Creating linear tree view');
201
-
202
- // Clear container
203
- this.container.innerHTML = '';
204
-
205
- // Create main tree container
206
- const treeContainer = document.createElement('div');
207
- treeContainer.id = 'linear-tree';
208
- treeContainer.className = 'linear-tree';
209
-
210
- this.container.appendChild(treeContainer);
211
-
212
- console.log('Linear tree view created');
213
- }
214
-
215
- /**
216
- * Subscribe to socket events
217
- */
218
- subscribeToEvents() {
219
- if (!window.socketClient) {
220
- console.warn('Socket client not available for activity tree');
221
- setTimeout(() => this.subscribeToEvents(), 1000);
222
- return;
223
- }
224
-
225
- console.log('ActivityTree: Setting up event subscription');
226
-
227
- // Subscribe to event updates from the socket client
228
- // FIXED: Now correctly receives both events AND sessions from socket client
229
- window.socketClient.onEventUpdate((events, sessions) => {
230
- console.log(`ActivityTree: onEventUpdate called with ${events.length} total events and ${sessions.size} sessions`);
231
-
232
- // IMPORTANT: Don't clear sessions! We need to preserve the accumulated agent data
233
- // Only create new sessions if they don't exist yet
234
- for (const [sessionId, sessionData] of sessions.entries()) {
235
- if (!this.sessions.has(sessionId)) {
236
- // Create new session only if it doesn't exist
237
- const activitySession = {
238
- id: sessionId,
239
- timestamp: new Date(sessionData.lastActivity || sessionData.startTime || new Date()),
240
- expanded: this.expandedSessions.has(sessionId) || true, // Preserve expansion state
241
- agents: new Map(),
242
- todos: [],
243
- userInstructions: [],
244
- tools: [],
245
- toolsMap: new Map(),
246
- status: 'active',
247
- currentTodoTool: null,
248
- // Preserve additional session metadata
249
- working_directory: sessionData.working_directory,
250
- git_branch: sessionData.git_branch,
251
- eventCount: sessionData.eventCount
252
- };
253
- this.sessions.set(sessionId, activitySession);
254
- } else {
255
- // Update existing session metadata without clearing accumulated data
256
- // CRITICAL: Preserve all accumulated data (tools, agents, todos, etc.)
257
- const existingSession = this.sessions.get(sessionId);
258
- existingSession.timestamp = new Date(sessionData.lastActivity || sessionData.startTime || existingSession.timestamp);
259
- existingSession.eventCount = sessionData.eventCount;
260
- existingSession.status = sessionData.status || existingSession.status;
261
- // Update metadata without losing accumulated data
262
- existingSession.working_directory = sessionData.working_directory || existingSession.working_directory;
263
- existingSession.git_branch = sessionData.git_branch || existingSession.git_branch;
264
- // DO NOT reset tools, agents, todos, userInstructions, toolsMap, etc.
265
- // These are built up from events and must be preserved!
266
- }
267
- }
268
-
269
- // Process only events we haven't seen before
270
- const newEvents = events.filter(event => {
271
- const eventId = event.id || `${event.type}-${event.timestamp}-${Math.random()}`;
272
- return !this.processedEventIds.has(eventId);
273
- });
274
-
275
- if (newEvents.length > 0) {
276
- console.log(`ActivityTree: Processing ${newEvents.length} new events`, newEvents);
277
-
278
- newEvents.forEach(event => {
279
- const eventId = event.id || `${event.type}-${event.timestamp}-${Math.random()}`;
280
- this.processedEventIds.add(eventId);
281
- this.processEvent(event);
282
- });
283
- }
284
-
285
- this.events = [...events];
286
- // Use debounced render to prevent excessive DOM rebuilds
287
- this.renderTreeDebounced();
288
-
289
- // Debug: Log session state after processing
290
- console.log(`ActivityTree: Sessions after sync with socket client:`, Array.from(this.sessions.entries()));
291
- });
292
-
293
- // Load existing data from socket client
294
- const socketState = window.socketClient?.getState();
295
-
296
- if (socketState && socketState.events.length > 0) {
297
- console.log(`ActivityTree: Loading existing data - ${socketState.events.length} events, ${socketState.sessions.size} sessions`);
298
-
299
- // Initialize from existing socket client data
300
- // Don't clear existing sessions - preserve accumulated data
301
-
302
- // Convert authoritative sessions Map to our format
303
- for (const [sessionId, sessionData] of socketState.sessions.entries()) {
304
- if (!this.sessions.has(sessionId)) {
305
- const activitySession = {
306
- id: sessionId,
307
- timestamp: new Date(sessionData.lastActivity || sessionData.startTime || new Date()),
308
- expanded: this.expandedSessions.has(sessionId) || true,
309
- agents: new Map(),
310
- todos: [],
311
- userInstructions: [],
312
- tools: [],
313
- toolsMap: new Map(),
314
- status: 'active',
315
- currentTodoTool: null,
316
- working_directory: sessionData.working_directory,
317
- git_branch: sessionData.git_branch,
318
- eventCount: sessionData.eventCount
319
- };
320
- this.sessions.set(sessionId, activitySession);
321
- }
322
- }
323
-
324
- // Process only events we haven't seen before
325
- const unprocessedEvents = socketState.events.filter(event => {
326
- const eventId = event.id || `${event.type}-${event.timestamp}-${Math.random()}`;
327
- return !this.processedEventIds.has(eventId);
328
- });
329
-
330
- if (unprocessedEvents.length > 0) {
331
- console.log(`ActivityTree: Processing ${unprocessedEvents.length} unprocessed events from initial load`);
332
- unprocessedEvents.forEach(event => {
333
- const eventId = event.id || `${event.type}-${event.timestamp}-${Math.random()}`;
334
- this.processedEventIds.add(eventId);
335
- this.processEvent(event);
336
- });
337
- }
338
-
339
- this.events = [...socketState.events];
340
- // Initial render can be immediate
341
- this.renderTree();
342
-
343
- // Debug: Log initial session state
344
- console.log(`ActivityTree: Initial sessions state:`, Array.from(this.sessions.entries()));
345
- } else {
346
- console.log('ActivityTree: No existing events found');
347
- this.events = [];
348
- this.sessions.clear();
349
- this.renderTree();
350
- }
351
- }
352
-
353
- /**
354
- * Process an event and update the session structure
355
- */
356
- processEvent(event) {
357
- if (!event) {
358
- console.log('ActivityTree: Ignoring null event');
359
- return;
360
- }
361
-
362
- // Determine event type
363
- let eventType = this.getEventType(event);
364
- if (!eventType) {
365
- return;
366
- }
367
-
368
- console.log(`ActivityTree: Processing event: ${eventType}`, event);
369
-
370
- // Fix timestamp processing - ensure we get a valid date
371
- let timestamp;
372
- if (event.timestamp) {
373
- // Handle both ISO strings and already parsed dates
374
- timestamp = new Date(event.timestamp);
375
- // Check if date is valid
376
- if (isNaN(timestamp.getTime())) {
377
- console.warn('ActivityTree: Invalid timestamp, using current time:', event.timestamp);
378
- timestamp = new Date();
379
- }
380
- } else {
381
- console.warn('ActivityTree: No timestamp found, using current time');
382
- timestamp = new Date();
383
- }
384
-
385
- // Get session ID from event - this should match the authoritative sessions
386
- const sessionId = event.session_id || event.data?.session_id;
387
-
388
- // Skip events without session ID - they can't be properly categorized
389
- if (!sessionId) {
390
- console.log(`ActivityTree: Skipping event without session_id: ${eventType}`);
391
- return;
392
- }
393
-
394
- // Find the session - it should already exist from authoritative sessions
395
- if (!this.sessions.has(sessionId)) {
396
- console.warn(`ActivityTree: Session ${sessionId} not found in authoritative sessions - skipping event`);
397
- return;
398
- }
399
-
400
- const session = this.sessions.get(sessionId);
401
-
402
- switch (eventType) {
403
- case 'Start':
404
- // New PM session started
405
- this.currentSession = session;
406
- break;
407
- case 'user_prompt':
408
- this.processUserInstruction(event, session);
409
- break;
410
- case 'TodoWrite':
411
- // TodoWrite is now handled as a tool in 'tool_use' events
412
- // Skip separate TodoWrite processing to avoid duplication
413
- break;
414
- case 'SubagentStart':
415
- this.processSubagentStart(event, session);
416
- break;
417
- case 'SubagentStop':
418
- this.processSubagentStop(event, session);
419
- break;
420
- case 'PreToolUse':
421
- this.processToolUse(event, session);
422
- break;
423
- case 'PostToolUse':
424
- this.updateToolStatus(event, session, 'completed');
425
- break;
426
- }
427
-
428
- this.updateStats();
429
- }
430
-
431
- /**
432
- * Get event type from event data
433
- */
434
- getEventType(event) {
435
- if (event.hook_event_name) {
436
- return event.hook_event_name;
437
- }
438
-
439
- if (event.type === 'hook' && event.subtype) {
440
- const mapping = {
441
- 'pre_tool': 'PreToolUse',
442
- 'post_tool': 'PostToolUse',
443
- 'subagent_start': 'SubagentStart',
444
- 'subagent_stop': 'SubagentStop',
445
- 'todo_write': 'TodoWrite'
446
- };
447
- return mapping[event.subtype];
448
- }
449
-
450
- if (event.type === 'todo' && event.subtype === 'updated') {
451
- return 'TodoWrite';
452
- }
453
-
454
- if (event.type === 'subagent') {
455
- if (event.subtype === 'started') return 'SubagentStart';
456
- if (event.subtype === 'stopped') return 'SubagentStop';
457
- }
458
-
459
- if (event.type === 'start') {
460
- return 'Start';
461
- }
462
-
463
- if (event.type === 'user_prompt' || event.subtype === 'user_prompt') {
464
- return 'user_prompt';
465
- }
466
-
467
- return null;
468
- }
469
-
470
- // getSessionId method removed - now using authoritative session IDs directly from socket client
471
-
472
- /**
473
- * Process user instruction/prompt event
474
- */
475
- processUserInstruction(event, session) {
476
- const promptText = event.prompt_text || event.data?.prompt_text || event.prompt || '';
477
- if (!promptText) return;
478
-
479
- const instruction = {
480
- id: `instruction-${session.id}-${Date.now()}`,
481
- text: promptText,
482
- preview: promptText.length > 100 ? promptText.substring(0, 100) + '...' : promptText,
483
- timestamp: event.timestamp || new Date().toISOString(),
484
- type: 'user_instruction'
485
- };
486
-
487
- // NEW USER PROMPT: Only collapse agents if we have existing ones
488
- // Don't clear - we want to keep the history!
489
- if (session.agents.size > 0) {
490
- console.log('ActivityTree: New user prompt detected, collapsing previous agents');
491
-
492
- // Mark all existing agents as completed (not active)
493
- for (let agent of session.agents.values()) {
494
- if (agent.status === 'active') {
495
- agent.status = 'completed';
496
- }
497
- // Collapse all existing agents
498
- this.expandedAgents.delete(agent.id);
499
- }
500
- }
501
-
502
- // Reset current active agent for new work
503
- session.currentActiveAgent = null;
504
-
505
- // Add to session's user instructions
506
- session.userInstructions.push(instruction);
507
-
508
- // Keep only last 5 instructions to prevent memory bloat
509
- if (session.userInstructions.length > 5) {
510
- session.userInstructions = session.userInstructions.slice(-5);
511
- }
512
- }
513
-
514
- /**
515
- * Process TodoWrite event - attach TODOs to session and active agent
516
- */
517
- processTodoWrite(event, session) {
518
- let todos = event.todos || event.data?.todos || event.data || [];
519
-
520
- if (todos && typeof todos === 'object' && todos.todos) {
521
- todos = todos.todos;
522
- }
523
-
524
- if (!Array.isArray(todos) || todos.length === 0) {
525
- return;
526
- }
527
-
528
- // Update session's current todos for latest state tracking
529
- session.currentTodos = todos.map(todo => ({
530
- content: todo.content,
531
- activeForm: todo.activeForm,
532
- status: todo.status,
533
- timestamp: event.timestamp
534
- }));
535
-
536
- // Find the appropriate agent to attach this TodoWrite to
537
- let targetAgent = session.currentActiveAgent;
538
-
539
- if (!targetAgent) {
540
- // Fall back to most recent active agent
541
- const activeAgents = this.getAllAgents(session)
542
- .filter(agent => agent.status === 'active' || agent.status === 'in_progress')
543
- .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
544
-
545
- if (activeAgents.length > 0) {
546
- targetAgent = activeAgents[0];
547
- } else {
548
- // If no active agents, check if this is PM-level
549
- const allAgents = this.getAllAgents(session);
550
- const pmAgent = allAgents.find(a => a.isPM);
551
- if (pmAgent) {
552
- targetAgent = pmAgent;
553
- } else if (allAgents.length > 0) {
554
- targetAgent = allAgents[0];
555
- }
556
- }
557
- }
558
-
559
- // Attach or update TodoWrite for the agent
560
- if (targetAgent) {
561
- if (!targetAgent.todoWritesMap) {
562
- targetAgent.todoWritesMap = new Map();
563
- }
564
- if (!targetAgent.todoWrites) {
565
- targetAgent.todoWrites = [];
566
- }
567
-
568
- // Check if we already have a TodoWrite instance
569
- const existingTodoWrite = targetAgent.todoWritesMap.get('TodoWrite');
570
-
571
- if (existingTodoWrite) {
572
- // Update existing TodoWrite instance
573
- existingTodoWrite.todos = todos;
574
- existingTodoWrite.timestamp = event.timestamp;
575
- existingTodoWrite.updateCount = (existingTodoWrite.updateCount || 1) + 1;
576
- } else {
577
- // Create new TodoWrite instance
578
- const todoWriteInstance = {
579
- id: `todowrite-${targetAgent.id}-${Date.now()}`,
580
- name: 'TodoWrite',
581
- type: 'todowrite',
582
- icon: '📝',
583
- timestamp: event.timestamp,
584
- status: 'completed',
585
- todos: todos,
586
- params: {
587
- todos: todos
588
- },
589
- updateCount: 1
590
- };
591
-
592
- targetAgent.todoWritesMap.set('TodoWrite', todoWriteInstance);
593
- targetAgent.todoWrites = [todoWriteInstance]; // Keep single instance
594
- }
595
-
596
- // Update agent's current todos for display when collapsed
597
- targetAgent.currentTodos = todos;
598
- } else {
599
- // No agent found, attach to session level
600
- if (!session.todoWrites) {
601
- session.todoWrites = [];
602
- }
603
- if (!session.todoWritesMap) {
604
- session.todoWritesMap = new Map();
605
- }
606
-
607
- const existingTodoWrite = session.todoWritesMap.get('TodoWrite');
608
- if (existingTodoWrite) {
609
- existingTodoWrite.todos = todos;
610
- existingTodoWrite.timestamp = event.timestamp;
611
- existingTodoWrite.updateCount = (existingTodoWrite.updateCount || 1) + 1;
612
- } else {
613
- const todoWriteInstance = {
614
- id: `todowrite-session-${Date.now()}`,
615
- name: 'TodoWrite',
616
- type: 'todowrite',
617
- icon: '📝',
618
- timestamp: event.timestamp,
619
- status: 'completed',
620
- todos: todos,
621
- updateCount: 1
622
- };
623
- session.todoWritesMap.set('TodoWrite', todoWriteInstance);
624
- session.todoWrites = [todoWriteInstance];
625
- }
626
- }
627
- }
628
-
629
- /**
630
- * Process SubagentStart event
631
- */
632
- processSubagentStart(event, session) {
633
- const agentName = event.agent_name || event.data?.agent_name || event.data?.agent_type || event.agent_type || event.agent || 'unknown';
634
- const agentSessionId = event.session_id || event.data?.session_id;
635
- const parentAgent = event.parent_agent || event.data?.parent_agent;
636
-
637
- // Use a composite key based on agent name and session to find existing instances
638
- // This ensures we track unique agent instances per session
639
- const agentKey = `${agentName}-${agentSessionId || 'no-session'}`;
640
-
641
- // Check if this exact agent already exists (same name and session)
642
- let existingAgent = null;
643
- const allAgents = this.getAllAgents(session);
644
- existingAgent = allAgents.find(a =>
645
- a.name === agentName &&
646
- a.sessionId === agentSessionId &&
647
- a.status === 'active' // Only reuse if still active
648
- );
649
-
650
- let agent;
651
- if (existingAgent) {
652
- // Update existing active agent
653
- agent = existingAgent;
654
- agent.timestamp = event.timestamp;
655
- agent.instanceCount = (agent.instanceCount || 1) + 1;
656
- // Auto-expand the active agent
657
- this.expandedAgents.add(agent.id);
658
- } else {
659
- // Create new agent instance for first occurrence
660
- const agentId = `agent-${agentKey}-${Date.now()}`;
661
- agent = {
662
- id: agentId,
663
- name: agentName,
664
- type: 'agent',
665
- icon: this.getAgentIcon(agentName),
666
- timestamp: event.timestamp,
667
- status: 'active',
668
- tools: [],
669
- subagents: new Map(), // Store nested subagents
670
- sessionId: agentSessionId,
671
- parentAgent: parentAgent,
672
- isPM: agentName.toLowerCase() === 'pm' || agentName.toLowerCase().includes('project manager'),
673
- instanceCount: 1,
674
- toolsMap: new Map() // Track unique tools by name
675
- };
676
-
677
- // If this is a subagent, nest it under the parent agent
678
- if (parentAgent) {
679
- // Find the parent agent in the session
680
- let parent = null;
681
- for (let [id, ag] of session.agents.entries()) {
682
- if (ag.sessionId === parentAgent || ag.name === parentAgent) {
683
- parent = ag;
684
- break;
685
- }
686
- }
687
-
688
- if (parent) {
689
- // Add as nested subagent
690
- if (!parent.subagents) {
691
- parent.subagents = new Map();
692
- }
693
- parent.subagents.set(agent.id, agent);
694
- } else {
695
- // No parent found, add to session level
696
- session.agents.set(agent.id, agent);
697
- }
698
- } else {
699
- // Top-level agent, add to session
700
- session.agents.set(agent.id, agent);
701
- }
702
-
703
- // Auto-expand new agents
704
- this.expandedAgents.add(agent.id);
705
- }
706
-
707
- // Track the currently active agent for tool/todo association
708
- session.currentActiveAgent = agent;
709
- }
710
-
711
- /**
712
- * Process SubagentStop event
713
- */
714
- processSubagentStop(event, session) {
715
- const agentSessionId = event.session_id || event.data?.session_id;
716
-
717
- // Find and mark agent as completed
718
- if (agentSessionId && session.agents.has(agentSessionId)) {
719
- const agent = session.agents.get(agentSessionId);
720
- agent.status = 'completed';
721
- }
722
- }
723
-
724
- /**
725
- * Process tool use event
726
- *
727
- * DISPLAY RULES:
728
- * 1. TodoWrite is a privileged tool that ALWAYS appears first under the agent/PM
729
- * 2. Each tool appears only once per unique instance (updated in place)
730
- * 3. Tools are listed in order of creation (after TodoWrite)
731
- * 4. Tool instances are updated with new events as they arrive
732
- */
733
- processToolUse(event, session) {
734
- const toolName = event.tool_name || event.data?.tool_name || event.tool || event.data?.tool || 'unknown';
735
- const params = event.tool_parameters || event.data?.tool_parameters || event.parameters || event.data?.parameters || {};
736
- const agentSessionId = event.session_id || event.data?.session_id;
737
-
738
- // Find the appropriate agent to attach this tool to
739
- let targetAgent = session.currentActiveAgent;
740
-
741
- if (!targetAgent) {
742
- // Fall back to finding by session ID or most recent active
743
- const allAgents = this.getAllAgents(session);
744
- targetAgent = allAgents.find(a => a.sessionId === agentSessionId) ||
745
- allAgents.find(a => a.status === 'active') ||
746
- allAgents[0];
747
- }
748
-
749
- if (targetAgent) {
750
- if (!targetAgent.toolsMap) {
751
- targetAgent.toolsMap = new Map();
752
- }
753
- if (!targetAgent.tools) {
754
- targetAgent.tools = [];
755
- }
756
-
757
- // Check if we already have this tool instance
758
- // Use tool name + params hash for unique identification
759
- const toolKey = this.getToolKey(toolName, params);
760
- let existingTool = targetAgent.toolsMap.get(toolKey);
761
-
762
- if (existingTool) {
763
- // UPDATE RULE: Update existing tool instance in place
764
- existingTool.params = params;
765
- existingTool.timestamp = event.timestamp;
766
- existingTool.status = 'in_progress';
767
- existingTool.eventId = event.id;
768
- existingTool.callCount = (existingTool.callCount || 1) + 1;
769
-
770
- // Update current tool for collapsed display
771
- targetAgent.currentTool = existingTool;
772
- } else {
773
- // CREATE RULE: Create new tool instance
774
- const tool = {
775
- id: `tool-${targetAgent.id}-${toolName}-${Date.now()}`,
776
- name: toolName,
777
- type: 'tool',
778
- icon: this.getToolIcon(toolName),
779
- timestamp: event.timestamp,
780
- status: 'in_progress',
781
- params: params,
782
- eventId: event.id,
783
- callCount: 1,
784
- createdAt: event.timestamp // Track creation order
785
- };
786
-
787
- // Special handling for Task tool (subagent delegation)
788
- if (toolName === 'Task' && params.subagent_type) {
789
- tool.isSubagentTask = true;
790
- tool.subagentType = params.subagent_type;
791
- }
792
-
793
- targetAgent.toolsMap.set(toolKey, tool);
794
-
795
- // ORDERING RULE: TodoWrite always goes first, others in creation order
796
- if (toolName === 'TodoWrite') {
797
- // Insert TodoWrite at the beginning
798
- targetAgent.tools.unshift(tool);
799
- } else {
800
- // Append other tools in creation order
801
- targetAgent.tools.push(tool);
802
- }
803
-
804
- targetAgent.currentTool = tool;
805
- }
806
- } else {
807
- // No agent found, attach to session (PM level)
808
- // PM RULE: Same display rules apply - TodoWrite first, others in creation order
809
- if (!session.tools) {
810
- session.tools = [];
811
- }
812
- if (!session.toolsMap) {
813
- session.toolsMap = new Map();
814
- }
815
-
816
- const toolKey = this.getToolKey(toolName, params);
817
- let existingTool = session.toolsMap.get(toolKey);
818
-
819
- if (existingTool) {
820
- // UPDATE RULE: Update existing tool instance in place
821
- existingTool.params = params;
822
- existingTool.timestamp = event.timestamp;
823
- existingTool.status = 'in_progress';
824
- existingTool.eventId = event.id;
825
- existingTool.callCount = (existingTool.callCount || 1) + 1;
826
- session.currentTool = existingTool;
827
- } else {
828
- const tool = {
829
- id: `tool-session-${toolName}-${Date.now()}`,
830
- name: toolName,
831
- type: 'tool',
832
- icon: this.getToolIcon(toolName),
833
- timestamp: event.timestamp,
834
- status: 'in_progress',
835
- params: params,
836
- eventId: event.id,
837
- callCount: 1,
838
- createdAt: event.timestamp // Track creation order
839
- };
840
-
841
- session.toolsMap.set(toolKey, tool);
842
-
843
- // ORDERING RULE: TodoWrite always goes first for PM too
844
- if (toolName === 'TodoWrite') {
845
- session.tools.unshift(tool);
846
- } else {
847
- session.tools.push(tool);
848
- }
849
-
850
- session.currentTool = tool;
851
- }
852
- }
853
- }
854
-
855
- /**
856
- * Generate unique key for tool instance identification
857
- * Tools are unique per name + certain parameter combinations
858
- */
859
- getToolKey(toolName, params) {
860
- // For TodoWrite, we want ONE instance per agent/PM that updates in place
861
- // So we use just the tool name as the key
862
- if (toolName === 'TodoWrite') {
863
- return 'TodoWrite'; // Single instance per agent/PM
864
- }
865
-
866
- // For other tools, we generally want one instance per tool type
867
- // that gets updated with each call (not creating new instances)
868
- let key = toolName;
869
-
870
- // Only add distinguishing params if we need multiple instances
871
- // For example, multiple files being edited simultaneously
872
- if (toolName === 'Edit' || toolName === 'Write' || toolName === 'Read') {
873
- if (params.file_path) {
874
- key += `-${params.file_path}`;
875
- }
876
- }
877
-
878
- // For search tools, we might want separate instances for different searches
879
- if ((toolName === 'Grep' || toolName === 'Glob') && params.pattern) {
880
- // Only add pattern if significantly different
881
- key += `-${params.pattern.substring(0, 20)}`;
882
- }
883
-
884
- // Most tools should have a single instance that updates
885
- // This prevents the tool list from growing unbounded
886
- return key;
887
- }
888
-
889
- /**
890
- * Update tool status after completion
891
- */
892
- updateToolStatus(event, session, status) {
893
- const toolName = event.tool_name || event.data?.tool_name || event.tool || 'unknown';
894
- const params = event.tool_parameters || event.data?.tool_parameters || event.parameters || event.data?.parameters || {};
895
- const agentSessionId = event.session_id || event.data?.session_id;
896
-
897
- // Generate the same key we used to store the tool
898
- const toolKey = this.getToolKey(toolName, params);
899
-
900
- // Find the appropriate agent
901
- let targetAgent = session.currentActiveAgent;
902
-
903
- if (!targetAgent) {
904
- const allAgents = this.getAllAgents(session);
905
- targetAgent = allAgents.find(a => a.sessionId === agentSessionId) ||
906
- allAgents.find(a => a.status === 'active');
907
- }
908
-
909
- if (targetAgent && targetAgent.toolsMap) {
910
- const tool = targetAgent.toolsMap.get(toolKey);
911
- if (tool) {
912
- tool.status = status;
913
- tool.completedAt = event.timestamp;
914
- if (event.data?.result || event.result) {
915
- tool.result = event.data?.result || event.result;
916
- }
917
- if (event.data?.duration_ms) {
918
- tool.duration = event.data.duration_ms;
919
- }
920
- return;
921
- }
922
- }
923
-
924
- // Check session-level tools
925
- if (session.toolsMap) {
926
- const tool = session.toolsMap.get(toolKey);
927
- if (tool) {
928
- tool.status = status;
929
- tool.completedAt = event.timestamp;
930
- if (event.data?.result || event.result) {
931
- tool.result = event.data?.result || event.result;
932
- }
933
- if (event.data?.duration_ms) {
934
- tool.duration = event.data.duration_ms;
935
- }
936
- return;
937
- }
938
- }
939
-
940
- console.log(`ActivityTree: Could not find tool to update status for ${toolName} with key ${toolKey} (event ${event.id})`);
941
- }
942
-
943
- /**
944
- * Render the linear tree view
945
- */
946
- renderTree() {
947
- const treeContainer = document.getElementById('linear-tree');
948
- if (!treeContainer) return;
949
-
950
- // Clear tree
951
- treeContainer.innerHTML = '';
952
-
953
- // Add sessions directly (no project root)
954
- const sortedSessions = Array.from(this.sessions.values())
955
- .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
956
-
957
- for (let session of sortedSessions) {
958
- if (this.selectedSessionFilter !== 'all' && this.selectedSessionFilter !== session.id) {
959
- continue;
960
- }
961
-
962
- const sessionElement = this.createSessionElement(session);
963
- treeContainer.appendChild(sessionElement);
964
- }
965
-
966
- // Session filtering is now handled by the main session selector via event listeners
967
- }
968
-
969
-
970
- /**
971
- * Create session element
972
- */
973
- createSessionElement(session) {
974
- const isExpanded = this.expandedSessions.has(session.id) || session.expanded;
975
-
976
- // Ensure timestamp is valid and format it consistently
977
- let sessionTime;
978
- try {
979
- const sessionDate = session.timestamp instanceof Date ? session.timestamp : new Date(session.timestamp);
980
- if (isNaN(sessionDate.getTime())) {
981
- sessionTime = 'Invalid Date';
982
- console.warn('ActivityTree: Invalid session timestamp:', session.timestamp);
983
- } else {
984
- sessionTime = sessionDate.toLocaleString();
985
- }
986
- } catch (error) {
987
- sessionTime = 'Invalid Date';
988
- console.error('ActivityTree: Error formatting session timestamp:', error, session.timestamp);
989
- }
990
-
991
- const element = document.createElement('div');
992
- element.className = 'tree-node session';
993
- element.dataset.sessionId = session.id;
994
-
995
- const expandIcon = isExpanded ? '▼' : '▶';
996
- // Count ALL agents including nested ones
997
- const agentCount = this.getAllAgents(session).length;
998
- const todoCount = session.currentTodos ? session.currentTodos.length : 0;
999
- const instructionCount = session.userInstructions ? session.userInstructions.length : 0;
1000
-
1001
- console.log(`ActivityTree: Rendering session ${session.id}: ${agentCount} agents, ${instructionCount} instructions, ${todoCount} todos at ${sessionTime}`);
1002
-
1003
- element.innerHTML = `
1004
- <div class="tree-node-content" onclick="window.activityTreeInstance.toggleSession('${session.id}')">
1005
- <span class="tree-expand-icon">${expandIcon}</span>
1006
- <span class="tree-icon">🎯</span>
1007
- <span class="tree-label">PM Session</span>
1008
- <span class="tree-meta">${sessionTime} • ${agentCount} agent(s) • ${instructionCount} instruction(s) • ${todoCount} todo(s)</span>
1009
- </div>
1010
- <div class="tree-children" style="display: ${isExpanded ? 'block' : 'none'}">
1011
- ${this.renderSessionContent(session)}
1012
- </div>
1013
- `;
1014
-
1015
- return element;
1016
- }
1017
-
1018
- /**
1019
- * Render session content (user instructions, todos, agents, tools)
1020
- *
1021
- * PM DISPLAY RULES (documented inline):
1022
- * 1. User instructions appear first (context)
1023
- * 2. PM-level tools follow the same rules as agent tools:
1024
- * - TodoWrite is privileged and appears first
1025
- * - Other tools appear in creation order
1026
- * - Each unique instance is updated in place
1027
- * 3. Agents appear after PM tools
1028
- */
1029
- renderSessionContent(session) {
1030
- let html = '';
1031
-
1032
- // Render user instructions first
1033
- if (session.userInstructions && session.userInstructions.length > 0) {
1034
- for (let instruction of session.userInstructions.slice(-3)) { // Show last 3 instructions
1035
- html += this.renderUserInstructionElement(instruction, 1);
1036
- }
1037
- }
1038
-
1039
- // PM TOOL DISPLAY RULES:
1040
- // Render PM-level tools (TodoWrite first, then others in creation order)
1041
- // The session.tools array is already properly ordered by processToolUse
1042
- if (session.tools && session.tools.length > 0) {
1043
- for (let tool of session.tools) {
1044
- html += this.renderToolElement(tool, 1);
1045
- }
1046
- }
1047
-
1048
- // Render agents (they will have their own TodoWrite at the top)
1049
- const agents = Array.from(session.agents.values())
1050
- .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));
1051
-
1052
- for (let agent of agents) {
1053
- html += this.renderAgentElement(agent, 1);
1054
- }
1055
-
1056
- return html;
1057
- }
1058
-
1059
- /**
1060
- * Render user instruction element
1061
- */
1062
- renderUserInstructionElement(instruction, level) {
1063
- const isSelected = this.selectedItem && this.selectedItem.type === 'instruction' && this.selectedItem.data.id === instruction.id;
1064
- const selectedClass = isSelected ? 'selected' : '';
1065
-
1066
- return `
1067
- <div class="tree-node user-instruction ${selectedClass}" data-level="${level}">
1068
- <div class="tree-node-content">
1069
- <span class="tree-expand-icon"></span>
1070
- <span class="tree-icon">💬</span>
1071
- <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(instruction)}, 'instruction', event)">User: "${this.escapeHtml(instruction.preview)}"</span>
1072
- <span class="tree-status status-active">instruction</span>
1073
- </div>
1074
- </div>
1075
- `;
1076
- }
1077
-
1078
- /**
1079
- * Render TODO checklist element
1080
- */
1081
- renderTodoChecklistElement(todos, level) {
1082
- const checklistId = `checklist-${Date.now()}`;
1083
- const isExpanded = this.expandedTools.has(checklistId) !== false; // Default to expanded
1084
- const expandIcon = isExpanded ? '▼' : '▶';
1085
-
1086
- // Calculate status summary
1087
- let completedCount = 0;
1088
- let inProgressCount = 0;
1089
- let pendingCount = 0;
1090
-
1091
- todos.forEach(todo => {
1092
- if (todo.status === 'completed') completedCount++;
1093
- else if (todo.status === 'in_progress') inProgressCount++;
1094
- else pendingCount++;
1095
- });
1096
-
1097
- let statusSummary = '';
1098
- if (inProgressCount > 0) {
1099
- statusSummary = `${inProgressCount} in progress, ${completedCount} completed`;
1100
- } else if (completedCount === todos.length && todos.length > 0) {
1101
- statusSummary = `All ${todos.length} completed`;
1102
- } else {
1103
- statusSummary = `${todos.length} todo(s)`;
1104
- }
1105
-
1106
- let html = `
1107
- <div class="tree-node todo-checklist" data-level="${level}">
1108
- <div class="tree-node-content">
1109
- <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${checklistId}'); event.stopPropagation();">${expandIcon}</span>
1110
- <span class="tree-icon">☑️</span>
1111
- <span class="tree-label">TODOs</span>
1112
- <span class="tree-params">${statusSummary}</span>
1113
- <span class="tree-status status-active">checklist</span>
1114
- </div>
1115
- `;
1116
-
1117
- // Show expanded todo items if expanded
1118
- if (isExpanded) {
1119
- html += '<div class="tree-children">';
1120
- for (let todo of todos) {
1121
- const statusIcon = this.getCheckboxIcon(todo.status);
1122
- const statusClass = `status-${todo.status}`;
1123
- const displayText = todo.status === 'in_progress' ? todo.activeForm : todo.content;
1124
-
1125
- html += `
1126
- <div class="tree-node todo-item ${statusClass}" data-level="${level + 1}">
1127
- <div class="tree-node-content">
1128
- <span class="tree-expand-icon"></span>
1129
- <span class="tree-icon">${statusIcon}</span>
1130
- <span class="tree-label">${this.escapeHtml(displayText)}</span>
1131
- <span class="tree-status ${statusClass}">${todo.status.replace('_', ' ')}</span>
1132
- </div>
1133
- </div>
1134
- `;
1135
- }
1136
- html += '</div>';
1137
- }
1138
-
1139
- html += '</div>';
1140
- return html;
1141
- }
1142
-
1143
- /**
1144
- * Render agent element with proper nesting
1145
- */
1146
- renderAgentElement(agent, level) {
1147
- const statusClass = agent.status === 'active' ? 'status-active' : 'status-completed';
1148
- const isExpanded = this.expandedAgents.has(agent.id);
1149
- const hasTools = agent.tools && agent.tools.length > 0;
1150
- const hasSubagents = agent.subagents && agent.subagents.size > 0;
1151
- const hasContent = hasTools || hasSubagents;
1152
- const isSelected = this.selectedItem && this.selectedItem.type === 'agent' && this.selectedItem.data.id === agent.id;
1153
-
1154
- const expandIcon = hasContent ? (isExpanded ? '▼' : '▶') : '';
1155
- const selectedClass = isSelected ? 'selected' : '';
1156
-
1157
- // Add instance count if called multiple times
1158
- const instanceIndicator = agent.instanceCount > 1 ? ` (${agent.instanceCount}x)` : '';
1159
-
1160
- // Build status display for collapsed state
1161
- let collapsedStatus = '';
1162
- if (!isExpanded && hasContent) {
1163
- const parts = [];
1164
- if (agent.currentTodos && agent.currentTodos.length > 0) {
1165
- const inProgress = agent.currentTodos.find(t => t.status === 'in_progress');
1166
- if (inProgress) {
1167
- parts.push(`📝 ${inProgress.activeForm || inProgress.content}`);
1168
- }
1169
- }
1170
- if (agent.currentTool) {
1171
- parts.push(`${agent.currentTool.icon} ${agent.currentTool.name}`);
1172
- }
1173
- if (parts.length > 0) {
1174
- collapsedStatus = ` • ${parts.join(' • ')}`;
1175
- }
1176
- }
1177
-
1178
- let html = `
1179
- <div class="tree-node agent ${statusClass} ${selectedClass}" data-level="${level}">
1180
- <div class="tree-node-content">
1181
- ${expandIcon ? `<span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleAgent('${agent.id}'); event.stopPropagation();">${expandIcon}</span>` : '<span class="tree-expand-icon"></span>'}
1182
- <span class="tree-icon">${agent.icon}</span>
1183
- <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(agent)}, 'agent', event)">${agent.name}${instanceIndicator}${collapsedStatus}</span>
1184
- <span class="tree-status ${statusClass}">${agent.status}</span>
1185
- </div>
1186
- `;
1187
-
1188
- // Render nested content when expanded
1189
- if (hasContent && isExpanded) {
1190
- html += '<div class="tree-children">';
1191
-
1192
- // DISPLAY ORDER RULES (documented inline):
1193
- // 1. TodoWrite is a privileged tool - ALWAYS appears first
1194
- // 2. Each tool appears only once per unique instance
1195
- // 3. Tools are displayed in order of creation (after TodoWrite)
1196
- // 4. Tool instances are updated in place as new events arrive
1197
-
1198
- // Render all tools in their proper order
1199
- // The tools array is already ordered: TodoWrite first, then others by creation
1200
- if (hasTools) {
1201
- for (let tool of agent.tools) {
1202
- html += this.renderToolElement(tool, level + 1);
1203
- }
1204
- }
1205
-
1206
- // Then render subagents (they will have their own TodoWrite at the top)
1207
- if (hasSubagents) {
1208
- const subagents = Array.from(agent.subagents.values());
1209
- for (let subagent of subagents) {
1210
- html += this.renderAgentElement(subagent, level + 1);
1211
- }
1212
- }
1213
-
1214
- html += '</div>';
1215
- }
1216
-
1217
- html += '</div>';
1218
- return html;
1219
- }
1220
-
1221
- /**
1222
- * Render tool element (non-expandable, clickable to show data)
1223
- */
1224
- renderToolElement(tool, level) {
1225
- const statusClass = `status-${tool.status}`;
1226
- const params = this.getToolParams(tool);
1227
- const isSelected = this.selectedItem && this.selectedItem.type === 'tool' && this.selectedItem.data.id === tool.id;
1228
- const selectedClass = isSelected ? 'selected' : '';
1229
-
1230
- // Add visual status indicators
1231
- const statusIcon = this.getToolStatusIcon(tool.status);
1232
- const statusLabel = this.getToolStatusLabel(tool.status);
1233
-
1234
- // Add call count if more than 1
1235
- const callIndicator = tool.callCount > 1 ? ` (${tool.callCount} calls)` : '';
1236
-
1237
- let html = `
1238
- <div class="tree-node tool ${statusClass} ${selectedClass}" data-level="${level}">
1239
- <div class="tree-node-content">
1240
- <span class="tree-expand-icon"></span>
1241
- <span class="tree-icon">${tool.icon}</span>
1242
- <span class="tree-status-icon">${statusIcon}</span>
1243
- <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(tool)}, 'tool', event)">${tool.name}${callIndicator}</span>
1244
- <span class="tree-params">${params}</span>
1245
- <span class="tree-status ${statusClass}">${statusLabel}</span>
1246
- </div>
1247
- </div>
1248
- `;
1249
-
1250
- return html;
1251
- }
1252
-
1253
- /**
1254
- * Get formatted tool parameters
1255
- */
1256
- getToolParams(tool) {
1257
- if (!tool.params) return '';
1258
-
1259
- if (tool.name === 'Read' && tool.params.file_path) {
1260
- return tool.params.file_path;
1261
- }
1262
- if (tool.name === 'Edit' && tool.params.file_path) {
1263
- return tool.params.file_path;
1264
- }
1265
- if (tool.name === 'Write' && tool.params.file_path) {
1266
- return tool.params.file_path;
1267
- }
1268
- if (tool.name === 'Bash' && tool.params.command) {
1269
- const cmd = tool.params.command;
1270
- return cmd.length > 50 ? cmd.substring(0, 50) + '...' : cmd;
1271
- }
1272
- if (tool.name === 'WebFetch' && tool.params.url) {
1273
- return tool.params.url;
1274
- }
1275
-
1276
- return '';
1277
- }
1278
-
1279
- /**
1280
- * Get status icon for todo status
1281
- */
1282
- getStatusIcon(status) {
1283
- const icons = {
1284
- 'pending': '⏸️',
1285
- 'in_progress': '🔄',
1286
- 'completed': '✅'
1287
- };
1288
- return icons[status] || '❓';
1289
- }
1290
-
1291
- /**
1292
- * Get checkbox icon for todo checklist items
1293
- */
1294
- getCheckboxIcon(status) {
1295
- const icons = {
1296
- 'pending': '⏳',
1297
- 'in_progress': '🔄',
1298
- 'completed': '✅'
1299
- };
1300
- return icons[status] || '❓';
1301
- }
1302
-
1303
- /**
1304
- * Get agent icon based on name
1305
- */
1306
- getAgentIcon(agentName) {
1307
- const icons = {
1308
- 'engineer': '👷',
1309
- 'research': '🔬',
1310
- 'qa': '🧪',
1311
- 'ops': '⚙️',
1312
- 'pm': '📊',
1313
- 'architect': '🏗️',
1314
- 'project manager': '📊'
1315
- };
1316
- return icons[agentName.toLowerCase()] || '🤖';
1317
- }
1318
-
1319
- /**
1320
- * Helper to get all agents including nested subagents
1321
- */
1322
- getAllAgents(session) {
1323
- const agents = [];
1324
-
1325
- const collectAgents = (agentMap) => {
1326
- if (!agentMap) return;
1327
-
1328
- for (let agent of agentMap.values()) {
1329
- agents.push(agent);
1330
- if (agent.subagents && agent.subagents.size > 0) {
1331
- collectAgents(agent.subagents);
1332
- }
1333
- }
1334
- };
1335
-
1336
- collectAgents(session.agents);
1337
- return agents;
1338
- }
1339
-
1340
- /**
1341
- * Render TodoWrite element
1342
- */
1343
- renderTodoWriteElement(todoWrite, level) {
1344
- const todoWriteId = todoWrite.id;
1345
- const isExpanded = this.expandedTools.has(todoWriteId);
1346
- const expandIcon = isExpanded ? '▼' : '▶';
1347
- const todos = todoWrite.todos || [];
1348
-
1349
- // Calculate status summary
1350
- let completedCount = 0;
1351
- let inProgressCount = 0;
1352
- let pendingCount = 0;
1353
-
1354
- todos.forEach(todo => {
1355
- if (todo.status === 'completed') completedCount++;
1356
- else if (todo.status === 'in_progress') inProgressCount++;
1357
- else pendingCount++;
1358
- });
1359
-
1360
- // Find current in-progress todo for highlighting
1361
- const currentTodo = todos.find(t => t.status === 'in_progress');
1362
- const currentIndicator = currentTodo ? ` • 🔄 ${currentTodo.activeForm || currentTodo.content}` : '';
1363
-
1364
- let statusSummary = '';
1365
- if (inProgressCount > 0) {
1366
- statusSummary = `${inProgressCount} in progress, ${completedCount}/${todos.length} done`;
1367
- } else if (completedCount === todos.length && todos.length > 0) {
1368
- statusSummary = `All ${todos.length} completed ✅`;
1369
- } else {
1370
- statusSummary = `${completedCount}/${todos.length} done`;
1371
- }
1372
-
1373
- // Add update count if more than 1
1374
- const updateIndicator = todoWrite.updateCount > 1 ? ` (${todoWrite.updateCount} updates)` : '';
1375
-
1376
- let html = `
1377
- <div class="tree-node todowrite ${currentTodo ? 'has-active' : ''}" data-level="${level}">
1378
- <div class="tree-node-content">
1379
- <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoWrite('${todoWriteId}'); event.stopPropagation();">${expandIcon}</span>
1380
- <span class="tree-icon">📝</span>
1381
- <span class="tree-label">TodoWrite${updateIndicator}${!isExpanded ? currentIndicator : ''}</span>
1382
- <span class="tree-params">${statusSummary}</span>
1383
- <span class="tree-status status-active">todos</span>
1384
- </div>
1385
- `;
1386
-
1387
- // Show expanded todo items if expanded
1388
- if (isExpanded && todos.length > 0) {
1389
- html += '<div class="tree-children">';
1390
- for (let todo of todos) {
1391
- const statusIcon = this.getCheckboxIcon(todo.status);
1392
- const statusClass = `status-${todo.status}`;
1393
- const displayText = todo.status === 'in_progress' ? todo.activeForm : todo.content;
1394
- const isCurrentTodo = todo === currentTodo;
1395
-
1396
- html += `
1397
- <div class="tree-node todo-item ${statusClass} ${isCurrentTodo ? 'current-active' : ''}" data-level="${level + 1}">
1398
- <div class="tree-node-content">
1399
- <span class="tree-expand-icon"></span>
1400
- <span class="tree-icon">${statusIcon}</span>
1401
- <span class="tree-label">${this.escapeHtml(displayText)}</span>
1402
- <span class="tree-status ${statusClass}">${todo.status.replace('_', ' ')}</span>
1403
- </div>
1404
- </div>
1405
- `;
1406
- }
1407
- html += '</div>';
1408
- }
1409
-
1410
- html += '</div>';
1411
- return html;
1412
- }
1413
-
1414
- /**
1415
- * Toggle TodoWrite expansion
1416
- */
1417
- toggleTodoWrite(todoWriteId) {
1418
- if (this.expandedTools.has(todoWriteId)) {
1419
- this.expandedTools.delete(todoWriteId);
1420
- } else {
1421
- this.expandedTools.add(todoWriteId);
1422
- }
1423
- this.renderTree();
1424
- }
1425
-
1426
- /**
1427
- * Get tool icon based on name
1428
- */
1429
- getToolIcon(toolName) {
1430
- const icons = {
1431
- 'read': '👁️',
1432
- 'write': '✍️',
1433
- 'edit': '✏️',
1434
- 'bash': '💻',
1435
- 'webfetch': '🌐',
1436
- 'grep': '🔍',
1437
- 'glob': '📂',
1438
- 'todowrite': '📝'
1439
- };
1440
- return icons[toolName.toLowerCase()] || '🔧';
1441
- }
1442
-
1443
- /**
1444
- * Get status icon for tool status
1445
- */
1446
- getToolStatusIcon(status) {
1447
- const icons = {
1448
- 'in_progress': '⏳',
1449
- 'completed': '✅',
1450
- 'failed': '❌',
1451
- 'error': '❌',
1452
- 'pending': '⏸️',
1453
- 'active': '🔄'
1454
- };
1455
- return icons[status] || '❓';
1456
- }
1457
-
1458
- /**
1459
- * Get formatted status label for tool
1460
- */
1461
- getToolStatusLabel(status) {
1462
- const labels = {
1463
- 'in_progress': 'in progress',
1464
- 'completed': 'completed',
1465
- 'failed': 'failed',
1466
- 'error': 'error',
1467
- 'pending': 'pending',
1468
- 'active': 'active'
1469
- };
1470
- return labels[status] || status;
1471
- }
1472
-
1473
- /**
1474
- * Toggle session expansion
1475
- */
1476
- toggleSession(sessionId) {
1477
- if (this.expandedSessions.has(sessionId)) {
1478
- this.expandedSessions.delete(sessionId);
1479
- } else {
1480
- this.expandedSessions.add(sessionId);
1481
- }
1482
-
1483
- // Update the session in the data structure
1484
- const session = this.sessions.get(sessionId);
1485
- if (session) {
1486
- session.expanded = this.expandedSessions.has(sessionId);
1487
- }
1488
-
1489
- this.renderTree();
1490
- }
1491
-
1492
- /**
1493
- * Expand all sessions
1494
- */
1495
- expandAllSessions() {
1496
- for (let sessionId of this.sessions.keys()) {
1497
- this.expandedSessions.add(sessionId);
1498
- const session = this.sessions.get(sessionId);
1499
- if (session) session.expanded = true;
1500
- }
1501
- this.renderTree();
1502
- }
1503
-
1504
- /**
1505
- * Collapse all sessions
1506
- */
1507
- collapseAllSessions() {
1508
- this.expandedSessions.clear();
1509
- for (let session of this.sessions.values()) {
1510
- session.expanded = false;
1511
- }
1512
- this.renderTree();
1513
- }
1514
-
1515
-
1516
- /**
1517
- * Update statistics
1518
- */
1519
- updateStats() {
1520
- const totalNodes = this.countTotalNodes();
1521
- const activeNodes = this.countActiveNodes();
1522
- const maxDepth = this.calculateMaxDepth();
1523
-
1524
- const nodeCountEl = document.getElementById('node-count');
1525
- const activeCountEl = document.getElementById('active-count');
1526
- const depthEl = document.getElementById('tree-depth');
1527
-
1528
- if (nodeCountEl) nodeCountEl.textContent = totalNodes;
1529
- if (activeCountEl) activeCountEl.textContent = activeNodes;
1530
- if (depthEl) depthEl.textContent = maxDepth;
1531
-
1532
- console.log(`ActivityTree: Stats updated - Nodes: ${totalNodes}, Active: ${activeNodes}, Depth: ${maxDepth}`);
1533
- }
1534
-
1535
- /**
1536
- * Count total nodes across all sessions
1537
- */
1538
- countTotalNodes() {
1539
- let count = 0; // No project root anymore
1540
- for (let session of this.sessions.values()) {
1541
- count += 1; // Session
1542
- count += session.agents.size; // Agents
1543
-
1544
- // Count user instructions
1545
- if (session.userInstructions) {
1546
- count += session.userInstructions.length;
1547
- }
1548
-
1549
- // Count todos
1550
- if (session.todos) {
1551
- count += session.todos.length;
1552
- }
1553
-
1554
- // Count session-level tools
1555
- if (session.tools) {
1556
- count += session.tools.length;
1557
- }
1558
-
1559
- // Count tools in agents
1560
- for (let agent of session.agents.values()) {
1561
- if (agent.tools) {
1562
- count += agent.tools.length;
1563
- }
1564
- }
1565
- }
1566
- return count;
1567
- }
1568
-
1569
- /**
1570
- * Count active nodes (in progress)
1571
- */
1572
- countActiveNodes() {
1573
- let count = 0;
1574
- for (let session of this.sessions.values()) {
1575
- // Count active session
1576
- if (session.status === 'active') count++;
1577
-
1578
- // Count active todos
1579
- if (session.todos) {
1580
- for (let todo of session.todos) {
1581
- if (todo.status === 'in_progress') count++;
1582
- }
1583
- }
1584
-
1585
- // Count session-level tools
1586
- if (session.tools) {
1587
- for (let tool of session.tools) {
1588
- if (tool.status === 'in_progress') count++;
1589
- }
1590
- }
1591
-
1592
- // Count agents and their tools
1593
- for (let agent of session.agents.values()) {
1594
- if (agent.status === 'active') count++;
1595
- if (agent.tools) {
1596
- for (let tool of agent.tools) {
1597
- if (tool.status === 'in_progress') count++;
1598
- }
1599
- }
1600
- }
1601
- }
1602
- return count;
1603
- }
1604
-
1605
- /**
1606
- * Calculate maximum depth
1607
- */
1608
- calculateMaxDepth() {
1609
- let maxDepth = 0; // No project root anymore
1610
- for (let session of this.sessions.values()) {
1611
- let sessionDepth = 1; // Session level (now root level)
1612
-
1613
- // Check session content (instructions, todos, tools)
1614
- if (session.userInstructions && session.userInstructions.length > 0) {
1615
- sessionDepth = Math.max(sessionDepth, 2); // Instruction level
1616
- }
1617
-
1618
- if (session.todos && session.todos.length > 0) {
1619
- sessionDepth = Math.max(sessionDepth, 3); // Todo checklist -> todo items
1620
- }
1621
-
1622
- if (session.tools && session.tools.length > 0) {
1623
- sessionDepth = Math.max(sessionDepth, 2); // Tool level
1624
- }
1625
-
1626
- // Check agents
1627
- for (let agent of session.agents.values()) {
1628
- if (agent.tools && agent.tools.length > 0) {
1629
- sessionDepth = Math.max(sessionDepth, 3); // Tool level under agents
1630
- }
1631
- }
1632
-
1633
- maxDepth = Math.max(maxDepth, sessionDepth);
1634
- }
1635
- return maxDepth;
1636
- }
1637
-
1638
- /**
1639
- * Toggle agent expansion
1640
- */
1641
- toggleAgent(agentId) {
1642
- if (this.expandedAgents.has(agentId)) {
1643
- this.expandedAgents.delete(agentId);
1644
- } else {
1645
- this.expandedAgents.add(agentId);
1646
- }
1647
- this.renderTree();
1648
- }
1649
-
1650
- /**
1651
- * Toggle tool expansion (deprecated - tools are no longer expandable)
1652
- */
1653
- toggleTool(toolId) {
1654
- // Tools are no longer expandable - this method is kept for compatibility
1655
- console.log('Tool expansion is disabled. Tools now show data in the left pane when clicked.');
1656
- }
1657
-
1658
- /**
1659
- * Toggle TODO checklist expansion
1660
- */
1661
- toggleTodoChecklist(checklistId) {
1662
- if (this.expandedTools.has(checklistId)) {
1663
- this.expandedTools.delete(checklistId);
1664
- } else {
1665
- this.expandedTools.add(checklistId);
1666
- }
1667
- this.renderTree();
1668
- }
1669
-
1670
- /**
1671
- * Render pinned TODOs element under agent
1672
- */
1673
- renderPinnedTodosElement(pinnedTodos, level) {
1674
- const checklistId = `pinned-todos-${Date.now()}`;
1675
- const isExpanded = this.expandedTools.has(checklistId) !== false; // Default to expanded
1676
- const expandIcon = isExpanded ? '▼' : '▶';
1677
- const todos = pinnedTodos.todos || [];
1678
-
1679
- // Calculate status summary
1680
- let completedCount = 0;
1681
- let inProgressCount = 0;
1682
- let pendingCount = 0;
1683
-
1684
- todos.forEach(todo => {
1685
- if (todo.status === 'completed') completedCount++;
1686
- else if (todo.status === 'in_progress') inProgressCount++;
1687
- else pendingCount++;
1688
- });
1689
-
1690
- let statusSummary = '';
1691
- if (inProgressCount > 0) {
1692
- statusSummary = `${inProgressCount} in progress, ${completedCount} completed`;
1693
- } else if (completedCount === todos.length && todos.length > 0) {
1694
- statusSummary = `All ${todos.length} completed`;
1695
- } else {
1696
- statusSummary = `${todos.length} todo(s)`;
1697
- }
1698
-
1699
- let html = `
1700
- <div class="tree-node pinned-todos" data-level="${level}">
1701
- <div class="tree-node-content">
1702
- <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${checklistId}'); event.stopPropagation();">${expandIcon}</span>
1703
- <span class="tree-icon">📌</span>
1704
- <span class="tree-label">Pinned TODOs</span>
1705
- <span class="tree-params">${statusSummary}</span>
1706
- <span class="tree-status status-active">pinned</span>
1707
- </div>
1708
- `;
1709
-
1710
- // Show expanded todo items if expanded
1711
- if (isExpanded) {
1712
- html += '<div class="tree-children">';
1713
- for (let todo of todos) {
1714
- const statusIcon = this.getCheckboxIcon(todo.status);
1715
- const statusClass = `status-${todo.status}`;
1716
- const displayText = todo.status === 'in_progress' ? todo.activeForm : todo.content;
1717
-
1718
- html += `
1719
- <div class="tree-node todo-item ${statusClass}" data-level="${level + 1}">
1720
- <div class="tree-node-content">
1721
- <span class="tree-expand-icon"></span>
1722
- <span class="tree-icon">${statusIcon}</span>
1723
- <span class="tree-label">${this.escapeHtml(displayText)}</span>
1724
- <span class="tree-status ${statusClass}">${todo.status.replace('_', ' ')}</span>
1725
- </div>
1726
- </div>
1727
- `;
1728
- }
1729
- html += '</div>';
1730
- }
1731
-
1732
- html += '</div>';
1733
- return html;
1734
- }
1735
-
1736
- /**
1737
- * Handle item click to show data in left pane
1738
- */
1739
- selectItem(item, itemType, event) {
1740
- // Stop event propagation to prevent expand/collapse when clicking on label
1741
- if (event) {
1742
- event.stopPropagation();
1743
- }
1744
-
1745
- this.selectedItem = { data: item, type: itemType };
1746
- this.displayItemData(item, itemType);
1747
- this.renderTree(); // Re-render to show selection highlight
1748
- }
1749
-
1750
- /**
1751
- * Display item data in left pane using UnifiedDataViewer for consistency with Tools viewer
1752
- */
1753
- displayItemData(item, itemType) {
1754
- // Initialize UnifiedDataViewer if not already available
1755
- if (!this.unifiedViewer) {
1756
- this.unifiedViewer = new UnifiedDataViewer('module-data-content');
1757
- }
1758
-
1759
- // Use the same UnifiedDataViewer as Tools viewer for consistent display
1760
- this.unifiedViewer.display(item, itemType);
1761
-
1762
- // Update module header for consistency
1763
- const moduleHeader = document.querySelector('.module-data-header h5');
1764
- if (moduleHeader) {
1765
- const icons = {
1766
- 'agent': '🤖',
1767
- 'tool': '🔧',
1768
- 'instruction': '💬',
1769
- 'session': '🎯',
1770
- 'todo': '📝'
1771
- };
1772
- const icon = icons[itemType] || '📊';
1773
- const name = item.name || item.agentName || item.tool_name || 'Item';
1774
- moduleHeader.textContent = `${icon} ${itemType}: ${name}`;
1775
- }
1776
- }
1777
-
1778
- // Display methods removed - now using UnifiedDataViewer for consistency
1779
-
1780
- /**
1781
- * Escape HTML for safe display
1782
- */
1783
- escapeHtml(text) {
1784
- const div = document.createElement('div');
1785
- div.textContent = text;
1786
- return div.innerHTML;
1787
- }
1788
-
1789
- /**
1790
- * Reset zoom and pan to initial state
1791
- */
1792
- resetZoom() {
1793
- if (this.svg && this.zoom) {
1794
- this.svg.transition()
1795
- .duration(this.duration)
1796
- .call(this.zoom.transform, d3.zoomIdentity);
1797
- }
1798
- }
1799
-
1800
- /**
1801
- * Escape JSON for safe inclusion in HTML attributes
1802
- */
1803
- escapeJson(obj) {
1804
- return JSON.stringify(obj).replace(/'/g, '&apos;').replace(/"/g, '&quot;');
1805
- }
1806
- }
1807
-
1808
- // Make ActivityTree globally available
1809
- window.ActivityTree = ActivityTree;
1810
-
1811
- // Initialize when the Activity tab is selected
1812
- const setupActivityTreeListeners = () => {
1813
- let activityTree = null;
1814
-
1815
- const initializeActivityTree = () => {
1816
- if (!activityTree) {
1817
- console.log('Creating new Activity Tree instance...');
1818
- activityTree = new ActivityTree();
1819
- window.activityTreeInstance = activityTree;
1820
- window.activityTree = () => activityTree; // For debugging
1821
- }
1822
-
1823
- setTimeout(() => {
1824
- console.log('Attempting to initialize Activity Tree visualization...');
1825
- activityTree.initialize();
1826
- }, 100);
1827
- };
1828
-
1829
- // REMOVED: Conflicting tab click handlers that were interfering with UIStateManager
1830
- // Tab switching is now handled entirely through the 'tabChanged' event listener below
1831
- // This prevents conflicts with the UIStateManager's hash-based navigation system
1832
-
1833
- // Listen for custom tab change events
1834
- document.addEventListener('tabChanged', (e) => {
1835
- if (e.detail && e.detail.newTab === 'activity') {
1836
- console.log('Tab changed to activity, initializing tree...');
1837
- initializeActivityTree();
1838
- if (activityTree) {
1839
- setTimeout(() => {
1840
- activityTree.renderWhenVisible();
1841
- activityTree.forceShow();
1842
- }, 150);
1843
- }
1844
- }
1845
- });
1846
-
1847
- // Check if activity tab is already active on load
1848
- const activeTab = document.querySelector('.tab-button.active');
1849
- if (activeTab && activeTab.getAttribute('data-tab') === 'activity') {
1850
- console.log('Activity tab is active on load, initializing tree...');
1851
- initializeActivityTree();
1852
- }
1853
-
1854
- const activityPanel = document.getElementById('activity-tab');
1855
- if (activityPanel && activityPanel.classList.contains('active')) {
1856
- console.log('Activity panel is active on load, initializing tree...');
1857
- if (!activityTree) {
1858
- initializeActivityTree();
1859
- }
1860
- }
1861
- };
1862
-
1863
- // Set up listeners when DOM is ready
1864
- if (document.readyState === 'loading') {
1865
- document.addEventListener('DOMContentLoaded', setupActivityTreeListeners);
1866
- } else {
1867
- setupActivityTreeListeners();
1868
- }
1869
-
1870
- export { ActivityTree };
1871
- export default ActivityTree;