claude-mpm 4.25.10__py3-none-any.whl → 5.1.8__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 (507) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/PM_INSTRUCTIONS.md +1055 -2230
  4. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  5. claude_mpm/agents/WORKFLOW.md +4 -4
  6. claude_mpm/agents/__init__.py +6 -0
  7. claude_mpm/agents/agent_loader.py +1 -4
  8. claude_mpm/agents/base_agent_loader.py +10 -35
  9. claude_mpm/agents/templates/{circuit_breakers.md → circuit-breakers.md} +576 -66
  10. claude_mpm/agents/templates/context-management-examples.md +544 -0
  11. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  12. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  13. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  14. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  15. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  16. claude_mpm/cli/__init__.py +28 -3
  17. claude_mpm/cli/commands/__init__.py +2 -0
  18. claude_mpm/cli/commands/agent_source.py +774 -0
  19. claude_mpm/cli/commands/agent_state_manager.py +188 -30
  20. claude_mpm/cli/commands/agents.py +959 -36
  21. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  22. claude_mpm/cli/commands/agents_discover.py +338 -0
  23. claude_mpm/cli/commands/auto_configure.py +537 -239
  24. claude_mpm/cli/commands/config.py +7 -4
  25. claude_mpm/cli/commands/configure.py +924 -45
  26. claude_mpm/cli/commands/configure_navigation.py +63 -46
  27. claude_mpm/cli/commands/doctor.py +10 -2
  28. claude_mpm/cli/commands/local_deploy.py +1 -4
  29. claude_mpm/cli/commands/postmortem.py +401 -0
  30. claude_mpm/cli/commands/run.py +1 -39
  31. claude_mpm/cli/commands/skill_source.py +694 -0
  32. claude_mpm/cli/commands/skills.py +322 -19
  33. claude_mpm/cli/executor.py +22 -3
  34. claude_mpm/cli/interactive/agent_wizard.py +1028 -43
  35. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  36. claude_mpm/cli/parsers/agents_parser.py +256 -4
  37. claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
  38. claude_mpm/cli/parsers/base_parser.py +25 -0
  39. claude_mpm/cli/parsers/config_parser.py +96 -43
  40. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  41. claude_mpm/cli/parsers/skills_parser.py +7 -0
  42. claude_mpm/cli/parsers/source_parser.py +138 -0
  43. claude_mpm/cli/startup.py +456 -103
  44. claude_mpm/cli/startup_display.py +4 -4
  45. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  46. claude_mpm/commands/mpm-agents-detect.md +9 -0
  47. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  48. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  49. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  50. claude_mpm/commands/mpm-doctor.md +9 -0
  51. claude_mpm/commands/mpm-help.md +14 -2
  52. claude_mpm/commands/mpm-init.md +9 -0
  53. claude_mpm/commands/mpm-monitor.md +9 -0
  54. claude_mpm/commands/mpm-postmortem.md +123 -0
  55. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  56. claude_mpm/commands/mpm-status.md +9 -0
  57. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  58. claude_mpm/commands/mpm-ticket-view.md +552 -0
  59. claude_mpm/commands/mpm-version.md +9 -0
  60. claude_mpm/commands/mpm.md +10 -0
  61. claude_mpm/config/agent_presets.py +488 -0
  62. claude_mpm/config/agent_sources.py +325 -0
  63. claude_mpm/config/skill_presets.py +392 -0
  64. claude_mpm/config/skill_sources.py +590 -0
  65. claude_mpm/constants.py +1 -0
  66. claude_mpm/core/claude_runner.py +5 -34
  67. claude_mpm/core/config.py +16 -0
  68. claude_mpm/core/framework/__init__.py +3 -16
  69. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  70. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  71. claude_mpm/core/interactive_session.py +83 -7
  72. claude_mpm/core/oneshot_session.py +71 -8
  73. claude_mpm/core/protocols/__init__.py +23 -0
  74. claude_mpm/core/protocols/runner_protocol.py +103 -0
  75. claude_mpm/core/protocols/session_protocol.py +131 -0
  76. claude_mpm/core/shared/singleton_manager.py +11 -4
  77. claude_mpm/core/system_context.py +38 -0
  78. claude_mpm/core/unified_config.py +22 -0
  79. claude_mpm/experimental/cli_enhancements.py +1 -5
  80. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  81. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  82. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  83. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  84. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  85. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  86. claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
  87. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  88. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  89. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  90. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  91. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  92. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  93. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  94. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  95. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  96. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  97. claude_mpm/models/git_repository.py +198 -0
  98. claude_mpm/services/agents/agent_builder.py +45 -9
  99. claude_mpm/services/agents/agent_preset_service.py +238 -0
  100. claude_mpm/services/agents/agent_selection_service.py +484 -0
  101. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  102. claude_mpm/services/agents/cache_git_manager.py +621 -0
  103. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  104. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  105. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  106. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  107. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  108. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  109. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  110. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  111. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  112. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  113. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  114. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  115. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  116. claude_mpm/services/agents/git_source_manager.py +629 -0
  117. claude_mpm/services/agents/loading/framework_agent_loader.py +1 -4
  118. claude_mpm/services/agents/local_template_manager.py +47 -9
  119. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  120. claude_mpm/services/agents/sources/__init__.py +13 -0
  121. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  122. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  123. claude_mpm/services/agents/startup_sync.py +239 -0
  124. claude_mpm/services/agents/toolchain_detector.py +474 -0
  125. claude_mpm/services/analysis/__init__.py +25 -0
  126. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  127. claude_mpm/services/analysis/postmortem_service.py +765 -0
  128. claude_mpm/services/command_deployment_service.py +200 -6
  129. claude_mpm/services/core/base.py +7 -2
  130. claude_mpm/services/core/interfaces/__init__.py +1 -3
  131. claude_mpm/services/core/interfaces/health.py +1 -4
  132. claude_mpm/services/core/models/__init__.py +2 -11
  133. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  134. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  135. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  136. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  137. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  138. claude_mpm/services/diagnostics/doctor_reporter.py +34 -6
  139. claude_mpm/services/git/__init__.py +21 -0
  140. claude_mpm/services/git/git_operations_service.py +494 -0
  141. claude_mpm/services/github/__init__.py +21 -0
  142. claude_mpm/services/github/github_cli_service.py +397 -0
  143. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  144. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  145. claude_mpm/services/instructions/__init__.py +9 -0
  146. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  147. claude_mpm/services/local_ops/__init__.py +3 -13
  148. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  149. claude_mpm/services/local_ops/health_manager.py +1 -4
  150. claude_mpm/services/mcp_config_manager.py +75 -145
  151. claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
  152. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  153. claude_mpm/services/mcp_service_verifier.py +6 -3
  154. claude_mpm/services/monitor/daemon.py +28 -8
  155. claude_mpm/services/monitor/daemon_manager.py +96 -19
  156. claude_mpm/services/pr/__init__.py +14 -0
  157. claude_mpm/services/pr/pr_template_service.py +329 -0
  158. claude_mpm/services/project/project_organizer.py +4 -0
  159. claude_mpm/services/runner_configuration_service.py +16 -3
  160. claude_mpm/services/session_management_service.py +16 -4
  161. claude_mpm/services/skills/__init__.py +18 -0
  162. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  163. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  164. claude_mpm/services/socketio/server/core.py +1 -4
  165. claude_mpm/services/socketio/server/main.py +1 -3
  166. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  167. claude_mpm/services/unified/unified_deployment.py +1 -5
  168. claude_mpm/services/visualization/__init__.py +1 -5
  169. claude_mpm/templates/questions/__init__.py +2 -7
  170. claude_mpm/templates/questions/pr_strategy.py +1 -4
  171. claude_mpm/templates/questions/project_init.py +1 -4
  172. claude_mpm/templates/questions/ticket_mgmt.py +1 -4
  173. claude_mpm/utils/agent_dependency_loader.py +77 -10
  174. claude_mpm/utils/agent_filters.py +288 -0
  175. claude_mpm/utils/gitignore.py +3 -0
  176. claude_mpm/utils/migration.py +372 -0
  177. claude_mpm/utils/progress.py +387 -0
  178. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/METADATA +356 -112
  179. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/RECORD +188 -439
  180. claude_mpm/agents/templates/agent-manager.json +0 -273
  181. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  182. claude_mpm/agents/templates/api_qa.json +0 -183
  183. claude_mpm/agents/templates/clerk-ops.json +0 -235
  184. claude_mpm/agents/templates/code_analyzer.json +0 -101
  185. claude_mpm/agents/templates/content-agent.json +0 -358
  186. claude_mpm/agents/templates/dart_engineer.json +0 -307
  187. claude_mpm/agents/templates/data_engineer.json +0 -225
  188. claude_mpm/agents/templates/documentation.json +0 -238
  189. claude_mpm/agents/templates/engineer.json +0 -210
  190. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  191. claude_mpm/agents/templates/golang_engineer.json +0 -270
  192. claude_mpm/agents/templates/imagemagick.json +0 -264
  193. claude_mpm/agents/templates/java_engineer.json +0 -346
  194. claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
  195. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  196. claude_mpm/agents/templates/memory_manager.json +0 -158
  197. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  198. claude_mpm/agents/templates/ops.json +0 -185
  199. claude_mpm/agents/templates/php-engineer.json +0 -287
  200. claude_mpm/agents/templates/product_owner.json +0 -338
  201. claude_mpm/agents/templates/project_organizer.json +0 -144
  202. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  203. claude_mpm/agents/templates/python_engineer.json +0 -387
  204. claude_mpm/agents/templates/qa.json +0 -243
  205. claude_mpm/agents/templates/react_engineer.json +0 -239
  206. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  207. claude_mpm/agents/templates/research.json +0 -258
  208. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  209. claude_mpm/agents/templates/rust_engineer.json +0 -275
  210. claude_mpm/agents/templates/security.json +0 -202
  211. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  212. claude_mpm/agents/templates/tauri_engineer.json +0 -274
  213. claude_mpm/agents/templates/ticketing.json +0 -181
  214. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  215. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  216. claude_mpm/agents/templates/version_control.json +0 -159
  217. claude_mpm/agents/templates/web_qa.json +0 -400
  218. claude_mpm/agents/templates/web_ui.json +0 -189
  219. claude_mpm/cli/README.md +0 -253
  220. claude_mpm/cli/commands/mcp_install_commands.py.backup +0 -284
  221. claude_mpm/cli/commands/mpm_init/README.md +0 -365
  222. claude_mpm/cli_module/refactoring_guide.md +0 -253
  223. claude_mpm/commands/mpm-tickets.md +0 -151
  224. claude_mpm/config/agent_capabilities.yaml +0 -658
  225. claude_mpm/config/async_logging_config.yaml +0 -145
  226. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +0 -34
  227. claude_mpm/d2/.gitignore +0 -22
  228. claude_mpm/d2/ARCHITECTURE_COMPARISON.md +0 -273
  229. claude_mpm/d2/FLASK_INTEGRATION.md +0 -156
  230. claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +0 -452
  231. claude_mpm/d2/QUICKSTART.md +0 -186
  232. claude_mpm/d2/README.md +0 -232
  233. claude_mpm/d2/STORE_FIX_SUMMARY.md +0 -167
  234. claude_mpm/d2/SVELTE5_STORES_GUIDE.md +0 -180
  235. claude_mpm/d2/TESTING.md +0 -288
  236. claude_mpm/d2/index.html +0 -118
  237. claude_mpm/d2/package.json +0 -19
  238. claude_mpm/d2/src/App.svelte +0 -110
  239. claude_mpm/d2/src/components/Header.svelte +0 -153
  240. claude_mpm/d2/src/components/MainContent.svelte +0 -74
  241. claude_mpm/d2/src/components/Sidebar.svelte +0 -85
  242. claude_mpm/d2/src/components/tabs/EventsTab.svelte +0 -326
  243. claude_mpm/d2/src/lib/socketio.js +0 -144
  244. claude_mpm/d2/src/main.js +0 -7
  245. claude_mpm/d2/src/stores/events.js +0 -114
  246. claude_mpm/d2/src/stores/socket.js +0 -108
  247. claude_mpm/d2/src/stores/theme.js +0 -65
  248. claude_mpm/d2/svelte.config.js +0 -12
  249. claude_mpm/d2/vite.config.js +0 -15
  250. claude_mpm/dashboard/.claude-mpm/memories/README.md +0 -36
  251. claude_mpm/dashboard/BUILD_NUMBER +0 -1
  252. claude_mpm/dashboard/README.md +0 -121
  253. claude_mpm/dashboard/VERSION +0 -1
  254. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  255. claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +0 -273
  256. claude_mpm/dashboard/react/components/ErrorBoundary.tsx +0 -75
  257. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  258. claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +0 -141
  259. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  260. claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +0 -36
  261. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  262. claude_mpm/dashboard/react/components/shared/FilterBar.tsx +0 -89
  263. claude_mpm/dashboard/react/contexts/DashboardContext.tsx +0 -215
  264. claude_mpm/dashboard/react/entries/events.tsx +0 -165
  265. claude_mpm/dashboard/react/hooks/useEvents.ts +0 -191
  266. claude_mpm/dashboard/react/hooks/useSocket.ts +0 -225
  267. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  268. claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +0 -170
  269. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  270. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  271. claude_mpm/dashboard/static/built/components/activity-tree.js.map +0 -1
  272. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  273. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  274. claude_mpm/dashboard/static/built/components/agent-inference.js.map +0 -1
  275. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  276. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  277. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  278. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  279. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  280. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  281. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  282. claude_mpm/dashboard/static/built/components/code-tree.js.map +0 -1
  283. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  284. claude_mpm/dashboard/static/built/components/code-viewer.js.map +0 -1
  285. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  286. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  287. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  288. claude_mpm/dashboard/static/built/components/event-processor.js.map +0 -1
  289. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  290. claude_mpm/dashboard/static/built/components/event-viewer.js.map +0 -1
  291. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  292. claude_mpm/dashboard/static/built/components/export-manager.js.map +0 -1
  293. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  294. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  295. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  296. claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +0 -1
  297. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  298. claude_mpm/dashboard/static/built/components/file-viewer.js.map +0 -1
  299. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  300. claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +0 -1
  301. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  302. claude_mpm/dashboard/static/built/components/hud-manager.js.map +0 -1
  303. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  304. claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +0 -1
  305. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  306. claude_mpm/dashboard/static/built/components/module-viewer.js.map +0 -1
  307. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  308. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  309. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  310. claude_mpm/dashboard/static/built/components/session-manager.js.map +0 -1
  311. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  312. claude_mpm/dashboard/static/built/components/socket-manager.js.map +0 -1
  313. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  314. claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +0 -1
  315. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  316. claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +0 -1
  317. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  318. claude_mpm/dashboard/static/built/components/working-directory.js.map +0 -1
  319. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  320. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  321. claude_mpm/dashboard/static/built/dashboard.js.map +0 -1
  322. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  323. claude_mpm/dashboard/static/built/react/events.js +0 -30
  324. claude_mpm/dashboard/static/built/react/events.js.map +0 -1
  325. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  326. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  327. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  328. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  329. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  330. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  331. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  332. claude_mpm/dashboard/static/built/socket-client.js.map +0 -1
  333. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  334. claude_mpm/dashboard/static/events.html +0 -607
  335. claude_mpm/dashboard/static/index.html +0 -635
  336. claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +0 -170
  337. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  338. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  339. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  340. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  341. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  342. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  343. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  344. claude_mpm/dashboard/static/legacy/files.html +0 -747
  345. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  346. claude_mpm/dashboard/static/monitors.html +0 -431
  347. claude_mpm/dashboard/static/navigation-test-results.md +0 -118
  348. claude_mpm/dashboard/static/production/events.html +0 -659
  349. claude_mpm/dashboard/static/production/main.html +0 -698
  350. claude_mpm/dashboard/static/production/monitors.html +0 -483
  351. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  352. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  353. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  354. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  355. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +0 -36
  356. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +0 -39
  357. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +0 -38
  358. claude_mpm/hooks/README.md +0 -143
  359. claude_mpm/hooks/templates/README.md +0 -180
  360. claude_mpm/hooks/templates/settings.json.example +0 -147
  361. claude_mpm/schemas/agent_schema.json +0 -596
  362. claude_mpm/schemas/frontmatter_schema.json +0 -165
  363. claude_mpm/services/event_bus/README.md +0 -244
  364. claude_mpm/services/events/README.md +0 -303
  365. claude_mpm/services/framework_claude_md_generator/README.md +0 -119
  366. claude_mpm/services/mcp_gateway/README.md +0 -185
  367. claude_mpm/services/socketio/handlers/connection.py.backup +0 -217
  368. claude_mpm/services/socketio/handlers/hook.py.backup +0 -154
  369. claude_mpm/services/static/.gitkeep +0 -2
  370. claude_mpm/services/version_control/VERSION +0 -1
  371. claude_mpm/skills/bundled/.gitkeep +0 -2
  372. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  373. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  374. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  375. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  376. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  377. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  378. claude_mpm/skills/bundled/collaboration/git-worktrees.md +0 -317
  379. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  380. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  381. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  382. claude_mpm/skills/bundled/collaboration/stacked-prs.md +0 -251
  383. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  384. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  385. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  386. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  387. claude_mpm/skills/bundled/debugging/root-cause-tracing/find-polluter.sh +0 -63
  388. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  389. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  390. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  391. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  392. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  393. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  394. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  395. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  396. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  397. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  398. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  399. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  400. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  401. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  402. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  403. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  404. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  405. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  406. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  407. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +0 -611
  408. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +0 -596
  409. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +0 -260
  410. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +0 -315
  411. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +0 -436
  412. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +0 -433
  413. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +0 -452
  414. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +0 -404
  415. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +0 -420
  416. claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +0 -202
  417. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  418. claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +0 -54
  419. claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +0 -322
  420. claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  421. claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +0 -202
  422. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  423. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  424. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  425. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  426. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  427. claude_mpm/skills/bundled/main/mcp-builder/LICENSE.txt +0 -202
  428. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  429. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  430. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  431. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  432. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  433. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  434. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  435. claude_mpm/skills/bundled/main/mcp-builder/scripts/example_evaluation.xml +0 -22
  436. claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +0 -2
  437. claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +0 -202
  438. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  439. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  440. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  441. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  442. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  443. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  444. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  445. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  446. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  447. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  448. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  449. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  450. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  451. claude_mpm/skills/bundled/react/flexlayout-react.md +0 -742
  452. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  453. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  454. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  455. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  456. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  457. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  458. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  459. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +0 -495
  460. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +0 -599
  461. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +0 -535
  462. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +0 -613
  463. claude_mpm/skills/bundled/tauri/tauri-event-system.md +0 -648
  464. claude_mpm/skills/bundled/tauri/tauri-file-system.md +0 -673
  465. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +0 -767
  466. claude_mpm/skills/bundled/tauri/tauri-performance.md +0 -669
  467. claude_mpm/skills/bundled/tauri/tauri-state-management.md +0 -573
  468. claude_mpm/skills/bundled/tauri/tauri-testing.md +0 -384
  469. claude_mpm/skills/bundled/tauri/tauri-window-management.md +0 -628
  470. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  471. claude_mpm/skills/bundled/testing/condition-based-waiting/example.ts +0 -158
  472. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  473. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  474. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  475. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  476. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  477. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  478. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  479. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +0 -458
  480. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +0 -411
  481. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +0 -317
  482. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +0 -270
  483. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +0 -436
  484. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  485. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  486. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  487. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  488. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  489. claude_mpm/skills/bundled/testing/webapp-testing/LICENSE.txt +0 -202
  490. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  491. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  492. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  493. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  494. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  495. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  496. claude_mpm/templates/questions/EXAMPLES.md +0 -501
  497. claude_mpm/tools/README_SOCKETIO_DEBUG.md +0 -224
  498. claude_mpm/tools/code_tree_analyzer/README.md +0 -64
  499. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  500. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  501. /claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +0 -0
  502. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  503. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  504. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/WHEEL +0 -0
  505. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/entry_points.txt +0 -0
  506. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/licenses/LICENSE +0 -0
  507. {claude_mpm-4.25.10.dist-info → claude_mpm-5.1.8.dist-info}/top_level.txt +0 -0
@@ -1,170 +0,0 @@
1
- # Dashboard JavaScript Refactoring Summary
2
-
3
- ## Date: 2025-09-05
4
-
5
- ## Overview
6
- Performed Phase 1 safe, incremental refactoring of the dashboard JavaScript code, focusing on the highest-impact, lowest-risk improvements.
7
-
8
- ## Changes Made
9
-
10
- ### 1. Created Shared Services Directory Structure
11
- Created `/src/claude_mpm/dashboard/static/js/shared/` with reusable services:
12
-
13
- #### **tooltip-service.js** (293 lines)
14
- - Unified tooltip implementation for all components
15
- - Single consistent API for all tooltips
16
- - Support for different tooltip types (hover, click, persistent)
17
- - Automatic viewport adjustment
18
- - Content formatting with HTML escaping
19
-
20
- #### **dom-helpers.js** (338 lines)
21
- - Common DOM manipulation utilities
22
- - createElement helpers with attribute and event handling
23
- - Class manipulation utilities
24
- - Safe querySelector wrappers
25
- - Viewport and scroll utilities
26
- - Debounce and throttle functions
27
-
28
- #### **event-bus.js** (277 lines)
29
- - Central event management with pub/sub pattern
30
- - Decouples components from direct communication
31
- - Priority-based event handlers
32
- - Event history and debugging capabilities
33
- - Scoped event buses for component isolation
34
-
35
- #### **logger.js** (354 lines)
36
- - Centralized logging with levels
37
- - Component-specific loggers
38
- - Performance timing helpers
39
- - Log history and export capabilities
40
- - Console group and table support
41
-
42
- ### 2. Extracted Code Tree Modules
43
- Created `/src/claude_mpm/dashboard/static/js/components/code-tree/` with specialized modules:
44
-
45
- #### **tree-utils.js** (424 lines)
46
- - File type detection and icons
47
- - Complexity level calculations
48
- - File size formatting
49
- - Node sorting and filtering
50
- - Tree statistics calculation
51
- - Path formatting utilities
52
-
53
- #### **tree-constants.js** (178 lines)
54
- - Layout dimensions and defaults
55
- - Animation timings
56
- - Color schemes for complexity
57
- - File extension to language mappings
58
- - API endpoints
59
- - WebSocket events
60
- - CSS class names
61
- - All constants are frozen to prevent modification
62
-
63
- #### **tree-search.js** (366 lines)
64
- - Search term management with debouncing
65
- - Language and type filtering
66
- - Complexity range filtering
67
- - Path pattern matching with wildcards
68
- - Search suggestions
69
- - Search term highlighting
70
- - Filter state management
71
-
72
- #### **tree-breadcrumb.js** (318 lines)
73
- - Path navigation display
74
- - Activity status updates
75
- - Clickable path segments
76
- - Overflow handling for long paths
77
- - Loading states
78
- - Activity history tracking
79
-
80
- ### 3. Updated code-tree.js Integration
81
- - Added service initialization in constructor
82
- - Uses extracted modules with fallback to original implementations
83
- - Maintains backward compatibility
84
- - Added documentation comments for module dependencies
85
-
86
- ### 4. Updated HTML Loading Sequence
87
- Modified `/src/claude_mpm/dashboard/templates/index.html`:
88
- - Loads shared services first (sequentially)
89
- - Then loads tree modules
90
- - Finally loads main components in parallel
91
- - Ensures proper dependency resolution
92
-
93
- ## Results
94
-
95
- ### Code Organization Improvements
96
- - **Before**: Single 5,845-line file with mixed concerns
97
- - **After**: Modular architecture with 8 specialized modules totaling ~2,500 lines
98
- - Clear separation of concerns
99
- - Reusable services available to all components
100
-
101
- ### Maintainability Benefits
102
- 1. **Single Responsibility**: Each module has a clear, focused purpose
103
- 2. **Reusability**: Services can be used by any dashboard component
104
- 3. **Testability**: Individual modules can be tested in isolation
105
- 4. **Documentation**: All modules have JSDoc comments
106
- 5. **Consistency**: Shared services ensure consistent behavior
107
-
108
- ### Performance Considerations
109
- - Modules loaded sequentially for dependencies, then parallel for main components
110
- - Services use singleton pattern to minimize memory usage
111
- - Lazy initialization where appropriate
112
- - Debouncing and throttling built into utilities
113
-
114
- ## Backward Compatibility
115
- - All changes maintain backward compatibility
116
- - Fallback implementations when services unavailable
117
- - No breaking changes to external APIs
118
- - Dashboard remains fully functional
119
-
120
- ## Next Steps for Phase 2 (Future Work)
121
-
122
- 1. **Further code-tree.js decomposition**:
123
- - Extract D3 visualization logic
124
- - Separate WebSocket handling
125
- - Create dedicated file analysis module
126
-
127
- 2. **Apply pattern to other components**:
128
- - Refactor activity-tree.js to use shared services
129
- - Update other components to use tooltip service
130
- - Migrate to event bus for inter-component communication
131
-
132
- 3. **Testing**:
133
- - Add unit tests for each module
134
- - Integration tests for service interactions
135
- - Performance benchmarks
136
-
137
- 4. **Documentation**:
138
- - API documentation for each service
139
- - Usage examples
140
- - Migration guide for other components
141
-
142
- ## Files Created/Modified
143
-
144
- ### Created (New Files)
145
- - `/static/js/shared/tooltip-service.js`
146
- - `/static/js/shared/dom-helpers.js`
147
- - `/static/js/shared/event-bus.js`
148
- - `/static/js/shared/logger.js`
149
- - `/static/js/components/code-tree/tree-utils.js`
150
- - `/static/js/components/code-tree/tree-constants.js`
151
- - `/static/js/components/code-tree/tree-search.js`
152
- - `/static/js/components/code-tree/tree-breadcrumb.js`
153
-
154
- ### Modified
155
- - `/static/js/components/code-tree.js` - Added service initialization and module usage
156
- - `/templates/index.html` - Updated script loading sequence
157
-
158
- ## Success Criteria Met
159
- ✅ Dashboard remains fully functional
160
- ✅ No console errors or warnings
161
- ✅ Shared services created and available
162
- ✅ All new code has JSDoc documentation
163
- ✅ Backward compatibility maintained
164
- ✅ Clear separation of concerns achieved
165
-
166
- ## Notes
167
- - The refactoring focused on extraction and organization rather than size reduction
168
- - The main code-tree.js file grew slightly due to initialization code and fallbacks
169
- - The real benefit is in the improved architecture and reusability
170
- - Future phases can now proceed with a solid foundation
@@ -1 +0,0 @@
1
- ._dataInspector_9ek2f_1{background:#0000004d;border-radius:6px;border:1px solid rgba(255,255,255,.1);overflow:hidden}._inspectorHeader_9ek2f_8{display:flex;gap:10px;padding:10px;background:#ffffff0d;border-bottom:1px solid rgba(255,255,255,.1);align-items:center}._searchInput_9ek2f_17{flex:1;padding:8px 12px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:4px;color:#fff;font-size:12px}._searchInput_9ek2f_17::placeholder{color:#ffffff80}._actions_9ek2f_31{display:flex;gap:8px}._actionButton_9ek2f_36{padding:6px 12px;background:#ffffff1a;border:none;border-radius:4px;color:#fff;font-size:11px;cursor:pointer;transition:background .2s}._actionButton_9ek2f_36:hover{background:#fff3}._treeContainer_9ek2f_51{overflow-y:auto;padding:10px;font-family:Courier New,monospace;font-size:13px;line-height:1.4}._treeNode_9ek2f_59{margin-bottom:2px}._nodeHeader_9ek2f_63{display:flex;align-items:center;gap:6px;padding:2px 4px;cursor:pointer;border-radius:3px;transition:background .2s}._nodeHeader_9ek2f_63:hover{background:#ffffff0d}._expandIcon_9ek2f_77{color:#94a3b8;font-size:10px;transition:transform .2s;cursor:pointer;user-select:none;width:12px;display:inline-block}._expandIcon_9ek2f_77._expanded_9ek2f_87{transform:rotate(90deg)}._leafIcon_9ek2f_91{color:#94a3b8;font-size:8px;width:12px;display:inline-block;text-align:center}._nodeKey_9ek2f_99{color:#60a5fa;font-weight:500}._nodeValue_9ek2f_104{margin-left:6px;word-break:break-all}._nodeValue_9ek2f_104._string_9ek2f_109{color:#86efac}._nodeValue_9ek2f_104._number_9ek2f_113{color:#fbbf24}._nodeValue_9ek2f_104._boolean_9ek2f_117{color:#a78bfa}._nodeValue_9ek2f_104._null_9ek2f_121,._nodeValue_9ek2f_104._undefined_9ek2f_122{color:#f87171;font-style:italic}._nodeValue_9ek2f_104._object_9ek2f_127,._nodeValue_9ek2f_104._array_9ek2f_128{color:#94a3b8;font-style:italic}._copyButton_9ek2f_133{margin-left:auto;background:none;border:none;color:#ffffff80;cursor:pointer;padding:2px;font-size:10px;opacity:0;transition:opacity .2s}._nodeHeader_9ek2f_63:hover ._copyButton_9ek2f_133{opacity:1}._copyButton_9ek2f_133:hover{color:#fffc}._nodeChildren_9ek2f_153{border-left:1px solid rgba(255,255,255,.1);margin-left:6px}._highlight_9ek2f_158{background:#fbbf244d;color:#fbbf24;padding:1px 2px;border-radius:2px}._noData_9ek2f_165{text-align:center;color:#ffffff80;padding:20px;font-style:italic}._treeContainer_9ek2f_51::-webkit-scrollbar{width:6px}._treeContainer_9ek2f_51::-webkit-scrollbar-track{background:#ffffff0d}._treeContainer_9ek2f_51::-webkit-scrollbar-thumb{background:#fff3;border-radius:3px}._treeContainer_9ek2f_51::-webkit-scrollbar-thumb:hover{background:#ffffff4d}._eventsContainer_3k2sj_1{background:#ffffff0d;backdrop-filter:blur(10px);border-radius:12px;border:1px solid rgba(255,255,255,.1);overflow:hidden;flex:1;display:flex;flex-direction:column;min-height:0}._eventsHeader_3k2sj_13{padding:15px 20px;background:#ffffff0d;border-bottom:1px solid rgba(255,255,255,.1);display:flex;justify-content:space-between;align-items:center}._eventsTitle_3k2sj_22{font-weight:600;font-size:16px}._eventsInfo_3k2sj_27{font-size:12px;color:#fff9}._eventsList_3k2sj_32{flex:1;position:relative;min-height:300px}._eventItem_3k2sj_38{padding:12px 20px;border-bottom:1px solid rgba(255,255,255,.05);transition:background .2s;cursor:pointer;font-family:Courier New,monospace;font-size:13px;position:relative;animation:_slideIn_3k2sj_1 .3s ease}@keyframes _slideIn_3k2sj_1{0%{opacity:0;transform:translate(-20px)}to{opacity:1;transform:translate(0)}}._eventItem_3k2sj_38:hover{background:#ffffff0d}._eventItem_3k2sj_38._expanded_3k2sj_64{background:#ffffff14}._eventHeader_3k2sj_68{width:100%}._eventHeaderRow_3k2sj_72{display:flex;gap:10px;align-items:center;margin-bottom:5px}._eventType_3k2sj_79{padding:3px 8px;border-radius:10px;font-size:11px;font-weight:600;text-transform:uppercase}._eventType_3k2sj_79._agent_3k2sj_87{background:#a78bfa33;color:#a78bfa}._eventType_3k2sj_79._tool_3k2sj_92{background:#60a5fa33;color:#60a5fa}._eventType_3k2sj_79._file_3k2sj_97{background:#fbbf2433;color:#fbbf24}._eventType_3k2sj_79._session_3k2sj_102{background:#4ade8033;color:#4ade80}._eventType_3k2sj_79._error_3k2sj_107{background:#f8717133;color:#f87171}._eventType_3k2sj_79._info_3k2sj_112{background:#86efac33;color:#86efac}._eventTime_3k2sj_117{font-size:11px;color:#ffffff80}._sourceIndicator_3k2sj_122{font-size:10px;color:#fff6;font-style:italic}._eventPreview_3k2sj_128{color:#ffffffb3;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}._eventDetails_3k2sj_136{margin-top:10px;padding:10px;background:#0003;border-radius:6px}._noEvents_3k2sj_143{text-align:center;padding:60px 20px;color:#ffffff80}._noEvents_3k2sj_143 h3{margin-bottom:10px;font-size:18px}._noEvents_3k2sj_143 p{font-size:14px}._controlsPanel_wgq69_1{background:#ffffff0d;backdrop-filter:blur(10px);border:1px solid rgba(255,255,255,.1);border-radius:10px;padding:15px;margin-bottom:20px;display:flex;gap:15px;align-items:center;flex-wrap:wrap}._controlGroup_wgq69_14{display:flex;align-items:center;gap:10px}._controlLabel_wgq69_20{font-size:14px;color:#94a3b8}._btn_wgq69_25{padding:10px 20px;background:linear-gradient(135deg,#10b981,#06b6d4);border:none;border-radius:8px;color:#fff;cursor:pointer;font-size:14px;transition:transform .2s,box-shadow .2s}._btn_wgq69_25:hover{transform:translateY(-2px);box-shadow:0 5px 15px #10b98166}._btn_wgq69_25._secondary_wgq69_41{background:#ffffff1a}._btn_wgq69_25._danger_wgq69_45{background:linear-gradient(135deg,#ef4444,#dc2626)}._searchBox_wgq69_49{flex:1;min-width:200px;padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;color:#fff;font-size:14px}._searchBox_wgq69_49::placeholder{color:#ffffff80}._filterSelect_wgq69_64{padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;color:#fff;font-size:14px;cursor:pointer}._filterSelect_wgq69_64 option{background:#0f172a}._checkboxLabel_wgq69_78{display:flex;align-items:center;gap:8px;padding:10px 15px;background:#ffffff0d;border:1px solid rgba(255,255,255,.1);border-radius:8px;cursor:pointer;font-size:14px}._checkboxLabel_wgq69_78 input{cursor:pointer}
@@ -1,2 +0,0 @@
1
- import{U as e}from"./unified-data-viewer.js";class t{constructor(){this.container=null,this.events=[],this.processedEventIds=new Set,this.sessions=new Map,this.currentSession=null,this.selectedSessionFilter="all",this.timeRange="30min",this.searchTerm="",this.initialized=!1,this.expandedSessions=new Set,this.expandedAgents=new Set,this.expandedTools=new Set,this.selectedItem=null,this.sessionFilterInitialized=!1,this.renderTreeDebounced=this.debounce(()=>this.renderTree(),100)}debounce(e,t){let s;return function(...n){clearTimeout(s),s=setTimeout(()=>{clearTimeout(s),e(...n)},t)}}initialize(){if(console.log("ActivityTree.initialize() called, initialized:",this.initialized),this.initialized)return void console.log("Activity tree already initialized, skipping");if(this.container=document.getElementById("activity-tree-container"),!this.container&&(this.container=document.getElementById("activity-tree"),!this.container))return void console.error("Activity tree container not found in DOM");const e=document.getElementById("activity-tab");if(e){if(!e.classList.contains("active"))return console.log("Activity tab not active, initializing but deferring render"),this.setupControls(),this.subscribeToEvents(),void(this.initialized=!0);this.setupControls(),this.createLinearTreeView(),this.subscribeToEvents(),this.initialized=!0,console.log("Activity tree initialization complete")}else console.error("Activity tab panel (#activity-tab) not found in DOM")}forceShow(){console.log("ActivityTree.forceShow() called"),this.container||(this.container=document.getElementById("activity-tree-container")||document.getElementById("activity-tree"),this.container)?(this.createLinearTreeView(),this.renderTree()):console.error("Cannot find activity tree container")}renderWhenVisible(){if(console.log("ActivityTree.renderWhenVisible() called"),!this.initialized)return console.log("Not initialized yet, calling initialize..."),void this.initialize();this.createLinearTreeView(),this.renderTree()}setupControls(){const e=document.getElementById("time-range");e&&e.addEventListener("change",e=>{this.timeRange=e.target.value,console.log(`ActivityTree: Time range changed to: ${this.timeRange}`),this.renderTree()}),document.addEventListener("sessionFilterChanged",e=>{this.selectedSessionFilter=e.detail.sessionId||"all",console.log(`ActivityTree: Session filter changed to: ${this.selectedSessionFilter} (from SessionManager)`),this.renderTree()}),document.addEventListener("sessionChanged",e=>{this.selectedSessionFilter=e.detail.sessionId||"all",console.log(`ActivityTree: Session changed to: ${this.selectedSessionFilter} (from SessionManager - backward compat)`),this.renderTree()}),setTimeout(()=>{if(window.sessionManager&&!this.sessionFilterInitialized){const e=window.sessionManager.getCurrentFilter();e!==this.selectedSessionFilter&&(this.selectedSessionFilter=e||"all",console.log(`ActivityTree: Initialized with current session filter: ${this.selectedSessionFilter}`),this.sessionFilterInitialized=!0,this.renderTree())}},100);const t=document.getElementById("expand-all");t&&t.addEventListener("click",()=>this.expandAllSessions());const s=document.getElementById("collapse-all");s&&s.addEventListener("click",()=>this.collapseAllSessions());const n=document.getElementById("reset-zoom");n&&(n.style.display="inline-block",n.addEventListener("click",()=>this.resetZoom()));const o=document.getElementById("activity-search");o&&o.addEventListener("input",e=>{this.searchTerm=e.target.value.toLowerCase(),this.renderTree()})}createLinearTreeView(){console.log("Creating linear tree view"),this.container.innerHTML="";const e=document.createElement("div");e.id="linear-tree",e.className="linear-tree",this.container.appendChild(e),console.log("Linear tree view created")}subscribeToEvents(){if(!window.socketClient)return console.warn("Socket client not available for activity tree"),void setTimeout(()=>this.subscribeToEvents(),1e3);console.log("ActivityTree: Setting up event subscription"),window.socketClient.onEventUpdate((e,t)=>{console.log(`ActivityTree: onEventUpdate called with ${e.length} total events and ${t.size} sessions`);for(const[n,o]of t.entries())if(this.sessions.has(n)){const e=this.sessions.get(n);e.timestamp=new Date(o.lastActivity||o.startTime||e.timestamp),e.eventCount=o.eventCount,e.status=o.status||e.status,e.working_directory=o.working_directory||e.working_directory,e.git_branch=o.git_branch||e.git_branch}else{const e={id:n,timestamp:new Date(o.lastActivity||o.startTime||new Date),expanded:this.expandedSessions.has(n)||!0,agents:new Map,todos:[],userInstructions:[],tools:[],toolsMap:new Map,status:"active",currentTodoTool:null,working_directory:o.working_directory,git_branch:o.git_branch,eventCount:o.eventCount};this.sessions.set(n,e)}const s=e.filter(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;return!this.processedEventIds.has(t)});s.length>0&&(console.log(`ActivityTree: Processing ${s.length} new events`,s),s.forEach(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;this.processedEventIds.add(t),this.processEvent(e)})),this.events=[...e],this.renderTreeDebounced(),console.log("ActivityTree: Sessions after sync with socket client:",Array.from(this.sessions.entries()))});const e=window.socketClient?.getState();if(e&&e.events.length>0){console.log(`ActivityTree: Loading existing data - ${e.events.length} events, ${e.sessions.size} sessions`);for(const[s,n]of e.sessions.entries())if(!this.sessions.has(s)){const e={id:s,timestamp:new Date(n.lastActivity||n.startTime||new Date),expanded:this.expandedSessions.has(s)||!0,agents:new Map,todos:[],userInstructions:[],tools:[],toolsMap:new Map,status:"active",currentTodoTool:null,working_directory:n.working_directory,git_branch:n.git_branch,eventCount:n.eventCount};this.sessions.set(s,e)}const t=e.events.filter(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;return!this.processedEventIds.has(t)});t.length>0&&(console.log(`ActivityTree: Processing ${t.length} unprocessed events from initial load`),t.forEach(e=>{const t=e.id||`${e.type}-${e.timestamp}-${Math.random()}`;this.processedEventIds.add(t),this.processEvent(e)})),this.events=[...e.events],this.renderTree(),console.log("ActivityTree: Initial sessions state:",Array.from(this.sessions.entries()))}else console.log("ActivityTree: No existing events found"),this.events=[],this.sessions.clear(),this.renderTree()}processEvent(e){if(!e)return void console.log("ActivityTree: Ignoring null event");let t,s=this.getEventType(e);if(!s)return;console.log(`ActivityTree: Processing event: ${s}`,e),e.timestamp?(t=new Date(e.timestamp),isNaN(t.getTime())&&(console.warn("ActivityTree: Invalid timestamp, using current time:",e.timestamp),t=new Date)):(console.warn("ActivityTree: No timestamp found, using current time"),t=new Date);const n=e.session_id||e.data?.session_id;if(!n)return void console.log(`ActivityTree: Skipping event without session_id: ${s}`);if(!this.sessions.has(n))return void console.warn(`ActivityTree: Session ${n} not found in authoritative sessions - skipping event`);const o=this.sessions.get(n);switch(s){case"Start":this.currentSession=o;break;case"user_prompt":this.processUserInstruction(e,o);break;case"TodoWrite":break;case"SubagentStart":this.processSubagentStart(e,o);break;case"SubagentStop":this.processSubagentStop(e,o);break;case"PreToolUse":this.processToolUse(e,o);break;case"PostToolUse":this.updateToolStatus(e,o,"completed")}this.updateStats()}getEventType(e){if(e.hook_event_name)return e.hook_event_name;if("hook"===e.type&&e.subtype){return{pre_tool:"PreToolUse",post_tool:"PostToolUse",subagent_start:"SubagentStart",subagent_stop:"SubagentStop",todo_write:"TodoWrite"}[e.subtype]}if("todo"===e.type&&"updated"===e.subtype)return"TodoWrite";if("subagent"===e.type){if("started"===e.subtype)return"SubagentStart";if("stopped"===e.subtype)return"SubagentStop"}return"start"===e.type?"Start":"user_prompt"===e.type||"user_prompt"===e.subtype?"user_prompt":null}processUserInstruction(e,t){const s=e.prompt_text||e.data?.prompt_text||e.prompt||"";if(!s)return;const n={id:`instruction-${t.id}-${Date.now()}`,text:s,preview:s.length>100?s.substring(0,100)+"...":s,timestamp:e.timestamp||(new Date).toISOString(),type:"user_instruction"};if(t.agents.size>0){console.log("ActivityTree: New user prompt detected, collapsing previous agents");for(let e of t.agents.values())"active"===e.status&&(e.status="completed"),this.expandedAgents.delete(e.id)}t.currentActiveAgent=null,t.userInstructions.push(n),t.userInstructions.length>5&&(t.userInstructions=t.userInstructions.slice(-5))}processTodoWrite(e,t){let s=e.todos||e.data?.todos||e.data||[];if(s&&"object"==typeof s&&s.todos&&(s=s.todos),!Array.isArray(s)||0===s.length)return;t.currentTodos=s.map(t=>({content:t.content,activeForm:t.activeForm,status:t.status,timestamp:e.timestamp}));let n=t.currentActiveAgent;if(!n){const e=this.getAllAgents(t).filter(e=>"active"===e.status||"in_progress"===e.status).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));if(e.length>0)n=e[0];else{const e=this.getAllAgents(t),s=e.find(e=>e.isPM);s?n=s:e.length>0&&(n=e[0])}}if(n){n.todoWritesMap||(n.todoWritesMap=new Map),n.todoWrites||(n.todoWrites=[]);const t=n.todoWritesMap.get("TodoWrite");if(t)t.todos=s,t.timestamp=e.timestamp,t.updateCount=(t.updateCount||1)+1;else{const t={id:`todowrite-${n.id}-${Date.now()}`,name:"TodoWrite",type:"todowrite",icon:"📝",timestamp:e.timestamp,status:"completed",todos:s,params:{todos:s},updateCount:1};n.todoWritesMap.set("TodoWrite",t),n.todoWrites=[t]}n.currentTodos=s}else{t.todoWrites||(t.todoWrites=[]),t.todoWritesMap||(t.todoWritesMap=new Map);const n=t.todoWritesMap.get("TodoWrite");if(n)n.todos=s,n.timestamp=e.timestamp,n.updateCount=(n.updateCount||1)+1;else{const n={id:`todowrite-session-${Date.now()}`,name:"TodoWrite",type:"todowrite",icon:"📝",timestamp:e.timestamp,status:"completed",todos:s,updateCount:1};t.todoWritesMap.set("TodoWrite",n),t.todoWrites=[n]}}}processSubagentStart(e,t){const s=e.agent_name||e.data?.agent_name||e.data?.agent_type||e.agent_type||e.agent||"unknown",n=e.session_id||e.data?.session_id,o=e.parent_agent||e.data?.parent_agent,i=`${s}-${n||"no-session"}`;let a=null;let r;if(a=this.getAllAgents(t).find(e=>e.name===s&&e.sessionId===n&&"active"===e.status),a)r=a,r.timestamp=e.timestamp,r.instanceCount=(r.instanceCount||1)+1,this.expandedAgents.add(r.id);else{if(r={id:`agent-${i}-${Date.now()}`,name:s,type:"agent",icon:this.getAgentIcon(s),timestamp:e.timestamp,status:"active",tools:[],subagents:new Map,sessionId:n,parentAgent:o,isPM:"pm"===s.toLowerCase()||s.toLowerCase().includes("project manager"),instanceCount:1,toolsMap:new Map},o){let e=null;for(let[s,n]of t.agents.entries())if(n.sessionId===o||n.name===o){e=n;break}e?(e.subagents||(e.subagents=new Map),e.subagents.set(r.id,r)):t.agents.set(r.id,r)}else t.agents.set(r.id,r);this.expandedAgents.add(r.id)}t.currentActiveAgent=r}processSubagentStop(e,t){const s=e.session_id||e.data?.session_id;if(s&&t.agents.has(s)){t.agents.get(s).status="completed"}}processToolUse(e,t){const s=e.tool_name||e.data?.tool_name||e.tool||e.data?.tool||"unknown",n=e.tool_parameters||e.data?.tool_parameters||e.parameters||e.data?.parameters||{},o=e.session_id||e.data?.session_id;let i=t.currentActiveAgent;if(!i){const e=this.getAllAgents(t);i=e.find(e=>e.sessionId===o)||e.find(e=>"active"===e.status)||e[0]}if(i){i.toolsMap||(i.toolsMap=new Map),i.tools||(i.tools=[]);const t=this.getToolKey(s,n);let o=i.toolsMap.get(t);if(o)o.params=n,o.timestamp=e.timestamp,o.status="in_progress",o.eventId=e.id,o.callCount=(o.callCount||1)+1,i.currentTool=o;else{const o={id:`tool-${i.id}-${s}-${Date.now()}`,name:s,type:"tool",icon:this.getToolIcon(s),timestamp:e.timestamp,status:"in_progress",params:n,eventId:e.id,callCount:1,createdAt:e.timestamp};"Task"===s&&n.subagent_type&&(o.isSubagentTask=!0,o.subagentType=n.subagent_type),i.toolsMap.set(t,o),"TodoWrite"===s?i.tools.unshift(o):i.tools.push(o),i.currentTool=o}}else{t.tools||(t.tools=[]),t.toolsMap||(t.toolsMap=new Map);const o=this.getToolKey(s,n);let i=t.toolsMap.get(o);if(i)i.params=n,i.timestamp=e.timestamp,i.status="in_progress",i.eventId=e.id,i.callCount=(i.callCount||1)+1,t.currentTool=i;else{const i={id:`tool-session-${s}-${Date.now()}`,name:s,type:"tool",icon:this.getToolIcon(s),timestamp:e.timestamp,status:"in_progress",params:n,eventId:e.id,callCount:1,createdAt:e.timestamp};t.toolsMap.set(o,i),"TodoWrite"===s?t.tools.unshift(i):t.tools.push(i),t.currentTool=i}}}getToolKey(e,t){if("TodoWrite"===e)return"TodoWrite";let s=e;return"Edit"!==e&&"Write"!==e&&"Read"!==e||t.file_path&&(s+=`-${t.file_path}`),"Grep"!==e&&"Glob"!==e||!t.pattern||(s+=`-${t.pattern.substring(0,20)}`),s}updateToolStatus(e,t,s){const n=e.tool_name||e.data?.tool_name||e.tool||"unknown",o=e.tool_parameters||e.data?.tool_parameters||e.parameters||e.data?.parameters||{},i=e.session_id||e.data?.session_id,a=this.getToolKey(n,o);let r=t.currentActiveAgent;if(!r){const e=this.getAllAgents(t);r=e.find(e=>e.sessionId===i)||e.find(e=>"active"===e.status)}if(r&&r.toolsMap){const t=r.toolsMap.get(a);if(t)return t.status=s,t.completedAt=e.timestamp,(e.data?.result||e.result)&&(t.result=e.data?.result||e.result),void(e.data?.duration_ms&&(t.duration=e.data.duration_ms))}if(t.toolsMap){const n=t.toolsMap.get(a);if(n)return n.status=s,n.completedAt=e.timestamp,(e.data?.result||e.result)&&(n.result=e.data?.result||e.result),void(e.data?.duration_ms&&(n.duration=e.data.duration_ms))}console.log(`ActivityTree: Could not find tool to update status for ${n} with key ${a} (event ${e.id})`)}renderTree(){const e=document.getElementById("linear-tree");if(!e)return;e.innerHTML="";const t=Array.from(this.sessions.values()).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));for(let s of t){if("all"!==this.selectedSessionFilter&&this.selectedSessionFilter!==s.id)continue;const t=this.createSessionElement(s);e.appendChild(t)}}createSessionElement(e){const t=this.expandedSessions.has(e.id)||e.expanded;let s;try{const t=e.timestamp instanceof Date?e.timestamp:new Date(e.timestamp);isNaN(t.getTime())?(s="Invalid Date",console.warn("ActivityTree: Invalid session timestamp:",e.timestamp)):s=t.toLocaleString()}catch(l){s="Invalid Date",console.error("ActivityTree: Error formatting session timestamp:",l,e.timestamp)}const n=document.createElement("div");n.className="tree-node session",n.dataset.sessionId=e.id;const o=t?"▼":"▶",i=this.getAllAgents(e).length,a=e.currentTodos?e.currentTodos.length:0,r=e.userInstructions?e.userInstructions.length:0;return console.log(`ActivityTree: Rendering session ${e.id}: ${i} agents, ${r} instructions, ${a} todos at ${s}`),n.innerHTML=`\n <div class="tree-node-content" onclick="window.activityTreeInstance.toggleSession('${e.id}')">\n <span class="tree-expand-icon">${o}</span>\n <span class="tree-icon">🎯</span>\n <span class="tree-label">PM Session</span>\n <span class="tree-meta">${s} • ${i} agent(s) • ${r} instruction(s) • ${a} todo(s)</span>\n </div>\n <div class="tree-children" style="display: ${t?"block":"none"}">\n ${this.renderSessionContent(e)}\n </div>\n `,n}renderSessionContent(e){let t="";if(e.userInstructions&&e.userInstructions.length>0)for(let n of e.userInstructions.slice(-3))t+=this.renderUserInstructionElement(n,1);if(e.tools&&e.tools.length>0)for(let n of e.tools)t+=this.renderToolElement(n,1);const s=Array.from(e.agents.values()).sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp));for(let n of s)t+=this.renderAgentElement(n,1);return t}renderUserInstructionElement(e,t){return`\n <div class="tree-node user-instruction ${this.selectedItem&&"instruction"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":""}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">💬</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'instruction', event)">User: "${this.escapeHtml(e.preview)}"</span>\n <span class="tree-status status-active">instruction</span>\n </div>\n </div>\n `}renderTodoChecklistElement(e,t){const s=`checklist-${Date.now()}`,n=!1!==this.expandedTools.has(s),o=n?"▼":"▶";let i=0,a=0;e.forEach(e=>{"completed"===e.status?i++:"in_progress"===e.status&&a++});let r="";r=a>0?`${a} in progress, ${i} completed`:i===e.length&&e.length>0?`All ${e.length} completed`:`${e.length} todo(s)`;let l=`\n <div class="tree-node todo-checklist" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">☑️</span>\n <span class="tree-label">TODOs</span>\n <span class="tree-params">${r}</span>\n <span class="tree-status status-active">checklist</span>\n </div>\n `;if(n){l+='<div class="tree-children">';for(let s of e){const e=this.getCheckboxIcon(s.status),n=`status-${s.status}`,o="in_progress"===s.status?s.activeForm:s.content;l+=`\n <div class="tree-node todo-item ${n}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${e}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${s.status.replace("_"," ")}</span>\n </div>\n </div>\n `}l+="</div>"}return l+="</div>",l}renderAgentElement(e,t){const s="active"===e.status?"status-active":"status-completed",n=this.expandedAgents.has(e.id),o=e.tools&&e.tools.length>0,i=e.subagents&&e.subagents.size>0,a=o||i,r=a?n?"▼":"▶":"",l=this.selectedItem&&"agent"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":"",c=e.instanceCount>1?` (${e.instanceCount}x)`:"";let d="";if(!n&&a){const t=[];if(e.currentTodos&&e.currentTodos.length>0){const s=e.currentTodos.find(e=>"in_progress"===e.status);s&&t.push(`📝 ${s.activeForm||s.content}`)}e.currentTool&&t.push(`${e.currentTool.icon} ${e.currentTool.name}`),t.length>0&&(d=` • ${t.join(" • ")}`)}let p=`\n <div class="tree-node agent ${s} ${l}" data-level="${t}">\n <div class="tree-node-content">\n ${r?`<span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleAgent('${e.id}'); event.stopPropagation();">${r}</span>`:'<span class="tree-expand-icon"></span>'}\n <span class="tree-icon">${e.icon}</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'agent', event)">${e.name}${c}${d}</span>\n <span class="tree-status ${s}">${e.status}</span>\n </div>\n `;if(a&&n){if(p+='<div class="tree-children">',o)for(let s of e.tools)p+=this.renderToolElement(s,t+1);if(i){const s=Array.from(e.subagents.values());for(let e of s)p+=this.renderAgentElement(e,t+1)}p+="</div>"}return p+="</div>",p}renderToolElement(e,t){const s=`status-${e.status}`,n=this.getToolParams(e),o=this.selectedItem&&"tool"===this.selectedItem.type&&this.selectedItem.data.id===e.id?"selected":"",i=this.getToolStatusIcon(e.status),a=this.getToolStatusLabel(e.status),r=e.callCount>1?` (${e.callCount} calls)`:"";return`\n <div class="tree-node tool ${s} ${o}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${e.icon}</span>\n <span class="tree-status-icon">${i}</span>\n <span class="tree-label clickable" onclick="window.activityTreeInstance.selectItem(${this.escapeJson(e)}, 'tool', event)">${e.name}${r}</span>\n <span class="tree-params">${n}</span>\n <span class="tree-status ${s}">${a}</span>\n </div>\n </div>\n `}getToolParams(e){if(!e.params)return"";if("Read"===e.name&&e.params.file_path)return e.params.file_path;if("Edit"===e.name&&e.params.file_path)return e.params.file_path;if("Write"===e.name&&e.params.file_path)return e.params.file_path;if("Bash"===e.name&&e.params.command){const t=e.params.command;return t.length>50?t.substring(0,50)+"...":t}return"WebFetch"===e.name&&e.params.url?e.params.url:""}getStatusIcon(e){return{pending:"⏸️",in_progress:"🔄",completed:"✅"}[e]||"❓"}getCheckboxIcon(e){return{pending:"⏳",in_progress:"🔄",completed:"✅"}[e]||"❓"}getAgentIcon(e){return{engineer:"👷",research:"🔬",qa:"🧪",ops:"⚙️",pm:"📊",architect:"🏗️","project manager":"📊"}[e.toLowerCase()]||"🤖"}getAllAgents(e){const t=[],s=e=>{if(e)for(let n of e.values())t.push(n),n.subagents&&n.subagents.size>0&&s(n.subagents)};return s(e.agents),t}renderTodoWriteElement(e,t){const s=e.id,n=this.expandedTools.has(s),o=n?"▼":"▶",i=e.todos||[];let a=0,r=0;i.forEach(e=>{"completed"===e.status?a++:"in_progress"===e.status&&r++});const l=i.find(e=>"in_progress"===e.status),c=l?` • 🔄 ${l.activeForm||l.content}`:"";let d="";d=r>0?`${r} in progress, ${a}/${i.length} done`:a===i.length&&i.length>0?`All ${i.length} completed ✅`:`${a}/${i.length} done`;let p=`\n <div class="tree-node todowrite ${l?"has-active":""}" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoWrite('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">📝</span>\n <span class="tree-label">TodoWrite${e.updateCount>1?` (${e.updateCount} updates)`:""}${n?"":c}</span>\n <span class="tree-params">${d}</span>\n <span class="tree-status status-active">todos</span>\n </div>\n `;if(n&&i.length>0){p+='<div class="tree-children">';for(let e of i){const s=this.getCheckboxIcon(e.status),n=`status-${e.status}`,o="in_progress"===e.status?e.activeForm:e.content;p+=`\n <div class="tree-node todo-item ${n} ${e===l?"current-active":""}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${s}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${e.status.replace("_"," ")}</span>\n </div>\n </div>\n `}p+="</div>"}return p+="</div>",p}toggleTodoWrite(e){this.expandedTools.has(e)?this.expandedTools.delete(e):this.expandedTools.add(e),this.renderTree()}getToolIcon(e){return{read:"👁️",write:"✍️",edit:"✏️",bash:"💻",webfetch:"🌐",grep:"🔍",glob:"📂",todowrite:"📝"}[e.toLowerCase()]||"🔧"}getToolStatusIcon(e){return{in_progress:"⏳",completed:"✅",failed:"❌",error:"❌",pending:"⏸️",active:"🔄"}[e]||"❓"}getToolStatusLabel(e){return{in_progress:"in progress",completed:"completed",failed:"failed",error:"error",pending:"pending",active:"active"}[e]||e}toggleSession(e){this.expandedSessions.has(e)?this.expandedSessions.delete(e):this.expandedSessions.add(e);const t=this.sessions.get(e);t&&(t.expanded=this.expandedSessions.has(e)),this.renderTree()}expandAllSessions(){for(let e of this.sessions.keys()){this.expandedSessions.add(e);const t=this.sessions.get(e);t&&(t.expanded=!0)}this.renderTree()}collapseAllSessions(){this.expandedSessions.clear();for(let e of this.sessions.values())e.expanded=!1;this.renderTree()}updateStats(){const e=this.countTotalNodes(),t=this.countActiveNodes(),s=this.calculateMaxDepth(),n=document.getElementById("node-count"),o=document.getElementById("active-count"),i=document.getElementById("tree-depth");n&&(n.textContent=e),o&&(o.textContent=t),i&&(i.textContent=s),console.log(`ActivityTree: Stats updated - Nodes: ${e}, Active: ${t}, Depth: ${s}`)}countTotalNodes(){let e=0;for(let t of this.sessions.values()){e+=1,e+=t.agents.size,t.userInstructions&&(e+=t.userInstructions.length),t.todos&&(e+=t.todos.length),t.tools&&(e+=t.tools.length);for(let s of t.agents.values())s.tools&&(e+=s.tools.length)}return e}countActiveNodes(){let e=0;for(let t of this.sessions.values()){if("active"===t.status&&e++,t.todos)for(let s of t.todos)"in_progress"===s.status&&e++;if(t.tools)for(let s of t.tools)"in_progress"===s.status&&e++;for(let s of t.agents.values())if("active"===s.status&&e++,s.tools)for(let t of s.tools)"in_progress"===t.status&&e++}return e}calculateMaxDepth(){let e=0;for(let t of this.sessions.values()){let s=1;t.userInstructions&&t.userInstructions.length>0&&(s=Math.max(s,2)),t.todos&&t.todos.length>0&&(s=Math.max(s,3)),t.tools&&t.tools.length>0&&(s=Math.max(s,2));for(let e of t.agents.values())e.tools&&e.tools.length>0&&(s=Math.max(s,3));e=Math.max(e,s)}return e}toggleAgent(e){this.expandedAgents.has(e)?this.expandedAgents.delete(e):this.expandedAgents.add(e),this.renderTree()}toggleTool(e){console.log("Tool expansion is disabled. Tools now show data in the left pane when clicked.")}toggleTodoChecklist(e){this.expandedTools.has(e)?this.expandedTools.delete(e):this.expandedTools.add(e),this.renderTree()}renderPinnedTodosElement(e,t){const s=`pinned-todos-${Date.now()}`,n=!1!==this.expandedTools.has(s),o=n?"▼":"▶",i=e.todos||[];let a=0,r=0;i.forEach(e=>{"completed"===e.status?a++:"in_progress"===e.status&&r++});let l="";l=r>0?`${r} in progress, ${a} completed`:a===i.length&&i.length>0?`All ${i.length} completed`:`${i.length} todo(s)`;let c=`\n <div class="tree-node pinned-todos" data-level="${t}">\n <div class="tree-node-content">\n <span class="tree-expand-icon" onclick="window.activityTreeInstance.toggleTodoChecklist('${s}'); event.stopPropagation();">${o}</span>\n <span class="tree-icon">📌</span>\n <span class="tree-label">Pinned TODOs</span>\n <span class="tree-params">${l}</span>\n <span class="tree-status status-active">pinned</span>\n </div>\n `;if(n){c+='<div class="tree-children">';for(let e of i){const s=this.getCheckboxIcon(e.status),n=`status-${e.status}`,o="in_progress"===e.status?e.activeForm:e.content;c+=`\n <div class="tree-node todo-item ${n}" data-level="${t+1}">\n <div class="tree-node-content">\n <span class="tree-expand-icon"></span>\n <span class="tree-icon">${s}</span>\n <span class="tree-label">${this.escapeHtml(o)}</span>\n <span class="tree-status ${n}">${e.status.replace("_"," ")}</span>\n </div>\n </div>\n `}c+="</div>"}return c+="</div>",c}selectItem(e,t,s){s&&s.stopPropagation(),this.selectedItem={data:e,type:t},this.displayItemData(e,t),this.renderTree()}displayItemData(t,s){this.unifiedViewer||(this.unifiedViewer=new e("module-data-content")),this.unifiedViewer.display(t,s);const n=document.querySelector(".module-data-header h5");if(n){const e={agent:"🤖",tool:"🔧",instruction:"💬",session:"🎯",todo:"📝"}[s]||"📊",o=t.name||t.agentName||t.tool_name||"Item";n.textContent=`${e} ${s}: ${o}`}}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}resetZoom(){this.svg&&this.zoom&&this.svg.transition().duration(this.duration).call(this.zoom.transform,d3.zoomIdentity)}escapeJson(e){return JSON.stringify(e).replace(/'/g,"&apos;").replace(/"/g,"&quot;")}}window.ActivityTree=t;const s=()=>{let e=null;const s=()=>{e||(console.log("Creating new Activity Tree instance..."),e=new t,window.activityTreeInstance=e,window.activityTree=()=>e),setTimeout(()=>{console.log("Attempting to initialize Activity Tree visualization..."),e.initialize()},100)};document.addEventListener("tabChanged",t=>{t.detail&&"activity"===t.detail.newTab&&(console.log("Tab changed to activity, initializing tree..."),s(),e&&setTimeout(()=>{e.renderWhenVisible(),e.forceShow()},150))});const n=document.querySelector(".tab-button.active");n&&"activity"===n.getAttribute("data-tab")&&(console.log("Activity tab is active on load, initializing tree..."),s());const o=document.getElementById("activity-tab");o&&o.classList.contains("active")&&(console.log("Activity panel is active on load, initializing tree..."),e||s())};"loading"===document.readyState?document.addEventListener("DOMContentLoaded",s):s();
2
- //# sourceMappingURL=activity-tree.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"activity-tree.js","sources":["../../js/components/activity-tree.js"],"sourcesContent":["/**\n * Activity Tree Component - Linear Tree View\n * \n * HTML/CSS-based linear tree visualization for showing PM activity hierarchy.\n * Replaces D3.js with simpler, cleaner linear tree structure.\n * Uses UnifiedDataViewer for consistent data display with Tools viewer.\n */\n\n// Import UnifiedDataViewer for consistent data display\nimport { UnifiedDataViewer } from './unified-data-viewer.js';\n\nclass ActivityTree {\n constructor() {\n this.container = null;\n this.events = [];\n this.processedEventIds = new Set(); // Track which events we've already processed\n this.sessions = new Map();\n this.currentSession = null;\n this.selectedSessionFilter = 'all';\n this.timeRange = '30min';\n this.searchTerm = '';\n this.initialized = false;\n this.expandedSessions = new Set();\n this.expandedAgents = new Set();\n this.expandedTools = new Set();\n this.selectedItem = null;\n this.sessionFilterInitialized = false; // Flag to prevent initialization loop\n \n // Add debounce for renderTree to prevent excessive DOM rebuilds\n this.renderTreeDebounced = this.debounce(() => this.renderTree(), 100);\n }\n \n /**\n * Debounce helper to prevent excessive DOM updates\n */\n debounce(func, wait) {\n let timeout;\n return function executedFunction(...args) {\n const later = () => {\n clearTimeout(timeout);\n func(...args);\n };\n clearTimeout(timeout);\n timeout = setTimeout(later, wait);\n };\n }\n\n /**\n * Initialize the activity tree\n */\n initialize() {\n console.log('ActivityTree.initialize() called, initialized:', this.initialized);\n \n if (this.initialized) {\n console.log('Activity tree already initialized, skipping');\n return;\n }\n \n this.container = document.getElementById('activity-tree-container');\n if (!this.container) {\n this.container = document.getElementById('activity-tree');\n if (!this.container) {\n console.error('Activity tree container not found in DOM');\n return;\n }\n }\n \n // Check if the container is visible before initializing\n const tabPanel = document.getElementById('activity-tab');\n if (!tabPanel) {\n console.error('Activity tab panel (#activity-tab) not found in DOM');\n return;\n }\n \n // Initialize even if tab is not active\n if (!tabPanel.classList.contains('active')) {\n console.log('Activity tab not active, initializing but deferring render');\n this.setupControls();\n this.subscribeToEvents();\n this.initialized = true;\n return;\n }\n\n this.setupControls();\n this.createLinearTreeView();\n this.subscribeToEvents();\n \n this.initialized = true;\n console.log('Activity tree initialization complete');\n }\n\n /**\n * Force show the tree visualization\n */\n forceShow() {\n console.log('ActivityTree.forceShow() called');\n \n if (!this.container) {\n this.container = document.getElementById('activity-tree-container') || document.getElementById('activity-tree');\n if (!this.container) {\n console.error('Cannot find activity tree container');\n return;\n }\n }\n \n this.createLinearTreeView();\n this.renderTree();\n }\n \n /**\n * Render the visualization when tab becomes visible\n */\n renderWhenVisible() {\n console.log('ActivityTree.renderWhenVisible() called');\n \n if (!this.initialized) {\n console.log('Not initialized yet, calling initialize...');\n this.initialize();\n return;\n }\n \n this.createLinearTreeView();\n this.renderTree();\n }\n\n /**\n * Setup control handlers\n */\n setupControls() {\n // Time range filter dropdown\n const timeRangeSelect = document.getElementById('time-range');\n if (timeRangeSelect) {\n timeRangeSelect.addEventListener('change', (e) => {\n this.timeRange = e.target.value;\n console.log(`ActivityTree: Time range changed to: ${this.timeRange}`);\n this.renderTree();\n });\n }\n\n // Listen for session filter changes from SessionManager\n document.addEventListener('sessionFilterChanged', (e) => {\n this.selectedSessionFilter = e.detail.sessionId || 'all';\n console.log(`ActivityTree: Session filter changed to: ${this.selectedSessionFilter} (from SessionManager)`);\n this.renderTree();\n });\n\n // Also listen for sessionChanged for backward compatibility\n document.addEventListener('sessionChanged', (e) => {\n this.selectedSessionFilter = e.detail.sessionId || 'all';\n console.log(`ActivityTree: Session changed to: ${this.selectedSessionFilter} (from SessionManager - backward compat)`);\n this.renderTree();\n });\n\n // Initialize with current session filter from SessionManager (prevent loop)\n setTimeout(() => {\n if (window.sessionManager && !this.sessionFilterInitialized) {\n const currentFilter = window.sessionManager.getCurrentFilter();\n if (currentFilter !== this.selectedSessionFilter) {\n this.selectedSessionFilter = currentFilter || 'all';\n console.log(`ActivityTree: Initialized with current session filter: ${this.selectedSessionFilter}`);\n this.sessionFilterInitialized = true; // Prevent re-initialization\n this.renderTree();\n }\n }\n }, 100); // Small delay to ensure SessionManager is initialized\n\n // Expand all button - expand all sessions\n const expandAllBtn = document.getElementById('expand-all');\n if (expandAllBtn) {\n expandAllBtn.addEventListener('click', () => this.expandAllSessions());\n }\n\n // Collapse all button - collapse all sessions\n const collapseAllBtn = document.getElementById('collapse-all');\n if (collapseAllBtn) {\n collapseAllBtn.addEventListener('click', () => this.collapseAllSessions());\n }\n\n // Reset zoom button functionality\n const resetZoomBtn = document.getElementById('reset-zoom');\n if (resetZoomBtn) {\n resetZoomBtn.style.display = 'inline-block';\n resetZoomBtn.addEventListener('click', () => this.resetZoom());\n }\n\n // Search input\n const searchInput = document.getElementById('activity-search');\n if (searchInput) {\n searchInput.addEventListener('input', (e) => {\n this.searchTerm = e.target.value.toLowerCase();\n this.renderTree();\n });\n }\n }\n\n /**\n * Create the linear tree view container\n */\n createLinearTreeView() {\n console.log('Creating linear tree view');\n \n // Clear container\n this.container.innerHTML = '';\n \n // Create main tree container\n const treeContainer = document.createElement('div');\n treeContainer.id = 'linear-tree';\n treeContainer.className = 'linear-tree';\n \n this.container.appendChild(treeContainer);\n \n console.log('Linear tree view created');\n }\n\n /**\n * Subscribe to socket events\n */\n subscribeToEvents() {\n if (!window.socketClient) {\n console.warn('Socket client not available for activity tree');\n setTimeout(() => this.subscribeToEvents(), 1000);\n return;\n }\n\n console.log('ActivityTree: Setting up event subscription');\n\n // Subscribe to event updates from the socket client\n // FIXED: Now correctly receives both events AND sessions from socket client\n window.socketClient.onEventUpdate((events, sessions) => {\n console.log(`ActivityTree: onEventUpdate called with ${events.length} total events and ${sessions.size} sessions`);\n \n // IMPORTANT: Don't clear sessions! We need to preserve the accumulated agent data\n // Only create new sessions if they don't exist yet\n for (const [sessionId, sessionData] of sessions.entries()) {\n if (!this.sessions.has(sessionId)) {\n // Create new session only if it doesn't exist\n const activitySession = {\n id: sessionId,\n timestamp: new Date(sessionData.lastActivity || sessionData.startTime || new Date()),\n expanded: this.expandedSessions.has(sessionId) || true, // Preserve expansion state\n agents: new Map(),\n todos: [],\n userInstructions: [],\n tools: [],\n toolsMap: new Map(),\n status: 'active',\n currentTodoTool: null,\n // Preserve additional session metadata\n working_directory: sessionData.working_directory,\n git_branch: sessionData.git_branch,\n eventCount: sessionData.eventCount\n };\n this.sessions.set(sessionId, activitySession);\n } else {\n // Update existing session metadata without clearing accumulated data\n // CRITICAL: Preserve all accumulated data (tools, agents, todos, etc.)\n const existingSession = this.sessions.get(sessionId);\n existingSession.timestamp = new Date(sessionData.lastActivity || sessionData.startTime || existingSession.timestamp);\n existingSession.eventCount = sessionData.eventCount;\n existingSession.status = sessionData.status || existingSession.status;\n // Update metadata without losing accumulated data\n existingSession.working_directory = sessionData.working_directory || existingSession.working_directory;\n existingSession.git_branch = sessionData.git_branch || existingSession.git_branch;\n // DO NOT reset tools, agents, todos, userInstructions, toolsMap, etc.\n // These are built up from events and must be preserved!\n }\n }\n \n // Process only events we haven't seen before\n const newEvents = events.filter(event => {\n const eventId = event.id || `${event.type}-${event.timestamp}-${Math.random()}`;\n return !this.processedEventIds.has(eventId);\n });\n \n if (newEvents.length > 0) {\n console.log(`ActivityTree: Processing ${newEvents.length} new events`, newEvents);\n \n newEvents.forEach(event => {\n const eventId = event.id || `${event.type}-${event.timestamp}-${Math.random()}`;\n this.processedEventIds.add(eventId);\n this.processEvent(event);\n });\n }\n \n this.events = [...events];\n // Use debounced render to prevent excessive DOM rebuilds\n this.renderTreeDebounced();\n \n // Debug: Log session state after processing\n console.log(`ActivityTree: Sessions after sync with socket client:`, Array.from(this.sessions.entries()));\n });\n\n // Load existing data from socket client\n const socketState = window.socketClient?.getState();\n \n if (socketState && socketState.events.length > 0) {\n console.log(`ActivityTree: Loading existing data - ${socketState.events.length} events, ${socketState.sessions.size} sessions`);\n \n // Initialize from existing socket client data\n // Don't clear existing sessions - preserve accumulated data\n \n // Convert authoritative sessions Map to our format\n for (const [sessionId, sessionData] of socketState.sessions.entries()) {\n if (!this.sessions.has(sessionId)) {\n const activitySession = {\n id: sessionId,\n timestamp: new Date(sessionData.lastActivity || sessionData.startTime || new Date()),\n expanded: this.expandedSessions.has(sessionId) || true,\n agents: new Map(),\n todos: [],\n userInstructions: [],\n tools: [],\n toolsMap: new Map(),\n status: 'active',\n currentTodoTool: null,\n working_directory: sessionData.working_directory,\n git_branch: sessionData.git_branch,\n eventCount: sessionData.eventCount\n };\n this.sessions.set(sessionId, activitySession);\n }\n }\n \n // Process only events we haven't seen before\n const unprocessedEvents = socketState.events.filter(event => {\n const eventId = event.id || `${event.type}-${event.timestamp}-${Math.random()}`;\n return !this.processedEventIds.has(eventId);\n });\n \n if (unprocessedEvents.length > 0) {\n console.log(`ActivityTree: Processing ${unprocessedEvents.length} unprocessed events from initial load`);\n unprocessedEvents.forEach(event => {\n const eventId = event.id || `${event.type}-${event.timestamp}-${Math.random()}`;\n this.processedEventIds.add(eventId);\n this.processEvent(event);\n });\n }\n \n this.events = [...socketState.events];\n // Initial render can be immediate\n this.renderTree();\n \n // Debug: Log initial session state\n console.log(`ActivityTree: Initial sessions state:`, Array.from(this.sessions.entries()));\n } else {\n console.log('ActivityTree: No existing events found');\n this.events = [];\n this.sessions.clear();\n this.renderTree();\n }\n }\n\n /**\n * Process an event and update the session structure\n */\n processEvent(event) {\n if (!event) {\n console.log('ActivityTree: Ignoring null event');\n return;\n }\n \n // Determine event type\n let eventType = this.getEventType(event);\n if (!eventType) {\n return;\n }\n \n console.log(`ActivityTree: Processing event: ${eventType}`, event);\n \n // Fix timestamp processing - ensure we get a valid date\n let timestamp;\n if (event.timestamp) {\n // Handle both ISO strings and already parsed dates\n timestamp = new Date(event.timestamp);\n // Check if date is valid\n if (isNaN(timestamp.getTime())) {\n console.warn('ActivityTree: Invalid timestamp, using current time:', event.timestamp);\n timestamp = new Date();\n }\n } else {\n console.warn('ActivityTree: No timestamp found, using current time');\n timestamp = new Date();\n }\n \n // Get session ID from event - this should match the authoritative sessions\n const sessionId = event.session_id || event.data?.session_id;\n \n // Skip events without session ID - they can't be properly categorized\n if (!sessionId) {\n console.log(`ActivityTree: Skipping event without session_id: ${eventType}`);\n return;\n }\n \n // Find the session - it should already exist from authoritative sessions\n if (!this.sessions.has(sessionId)) {\n console.warn(`ActivityTree: Session ${sessionId} not found in authoritative sessions - skipping event`);\n return;\n }\n \n const session = this.sessions.get(sessionId);\n \n switch (eventType) {\n case 'Start':\n // New PM session started\n this.currentSession = session;\n break;\n case 'user_prompt':\n this.processUserInstruction(event, session);\n break;\n case 'TodoWrite':\n // TodoWrite is now handled as a tool in 'tool_use' events\n // Skip separate TodoWrite processing to avoid duplication\n break;\n case 'SubagentStart':\n this.processSubagentStart(event, session);\n break;\n case 'SubagentStop':\n this.processSubagentStop(event, session);\n break;\n case 'PreToolUse':\n this.processToolUse(event, session);\n break;\n case 'PostToolUse':\n this.updateToolStatus(event, session, 'completed');\n break;\n }\n \n this.updateStats();\n }\n\n /**\n * Get event type from event data\n */\n getEventType(event) {\n if (event.hook_event_name) {\n return event.hook_event_name;\n }\n \n if (event.type === 'hook' && event.subtype) {\n const mapping = {\n 'pre_tool': 'PreToolUse',\n 'post_tool': 'PostToolUse',\n 'subagent_start': 'SubagentStart',\n 'subagent_stop': 'SubagentStop',\n 'todo_write': 'TodoWrite'\n };\n return mapping[event.subtype];\n }\n \n if (event.type === 'todo' && event.subtype === 'updated') {\n return 'TodoWrite';\n }\n \n if (event.type === 'subagent') {\n if (event.subtype === 'started') return 'SubagentStart';\n if (event.subtype === 'stopped') return 'SubagentStop';\n }\n \n if (event.type === 'start') {\n return 'Start';\n }\n \n if (event.type === 'user_prompt' || event.subtype === 'user_prompt') {\n return 'user_prompt';\n }\n \n return null;\n }\n\n // getSessionId method removed - now using authoritative session IDs directly from socket client\n\n /**\n * Process user instruction/prompt event\n */\n processUserInstruction(event, session) {\n const promptText = event.prompt_text || event.data?.prompt_text || event.prompt || '';\n if (!promptText) return;\n \n const instruction = {\n id: `instruction-${session.id}-${Date.now()}`,\n text: promptText,\n preview: promptText.length > 100 ? promptText.substring(0, 100) + '...' : promptText,\n timestamp: event.timestamp || new Date().toISOString(),\n type: 'user_instruction'\n };\n \n // NEW USER PROMPT: Only collapse agents if we have existing ones\n // Don't clear - we want to keep the history!\n if (session.agents.size > 0) {\n console.log('ActivityTree: New user prompt detected, collapsing previous agents');\n \n // Mark all existing agents as completed (not active)\n for (let agent of session.agents.values()) {\n if (agent.status === 'active') {\n agent.status = 'completed';\n }\n // Collapse all existing agents\n this.expandedAgents.delete(agent.id);\n }\n }\n \n // Reset current active agent for new work\n session.currentActiveAgent = null;\n \n // Add to session's user instructions\n session.userInstructions.push(instruction);\n \n // Keep only last 5 instructions to prevent memory bloat\n if (session.userInstructions.length > 5) {\n session.userInstructions = session.userInstructions.slice(-5);\n }\n }\n\n /**\n * Process TodoWrite event - attach TODOs to session and active agent\n */\n processTodoWrite(event, session) {\n let todos = event.todos || event.data?.todos || event.data || [];\n \n if (todos && typeof todos === 'object' && todos.todos) {\n todos = todos.todos;\n }\n \n if (!Array.isArray(todos) || todos.length === 0) {\n return;\n }\n\n // Update session's current todos for latest state tracking\n session.currentTodos = todos.map(todo => ({\n content: todo.content,\n activeForm: todo.activeForm,\n status: todo.status,\n timestamp: event.timestamp\n }));\n\n // Find the appropriate agent to attach this TodoWrite to\n let targetAgent = session.currentActiveAgent;\n \n if (!targetAgent) {\n // Fall back to most recent active agent\n const activeAgents = this.getAllAgents(session)\n .filter(agent => agent.status === 'active' || agent.status === 'in_progress')\n .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));\n \n if (activeAgents.length > 0) {\n targetAgent = activeAgents[0];\n } else {\n // If no active agents, check if this is PM-level\n const allAgents = this.getAllAgents(session);\n const pmAgent = allAgents.find(a => a.isPM);\n if (pmAgent) {\n targetAgent = pmAgent;\n } else if (allAgents.length > 0) {\n targetAgent = allAgents[0];\n }\n }\n }\n\n // Attach or update TodoWrite for the agent\n if (targetAgent) {\n if (!targetAgent.todoWritesMap) {\n targetAgent.todoWritesMap = new Map();\n }\n if (!targetAgent.todoWrites) {\n targetAgent.todoWrites = [];\n }\n \n // Check if we already have a TodoWrite instance\n const existingTodoWrite = targetAgent.todoWritesMap.get('TodoWrite');\n \n if (existingTodoWrite) {\n // Update existing TodoWrite instance\n existingTodoWrite.todos = todos;\n existingTodoWrite.timestamp = event.timestamp;\n existingTodoWrite.updateCount = (existingTodoWrite.updateCount || 1) + 1;\n } else {\n // Create new TodoWrite instance\n const todoWriteInstance = {\n id: `todowrite-${targetAgent.id}-${Date.now()}`,\n name: 'TodoWrite',\n type: 'todowrite',\n icon: '📝',\n timestamp: event.timestamp,\n status: 'completed',\n todos: todos,\n params: {\n todos: todos\n },\n updateCount: 1\n };\n \n targetAgent.todoWritesMap.set('TodoWrite', todoWriteInstance);\n targetAgent.todoWrites = [todoWriteInstance]; // Keep single instance\n }\n \n // Update agent's current todos for display when collapsed\n targetAgent.currentTodos = todos;\n } else {\n // No agent found, attach to session level\n if (!session.todoWrites) {\n session.todoWrites = [];\n }\n if (!session.todoWritesMap) {\n session.todoWritesMap = new Map();\n }\n \n const existingTodoWrite = session.todoWritesMap.get('TodoWrite');\n if (existingTodoWrite) {\n existingTodoWrite.todos = todos;\n existingTodoWrite.timestamp = event.timestamp;\n existingTodoWrite.updateCount = (existingTodoWrite.updateCount || 1) + 1;\n } else {\n const todoWriteInstance = {\n id: `todowrite-session-${Date.now()}`,\n name: 'TodoWrite',\n type: 'todowrite',\n icon: '📝',\n timestamp: event.timestamp,\n status: 'completed',\n todos: todos,\n updateCount: 1\n };\n session.todoWritesMap.set('TodoWrite', todoWriteInstance);\n session.todoWrites = [todoWriteInstance];\n }\n }\n }\n\n /**\n * Process SubagentStart event\n */\n processSubagentStart(event, session) {\n const agentName = event.agent_name || event.data?.agent_name || event.data?.agent_type || event.agent_type || event.agent || 'unknown';\n const agentSessionId = event.session_id || event.data?.session_id;\n const parentAgent = event.parent_agent || event.data?.parent_agent;\n \n // Use a composite key based on agent name and session to find existing instances\n // This ensures we track unique agent instances per session\n const agentKey = `${agentName}-${agentSessionId || 'no-session'}`;\n \n // Check if this exact agent already exists (same name and session)\n let existingAgent = null;\n const allAgents = this.getAllAgents(session);\n existingAgent = allAgents.find(a => \n a.name === agentName && \n a.sessionId === agentSessionId &&\n a.status === 'active' // Only reuse if still active\n );\n \n let agent;\n if (existingAgent) {\n // Update existing active agent\n agent = existingAgent;\n agent.timestamp = event.timestamp;\n agent.instanceCount = (agent.instanceCount || 1) + 1;\n // Auto-expand the active agent\n this.expandedAgents.add(agent.id);\n } else {\n // Create new agent instance for first occurrence\n const agentId = `agent-${agentKey}-${Date.now()}`;\n agent = {\n id: agentId,\n name: agentName,\n type: 'agent',\n icon: this.getAgentIcon(agentName),\n timestamp: event.timestamp,\n status: 'active',\n tools: [],\n subagents: new Map(), // Store nested subagents\n sessionId: agentSessionId,\n parentAgent: parentAgent,\n isPM: agentName.toLowerCase() === 'pm' || agentName.toLowerCase().includes('project manager'),\n instanceCount: 1,\n toolsMap: new Map() // Track unique tools by name\n };\n \n // If this is a subagent, nest it under the parent agent\n if (parentAgent) {\n // Find the parent agent in the session\n let parent = null;\n for (let [id, ag] of session.agents.entries()) {\n if (ag.sessionId === parentAgent || ag.name === parentAgent) {\n parent = ag;\n break;\n }\n }\n \n if (parent) {\n // Add as nested subagent\n if (!parent.subagents) {\n parent.subagents = new Map();\n }\n parent.subagents.set(agent.id, agent);\n } else {\n // No parent found, add to session level\n session.agents.set(agent.id, agent);\n }\n } else {\n // Top-level agent, add to session\n session.agents.set(agent.id, agent);\n }\n \n // Auto-expand new agents\n this.expandedAgents.add(agent.id);\n }\n \n // Track the currently active agent for tool/todo association\n session.currentActiveAgent = agent;\n }\n\n /**\n * Process SubagentStop event\n */\n processSubagentStop(event, session) {\n const agentSessionId = event.session_id || event.data?.session_id;\n \n // Find and mark agent as completed\n if (agentSessionId && session.agents.has(agentSessionId)) {\n const agent = session.agents.get(agentSessionId);\n agent.status = 'completed';\n }\n }\n\n /**\n * Process tool use event\n * \n * DISPLAY RULES:\n * 1. TodoWrite is a privileged tool that ALWAYS appears first under the agent/PM\n * 2. Each tool appears only once per unique instance (updated in place)\n * 3. Tools are listed in order of creation (after TodoWrite)\n * 4. Tool instances are updated with new events as they arrive\n */\n processToolUse(event, session) {\n const toolName = event.tool_name || event.data?.tool_name || event.tool || event.data?.tool || 'unknown';\n const params = event.tool_parameters || event.data?.tool_parameters || event.parameters || event.data?.parameters || {};\n const agentSessionId = event.session_id || event.data?.session_id;\n\n // Find the appropriate agent to attach this tool to\n let targetAgent = session.currentActiveAgent;\n \n if (!targetAgent) {\n // Fall back to finding by session ID or most recent active\n const allAgents = this.getAllAgents(session);\n targetAgent = allAgents.find(a => a.sessionId === agentSessionId) ||\n allAgents.find(a => a.status === 'active') ||\n allAgents[0];\n }\n\n if (targetAgent) {\n if (!targetAgent.toolsMap) {\n targetAgent.toolsMap = new Map();\n }\n if (!targetAgent.tools) {\n targetAgent.tools = [];\n }\n \n // Check if we already have this tool instance\n // Use tool name + params hash for unique identification\n const toolKey = this.getToolKey(toolName, params);\n let existingTool = targetAgent.toolsMap.get(toolKey);\n \n if (existingTool) {\n // UPDATE RULE: Update existing tool instance in place\n existingTool.params = params;\n existingTool.timestamp = event.timestamp;\n existingTool.status = 'in_progress';\n existingTool.eventId = event.id;\n existingTool.callCount = (existingTool.callCount || 1) + 1;\n \n // Update current tool for collapsed display\n targetAgent.currentTool = existingTool;\n } else {\n // CREATE RULE: Create new tool instance\n const tool = {\n id: `tool-${targetAgent.id}-${toolName}-${Date.now()}`,\n name: toolName,\n type: 'tool',\n icon: this.getToolIcon(toolName),\n timestamp: event.timestamp,\n status: 'in_progress',\n params: params,\n eventId: event.id,\n callCount: 1,\n createdAt: event.timestamp // Track creation order\n };\n \n // Special handling for Task tool (subagent delegation)\n if (toolName === 'Task' && params.subagent_type) {\n tool.isSubagentTask = true;\n tool.subagentType = params.subagent_type;\n }\n \n targetAgent.toolsMap.set(toolKey, tool);\n \n // ORDERING RULE: TodoWrite always goes first, others in creation order\n if (toolName === 'TodoWrite') {\n // Insert TodoWrite at the beginning\n targetAgent.tools.unshift(tool);\n } else {\n // Append other tools in creation order\n targetAgent.tools.push(tool);\n }\n \n targetAgent.currentTool = tool;\n }\n } else {\n // No agent found, attach to session (PM level)\n // PM RULE: Same display rules apply - TodoWrite first, others in creation order\n if (!session.tools) {\n session.tools = [];\n }\n if (!session.toolsMap) {\n session.toolsMap = new Map();\n }\n \n const toolKey = this.getToolKey(toolName, params);\n let existingTool = session.toolsMap.get(toolKey);\n \n if (existingTool) {\n // UPDATE RULE: Update existing tool instance in place\n existingTool.params = params;\n existingTool.timestamp = event.timestamp;\n existingTool.status = 'in_progress';\n existingTool.eventId = event.id;\n existingTool.callCount = (existingTool.callCount || 1) + 1;\n session.currentTool = existingTool;\n } else {\n const tool = {\n id: `tool-session-${toolName}-${Date.now()}`,\n name: toolName,\n type: 'tool',\n icon: this.getToolIcon(toolName),\n timestamp: event.timestamp,\n status: 'in_progress',\n params: params,\n eventId: event.id,\n callCount: 1,\n createdAt: event.timestamp // Track creation order\n };\n \n session.toolsMap.set(toolKey, tool);\n \n // ORDERING RULE: TodoWrite always goes first for PM too\n if (toolName === 'TodoWrite') {\n session.tools.unshift(tool);\n } else {\n session.tools.push(tool);\n }\n \n session.currentTool = tool;\n }\n }\n }\n\n /**\n * Generate unique key for tool instance identification\n * Tools are unique per name + certain parameter combinations\n */\n getToolKey(toolName, params) {\n // For TodoWrite, we want ONE instance per agent/PM that updates in place\n // So we use just the tool name as the key\n if (toolName === 'TodoWrite') {\n return 'TodoWrite'; // Single instance per agent/PM\n }\n \n // For other tools, we generally want one instance per tool type\n // that gets updated with each call (not creating new instances)\n let key = toolName;\n \n // Only add distinguishing params if we need multiple instances\n // For example, multiple files being edited simultaneously\n if (toolName === 'Edit' || toolName === 'Write' || toolName === 'Read') {\n if (params.file_path) {\n key += `-${params.file_path}`;\n }\n }\n \n // For search tools, we might want separate instances for different searches\n if ((toolName === 'Grep' || toolName === 'Glob') && params.pattern) {\n // Only add pattern if significantly different\n key += `-${params.pattern.substring(0, 20)}`;\n }\n \n // Most tools should have a single instance that updates\n // This prevents the tool list from growing unbounded\n return key;\n }\n\n /**\n * Update tool status after completion\n */\n updateToolStatus(event, session, status) {\n const toolName = event.tool_name || event.data?.tool_name || event.tool || 'unknown';\n const params = event.tool_parameters || event.data?.tool_parameters || event.parameters || event.data?.parameters || {};\n const agentSessionId = event.session_id || event.data?.session_id;\n \n // Generate the same key we used to store the tool\n const toolKey = this.getToolKey(toolName, params);\n \n // Find the appropriate agent\n let targetAgent = session.currentActiveAgent;\n \n if (!targetAgent) {\n const allAgents = this.getAllAgents(session);\n targetAgent = allAgents.find(a => a.sessionId === agentSessionId) ||\n allAgents.find(a => a.status === 'active');\n }\n \n if (targetAgent && targetAgent.toolsMap) {\n const tool = targetAgent.toolsMap.get(toolKey);\n if (tool) {\n tool.status = status;\n tool.completedAt = event.timestamp;\n if (event.data?.result || event.result) {\n tool.result = event.data?.result || event.result;\n }\n if (event.data?.duration_ms) {\n tool.duration = event.data.duration_ms;\n }\n return;\n }\n }\n \n // Check session-level tools\n if (session.toolsMap) {\n const tool = session.toolsMap.get(toolKey);\n if (tool) {\n tool.status = status;\n tool.completedAt = event.timestamp;\n if (event.data?.result || event.result) {\n tool.result = event.data?.result || event.result;\n }\n if (event.data?.duration_ms) {\n tool.duration = event.data.duration_ms;\n }\n return;\n }\n }\n \n console.log(`ActivityTree: Could not find tool to update status for ${toolName} with key ${toolKey} (event ${event.id})`);\n }\n\n /**\n * Render the linear tree view\n */\n renderTree() {\n const treeContainer = document.getElementById('linear-tree');\n if (!treeContainer) return;\n \n // Clear tree\n treeContainer.innerHTML = '';\n \n // Add sessions directly (no project root)\n const sortedSessions = Array.from(this.sessions.values())\n .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));\n \n for (let session of sortedSessions) {\n if (this.selectedSessionFilter !== 'all' && this.selectedSessionFilter !== session.id) {\n continue;\n }\n \n const sessionElement = this.createSessionElement(session);\n treeContainer.appendChild(sessionElement);\n }\n \n // Session filtering is now handled by the main session selector via event listeners\n }\n\n\n /**\n * Create session element\n */\n createSessionElement(session) {\n const isExpanded = this.expandedSessions.has(session.id) || session.expanded;\n \n // Ensure timestamp is valid and format it consistently\n let sessionTime;\n try {\n const sessionDate = session.timestamp instanceof Date ? session.timestamp : new Date(session.timestamp);\n if (isNaN(sessionDate.getTime())) {\n sessionTime = 'Invalid Date';\n console.warn('ActivityTree: Invalid session timestamp:', session.timestamp);\n } else {\n sessionTime = sessionDate.toLocaleString();\n }\n } catch (error) {\n sessionTime = 'Invalid Date';\n console.error('ActivityTree: Error formatting session timestamp:', error, session.timestamp);\n }\n \n const element = document.createElement('div');\n element.className = 'tree-node session';\n element.dataset.sessionId = session.id;\n \n const expandIcon = isExpanded ? '▼' : '▶';\n // Count ALL agents including nested ones\n const agentCount = this.getAllAgents(session).length;\n const todoCount = session.currentTodos ? session.currentTodos.length : 0;\n const instructionCount = session.userInstructions ? session.userInstructions.length : 0;\n \n console.log(`ActivityTree: Rendering session ${session.id}: ${agentCount} agents, ${instructionCount} instructions, ${todoCount} todos at ${sessionTime}`);\n \n element.innerHTML = `\n <div class=\"tree-node-content\" onclick=\"window.activityTreeInstance.toggleSession('${session.id}')\">\n <span class=\"tree-expand-icon\">${expandIcon}</span>\n <span class=\"tree-icon\">🎯</span>\n <span class=\"tree-label\">PM Session</span>\n <span class=\"tree-meta\">${sessionTime} • ${agentCount} agent(s) • ${instructionCount} instruction(s) • ${todoCount} todo(s)</span>\n </div>\n <div class=\"tree-children\" style=\"display: ${isExpanded ? 'block' : 'none'}\">\n ${this.renderSessionContent(session)}\n </div>\n `;\n \n return element;\n }\n\n /**\n * Render session content (user instructions, todos, agents, tools)\n * \n * PM DISPLAY RULES (documented inline):\n * 1. User instructions appear first (context)\n * 2. PM-level tools follow the same rules as agent tools:\n * - TodoWrite is privileged and appears first\n * - Other tools appear in creation order\n * - Each unique instance is updated in place\n * 3. Agents appear after PM tools\n */\n renderSessionContent(session) {\n let html = '';\n \n // Render user instructions first\n if (session.userInstructions && session.userInstructions.length > 0) {\n for (let instruction of session.userInstructions.slice(-3)) { // Show last 3 instructions\n html += this.renderUserInstructionElement(instruction, 1);\n }\n }\n \n // PM TOOL DISPLAY RULES:\n // Render PM-level tools (TodoWrite first, then others in creation order)\n // The session.tools array is already properly ordered by processToolUse\n if (session.tools && session.tools.length > 0) {\n for (let tool of session.tools) {\n html += this.renderToolElement(tool, 1);\n }\n }\n \n // Render agents (they will have their own TodoWrite at the top)\n const agents = Array.from(session.agents.values())\n .sort((a, b) => new Date(b.timestamp) - new Date(a.timestamp));\n \n for (let agent of agents) {\n html += this.renderAgentElement(agent, 1);\n }\n \n return html;\n }\n\n /**\n * Render user instruction element\n */\n renderUserInstructionElement(instruction, level) {\n const isSelected = this.selectedItem && this.selectedItem.type === 'instruction' && this.selectedItem.data.id === instruction.id;\n const selectedClass = isSelected ? 'selected' : '';\n \n return `\n <div class=\"tree-node user-instruction ${selectedClass}\" data-level=\"${level}\">\n <div class=\"tree-node-content\">\n <span class=\"tree-expand-icon\"></span>\n <span class=\"tree-icon\">💬</span>\n <span class=\"tree-label clickable\" onclick=\"window.activityTreeInstance.selectItem(${this.escapeJson(instruction)}, 'instruction', event)\">User: \"${this.escapeHtml(instruction.preview)}\"</span>\n <span class=\"tree-status status-active\">instruction</span>\n </div>\n </div>\n `;\n }\n\n /**\n * Render TODO checklist element\n */\n renderTodoChecklistElement(todos, level) {\n const checklistId = `checklist-${Date.now()}`;\n const isExpanded = this.expandedTools.has(checklistId) !== false; // Default to expanded\n const expandIcon = isExpanded ? '▼' : '▶';\n \n // Calculate status summary\n let completedCount = 0;\n let inProgressCount = 0;\n let pendingCount = 0;\n \n todos.forEach(todo => {\n if (todo.status === 'completed') completedCount++;\n else if (todo.status === 'in_progress') inProgressCount++;\n else pendingCount++;\n });\n \n let statusSummary = '';\n if (inProgressCount > 0) {\n statusSummary = `${inProgressCount} in progress, ${completedCount} completed`;\n } else if (completedCount === todos.length && todos.length > 0) {\n statusSummary = `All ${todos.length} completed`;\n } else {\n statusSummary = `${todos.length} todo(s)`;\n }\n \n let html = `\n <div class=\"tree-node todo-checklist\" data-level=\"${level}\">\n <div class=\"tree-node-content\">\n <span class=\"tree-expand-icon\" onclick=\"window.activityTreeInstance.toggleTodoChecklist('${checklistId}'); event.stopPropagation();\">${expandIcon}</span>\n <span class=\"tree-icon\">☑️</span>\n <span class=\"tree-label\">TODOs</span>\n <span class=\"tree-params\">${statusSummary}</span>\n <span class=\"tree-status status-active\">checklist</span>\n </div>\n `;\n \n // Show expanded todo items if expanded\n if (isExpanded) {\n html += '<div class=\"tree-children\">';\n for (let todo of todos) {\n const statusIcon = this.getCheckboxIcon(todo.status);\n const statusClass = `status-${todo.status}`;\n const displayText = todo.status === 'in_progress' ? todo.activeForm : todo.content;\n \n html += `\n <div class=\"tree-node todo-item ${statusClass}\" data-level=\"${level + 1}\">\n <div class=\"tree-node-content\">\n <span class=\"tree-expand-icon\"></span>\n <span class=\"tree-icon\">${statusIcon}</span>\n <span class=\"tree-label\">${this.escapeHtml(displayText)}</span>\n <span class=\"tree-status ${statusClass}\">${todo.status.replace('_', ' ')}</span>\n </div>\n </div>\n `;\n }\n html += '</div>';\n }\n \n html += '</div>';\n return html;\n }\n\n /**\n * Render agent element with proper nesting\n */\n renderAgentElement(agent, level) {\n const statusClass = agent.status === 'active' ? 'status-active' : 'status-completed';\n const isExpanded = this.expandedAgents.has(agent.id);\n const hasTools = agent.tools && agent.tools.length > 0;\n const hasSubagents = agent.subagents && agent.subagents.size > 0;\n const hasContent = hasTools || hasSubagents;\n const isSelected = this.selectedItem && this.selectedItem.type === 'agent' && this.selectedItem.data.id === agent.id;\n \n const expandIcon = hasContent ? (isExpanded ? '▼' : '▶') : '';\n const selectedClass = isSelected ? 'selected' : '';\n \n // Add instance count if called multiple times\n const instanceIndicator = agent.instanceCount > 1 ? ` (${agent.instanceCount}x)` : '';\n \n // Build status display for collapsed state\n let collapsedStatus = '';\n if (!isExpanded && hasContent) {\n const parts = [];\n if (agent.currentTodos && agent.currentTodos.length > 0) {\n const inProgress = agent.currentTodos.find(t => t.status === 'in_progress');\n if (inProgress) {\n parts.push(`📝 ${inProgress.activeForm || inProgress.content}`);\n }\n }\n if (agent.currentTool) {\n parts.push(`${agent.currentTool.icon} ${agent.currentTool.name}`);\n }\n if (parts.length > 0) {\n collapsedStatus = ` • ${parts.join(' • ')}`;\n }\n }\n \n let html = `\n <div class=\"tree-node agent ${statusClass} ${selectedClass}\" data-level=\"${level}\">\n <div class=\"tree-node-content\">\n ${expandIcon ? `<span class=\"tree-expand-icon\" onclick=\"window.activityTreeInstance.toggleAgent('${agent.id}'); event.stopPropagation();\">${expandIcon}</span>` : '<span class=\"tree-expand-icon\"></span>'}\n <span class=\"tree-icon\">${agent.icon}</span>\n <span class=\"tree-label clickable\" onclick=\"window.activityTreeInstance.selectItem(${this.escapeJson(agent)}, 'agent', event)\">${agent.name}${instanceIndicator}${collapsedStatus}</span>\n <span class=\"tree-status ${statusClass}\">${agent.status}</span>\n </div>\n `;\n \n // Render nested content when expanded\n if (hasContent && isExpanded) {\n html += '<div class=\"tree-children\">';\n \n // DISPLAY ORDER RULES (documented inline):\n // 1. TodoWrite is a privileged tool - ALWAYS appears first\n // 2. Each tool appears only once per unique instance\n // 3. Tools are displayed in order of creation (after TodoWrite)\n // 4. Tool instances are updated in place as new events arrive\n \n // Render all tools in their proper order\n // The tools array is already ordered: TodoWrite first, then others by creation\n if (hasTools) {\n for (let tool of agent.tools) {\n html += this.renderToolElement(tool, level + 1);\n }\n }\n \n // Then render subagents (they will have their own TodoWrite at the top)\n if (hasSubagents) {\n const subagents = Array.from(agent.subagents.values());\n for (let subagent of subagents) {\n html += this.renderAgentElement(subagent, level + 1);\n }\n }\n \n html += '</div>';\n }\n \n html += '</div>';\n return html;\n }\n\n /**\n * Render tool element (non-expandable, clickable to show data)\n */\n renderToolElement(tool, level) {\n const statusClass = `status-${tool.status}`;\n const params = this.getToolParams(tool);\n const isSelected = this.selectedItem && this.selectedItem.type === 'tool' && this.selectedItem.data.id === tool.id;\n const selectedClass = isSelected ? 'selected' : '';\n \n // Add visual status indicators\n const statusIcon = this.getToolStatusIcon(tool.status);\n const statusLabel = this.getToolStatusLabel(tool.status);\n \n // Add call count if more than 1\n const callIndicator = tool.callCount > 1 ? ` (${tool.callCount} calls)` : '';\n \n let html = `\n <div class=\"tree-node tool ${statusClass} ${selectedClass}\" data-level=\"${level}\">\n <div class=\"tree-node-content\">\n <span class=\"tree-expand-icon\"></span>\n <span class=\"tree-icon\">${tool.icon}</span>\n <span class=\"tree-status-icon\">${statusIcon}</span>\n <span class=\"tree-label clickable\" onclick=\"window.activityTreeInstance.selectItem(${this.escapeJson(tool)}, 'tool', event)\">${tool.name}${callIndicator}</span>\n <span class=\"tree-params\">${params}</span>\n <span class=\"tree-status ${statusClass}\">${statusLabel}</span>\n </div>\n </div>\n `;\n \n return html;\n }\n\n /**\n * Get formatted tool parameters\n */\n getToolParams(tool) {\n if (!tool.params) return '';\n \n if (tool.name === 'Read' && tool.params.file_path) {\n return tool.params.file_path;\n }\n if (tool.name === 'Edit' && tool.params.file_path) {\n return tool.params.file_path;\n }\n if (tool.name === 'Write' && tool.params.file_path) {\n return tool.params.file_path;\n }\n if (tool.name === 'Bash' && tool.params.command) {\n const cmd = tool.params.command;\n return cmd.length > 50 ? cmd.substring(0, 50) + '...' : cmd;\n }\n if (tool.name === 'WebFetch' && tool.params.url) {\n return tool.params.url;\n }\n \n return '';\n }\n\n /**\n * Get status icon for todo status\n */\n getStatusIcon(status) {\n const icons = {\n 'pending': '⏸️',\n 'in_progress': '🔄',\n 'completed': '✅'\n };\n return icons[status] || '❓';\n }\n\n /**\n * Get checkbox icon for todo checklist items\n */\n getCheckboxIcon(status) {\n const icons = {\n 'pending': '⏳',\n 'in_progress': '🔄',\n 'completed': '✅'\n };\n return icons[status] || '❓';\n }\n\n /**\n * Get agent icon based on name\n */\n getAgentIcon(agentName) {\n const icons = {\n 'engineer': '👷',\n 'research': '🔬',\n 'qa': '🧪',\n 'ops': '⚙️',\n 'pm': '📊',\n 'architect': '🏗️',\n 'project manager': '📊'\n };\n return icons[agentName.toLowerCase()] || '🤖';\n }\n\n /**\n * Helper to get all agents including nested subagents\n */\n getAllAgents(session) {\n const agents = [];\n \n const collectAgents = (agentMap) => {\n if (!agentMap) return;\n \n for (let agent of agentMap.values()) {\n agents.push(agent);\n if (agent.subagents && agent.subagents.size > 0) {\n collectAgents(agent.subagents);\n }\n }\n };\n \n collectAgents(session.agents);\n return agents;\n }\n\n /**\n * Render TodoWrite element\n */\n renderTodoWriteElement(todoWrite, level) {\n const todoWriteId = todoWrite.id;\n const isExpanded = this.expandedTools.has(todoWriteId);\n const expandIcon = isExpanded ? '▼' : '▶';\n const todos = todoWrite.todos || [];\n \n // Calculate status summary\n let completedCount = 0;\n let inProgressCount = 0;\n let pendingCount = 0;\n \n todos.forEach(todo => {\n if (todo.status === 'completed') completedCount++;\n else if (todo.status === 'in_progress') inProgressCount++;\n else pendingCount++;\n });\n \n // Find current in-progress todo for highlighting\n const currentTodo = todos.find(t => t.status === 'in_progress');\n const currentIndicator = currentTodo ? ` • 🔄 ${currentTodo.activeForm || currentTodo.content}` : '';\n \n let statusSummary = '';\n if (inProgressCount > 0) {\n statusSummary = `${inProgressCount} in progress, ${completedCount}/${todos.length} done`;\n } else if (completedCount === todos.length && todos.length > 0) {\n statusSummary = `All ${todos.length} completed ✅`;\n } else {\n statusSummary = `${completedCount}/${todos.length} done`;\n }\n \n // Add update count if more than 1\n const updateIndicator = todoWrite.updateCount > 1 ? ` (${todoWrite.updateCount} updates)` : '';\n \n let html = `\n <div class=\"tree-node todowrite ${currentTodo ? 'has-active' : ''}\" data-level=\"${level}\">\n <div class=\"tree-node-content\">\n <span class=\"tree-expand-icon\" onclick=\"window.activityTreeInstance.toggleTodoWrite('${todoWriteId}'); event.stopPropagation();\">${expandIcon}</span>\n <span class=\"tree-icon\">📝</span>\n <span class=\"tree-label\">TodoWrite${updateIndicator}${!isExpanded ? currentIndicator : ''}</span>\n <span class=\"tree-params\">${statusSummary}</span>\n <span class=\"tree-status status-active\">todos</span>\n </div>\n `;\n \n // Show expanded todo items if expanded\n if (isExpanded && todos.length > 0) {\n html += '<div class=\"tree-children\">';\n for (let todo of todos) {\n const statusIcon = this.getCheckboxIcon(todo.status);\n const statusClass = `status-${todo.status}`;\n const displayText = todo.status === 'in_progress' ? todo.activeForm : todo.content;\n const isCurrentTodo = todo === currentTodo;\n \n html += `\n <div class=\"tree-node todo-item ${statusClass} ${isCurrentTodo ? 'current-active' : ''}\" data-level=\"${level + 1}\">\n <div class=\"tree-node-content\">\n <span class=\"tree-expand-icon\"></span>\n <span class=\"tree-icon\">${statusIcon}</span>\n <span class=\"tree-label\">${this.escapeHtml(displayText)}</span>\n <span class=\"tree-status ${statusClass}\">${todo.status.replace('_', ' ')}</span>\n </div>\n </div>\n `;\n }\n html += '</div>';\n }\n \n html += '</div>';\n return html;\n }\n\n /**\n * Toggle TodoWrite expansion\n */\n toggleTodoWrite(todoWriteId) {\n if (this.expandedTools.has(todoWriteId)) {\n this.expandedTools.delete(todoWriteId);\n } else {\n this.expandedTools.add(todoWriteId);\n }\n this.renderTree();\n }\n\n /**\n * Get tool icon based on name\n */\n getToolIcon(toolName) {\n const icons = {\n 'read': '👁️',\n 'write': '✍️',\n 'edit': '✏️',\n 'bash': '💻',\n 'webfetch': '🌐',\n 'grep': '🔍',\n 'glob': '📂',\n 'todowrite': '📝'\n };\n return icons[toolName.toLowerCase()] || '🔧';\n }\n\n /**\n * Get status icon for tool status\n */\n getToolStatusIcon(status) {\n const icons = {\n 'in_progress': '⏳',\n 'completed': '✅',\n 'failed': '❌',\n 'error': '❌',\n 'pending': '⏸️',\n 'active': '🔄'\n };\n return icons[status] || '❓';\n }\n\n /**\n * Get formatted status label for tool\n */\n getToolStatusLabel(status) {\n const labels = {\n 'in_progress': 'in progress',\n 'completed': 'completed',\n 'failed': 'failed',\n 'error': 'error',\n 'pending': 'pending',\n 'active': 'active'\n };\n return labels[status] || status;\n }\n\n /**\n * Toggle session expansion\n */\n toggleSession(sessionId) {\n if (this.expandedSessions.has(sessionId)) {\n this.expandedSessions.delete(sessionId);\n } else {\n this.expandedSessions.add(sessionId);\n }\n \n // Update the session in the data structure\n const session = this.sessions.get(sessionId);\n if (session) {\n session.expanded = this.expandedSessions.has(sessionId);\n }\n \n this.renderTree();\n }\n\n /**\n * Expand all sessions\n */\n expandAllSessions() {\n for (let sessionId of this.sessions.keys()) {\n this.expandedSessions.add(sessionId);\n const session = this.sessions.get(sessionId);\n if (session) session.expanded = true;\n }\n this.renderTree();\n }\n\n /**\n * Collapse all sessions\n */\n collapseAllSessions() {\n this.expandedSessions.clear();\n for (let session of this.sessions.values()) {\n session.expanded = false;\n }\n this.renderTree();\n }\n\n\n /**\n * Update statistics\n */\n updateStats() {\n const totalNodes = this.countTotalNodes();\n const activeNodes = this.countActiveNodes();\n const maxDepth = this.calculateMaxDepth();\n\n const nodeCountEl = document.getElementById('node-count');\n const activeCountEl = document.getElementById('active-count');\n const depthEl = document.getElementById('tree-depth');\n \n if (nodeCountEl) nodeCountEl.textContent = totalNodes;\n if (activeCountEl) activeCountEl.textContent = activeNodes;\n if (depthEl) depthEl.textContent = maxDepth;\n \n console.log(`ActivityTree: Stats updated - Nodes: ${totalNodes}, Active: ${activeNodes}, Depth: ${maxDepth}`);\n }\n\n /**\n * Count total nodes across all sessions\n */\n countTotalNodes() {\n let count = 0; // No project root anymore\n for (let session of this.sessions.values()) {\n count += 1; // Session\n count += session.agents.size; // Agents\n \n // Count user instructions\n if (session.userInstructions) {\n count += session.userInstructions.length;\n }\n \n // Count todos\n if (session.todos) {\n count += session.todos.length;\n }\n \n // Count session-level tools\n if (session.tools) {\n count += session.tools.length;\n }\n \n // Count tools in agents\n for (let agent of session.agents.values()) {\n if (agent.tools) {\n count += agent.tools.length;\n }\n }\n }\n return count;\n }\n\n /**\n * Count active nodes (in progress)\n */\n countActiveNodes() {\n let count = 0;\n for (let session of this.sessions.values()) {\n // Count active session\n if (session.status === 'active') count++;\n \n // Count active todos\n if (session.todos) {\n for (let todo of session.todos) {\n if (todo.status === 'in_progress') count++;\n }\n }\n \n // Count session-level tools\n if (session.tools) {\n for (let tool of session.tools) {\n if (tool.status === 'in_progress') count++;\n }\n }\n \n // Count agents and their tools\n for (let agent of session.agents.values()) {\n if (agent.status === 'active') count++;\n if (agent.tools) {\n for (let tool of agent.tools) {\n if (tool.status === 'in_progress') count++;\n }\n }\n }\n }\n return count;\n }\n\n /**\n * Calculate maximum depth\n */\n calculateMaxDepth() {\n let maxDepth = 0; // No project root anymore\n for (let session of this.sessions.values()) {\n let sessionDepth = 1; // Session level (now root level)\n \n // Check session content (instructions, todos, tools)\n if (session.userInstructions && session.userInstructions.length > 0) {\n sessionDepth = Math.max(sessionDepth, 2); // Instruction level\n }\n \n if (session.todos && session.todos.length > 0) {\n sessionDepth = Math.max(sessionDepth, 3); // Todo checklist -> todo items\n }\n \n if (session.tools && session.tools.length > 0) {\n sessionDepth = Math.max(sessionDepth, 2); // Tool level\n }\n \n // Check agents\n for (let agent of session.agents.values()) {\n if (agent.tools && agent.tools.length > 0) {\n sessionDepth = Math.max(sessionDepth, 3); // Tool level under agents\n }\n }\n \n maxDepth = Math.max(maxDepth, sessionDepth);\n }\n return maxDepth;\n }\n\n /**\n * Toggle agent expansion\n */\n toggleAgent(agentId) {\n if (this.expandedAgents.has(agentId)) {\n this.expandedAgents.delete(agentId);\n } else {\n this.expandedAgents.add(agentId);\n }\n this.renderTree();\n }\n \n /**\n * Toggle tool expansion (deprecated - tools are no longer expandable)\n */\n toggleTool(toolId) {\n // Tools are no longer expandable - this method is kept for compatibility\n console.log('Tool expansion is disabled. Tools now show data in the left pane when clicked.');\n }\n\n /**\n * Toggle TODO checklist expansion\n */\n toggleTodoChecklist(checklistId) {\n if (this.expandedTools.has(checklistId)) {\n this.expandedTools.delete(checklistId);\n } else {\n this.expandedTools.add(checklistId);\n }\n this.renderTree();\n }\n\n /**\n * Render pinned TODOs element under agent\n */\n renderPinnedTodosElement(pinnedTodos, level) {\n const checklistId = `pinned-todos-${Date.now()}`;\n const isExpanded = this.expandedTools.has(checklistId) !== false; // Default to expanded\n const expandIcon = isExpanded ? '▼' : '▶';\n const todos = pinnedTodos.todos || [];\n \n // Calculate status summary\n let completedCount = 0;\n let inProgressCount = 0;\n let pendingCount = 0;\n \n todos.forEach(todo => {\n if (todo.status === 'completed') completedCount++;\n else if (todo.status === 'in_progress') inProgressCount++;\n else pendingCount++;\n });\n \n let statusSummary = '';\n if (inProgressCount > 0) {\n statusSummary = `${inProgressCount} in progress, ${completedCount} completed`;\n } else if (completedCount === todos.length && todos.length > 0) {\n statusSummary = `All ${todos.length} completed`;\n } else {\n statusSummary = `${todos.length} todo(s)`;\n }\n \n let html = `\n <div class=\"tree-node pinned-todos\" data-level=\"${level}\">\n <div class=\"tree-node-content\">\n <span class=\"tree-expand-icon\" onclick=\"window.activityTreeInstance.toggleTodoChecklist('${checklistId}'); event.stopPropagation();\">${expandIcon}</span>\n <span class=\"tree-icon\">📌</span>\n <span class=\"tree-label\">Pinned TODOs</span>\n <span class=\"tree-params\">${statusSummary}</span>\n <span class=\"tree-status status-active\">pinned</span>\n </div>\n `;\n \n // Show expanded todo items if expanded\n if (isExpanded) {\n html += '<div class=\"tree-children\">';\n for (let todo of todos) {\n const statusIcon = this.getCheckboxIcon(todo.status);\n const statusClass = `status-${todo.status}`;\n const displayText = todo.status === 'in_progress' ? todo.activeForm : todo.content;\n \n html += `\n <div class=\"tree-node todo-item ${statusClass}\" data-level=\"${level + 1}\">\n <div class=\"tree-node-content\">\n <span class=\"tree-expand-icon\"></span>\n <span class=\"tree-icon\">${statusIcon}</span>\n <span class=\"tree-label\">${this.escapeHtml(displayText)}</span>\n <span class=\"tree-status ${statusClass}\">${todo.status.replace('_', ' ')}</span>\n </div>\n </div>\n `;\n }\n html += '</div>';\n }\n \n html += '</div>';\n return html;\n }\n\n /**\n * Handle item click to show data in left pane\n */\n selectItem(item, itemType, event) {\n // Stop event propagation to prevent expand/collapse when clicking on label\n if (event) {\n event.stopPropagation();\n }\n \n this.selectedItem = { data: item, type: itemType };\n this.displayItemData(item, itemType);\n this.renderTree(); // Re-render to show selection highlight\n }\n\n /**\n * Display item data in left pane using UnifiedDataViewer for consistency with Tools viewer\n */\n displayItemData(item, itemType) {\n // Initialize UnifiedDataViewer if not already available\n if (!this.unifiedViewer) {\n this.unifiedViewer = new UnifiedDataViewer('module-data-content');\n }\n \n // Use the same UnifiedDataViewer as Tools viewer for consistent display\n this.unifiedViewer.display(item, itemType);\n \n // Update module header for consistency\n const moduleHeader = document.querySelector('.module-data-header h5');\n if (moduleHeader) {\n const icons = {\n 'agent': '🤖',\n 'tool': '🔧', \n 'instruction': '💬',\n 'session': '🎯',\n 'todo': '📝'\n };\n const icon = icons[itemType] || '📊';\n const name = item.name || item.agentName || item.tool_name || 'Item';\n moduleHeader.textContent = `${icon} ${itemType}: ${name}`;\n }\n }\n\n // Display methods removed - now using UnifiedDataViewer for consistency\n\n /**\n * Escape HTML for safe display\n */\n escapeHtml(text) {\n const div = document.createElement('div');\n div.textContent = text;\n return div.innerHTML;\n }\n\n /**\n * Reset zoom and pan to initial state\n */\n resetZoom() {\n if (this.svg && this.zoom) {\n this.svg.transition()\n .duration(this.duration)\n .call(this.zoom.transform, d3.zoomIdentity);\n }\n }\n \n /**\n * Escape JSON for safe inclusion in HTML attributes\n */\n escapeJson(obj) {\n return JSON.stringify(obj).replace(/'/g, '&apos;').replace(/\"/g, '&quot;');\n }\n}\n\n// Make ActivityTree globally available\nwindow.ActivityTree = ActivityTree;\n\n// Initialize when the Activity tab is selected\nconst setupActivityTreeListeners = () => {\n let activityTree = null;\n\n const initializeActivityTree = () => {\n if (!activityTree) {\n console.log('Creating new Activity Tree instance...');\n activityTree = new ActivityTree();\n window.activityTreeInstance = activityTree;\n window.activityTree = () => activityTree; // For debugging\n }\n \n setTimeout(() => {\n console.log('Attempting to initialize Activity Tree visualization...');\n activityTree.initialize();\n }, 100);\n };\n\n // REMOVED: Conflicting tab click handlers that were interfering with UIStateManager\n // Tab switching is now handled entirely through the 'tabChanged' event listener below\n // This prevents conflicts with the UIStateManager's hash-based navigation system\n\n // Listen for custom tab change events\n document.addEventListener('tabChanged', (e) => {\n if (e.detail && e.detail.newTab === 'activity') {\n console.log('Tab changed to activity, initializing tree...');\n initializeActivityTree();\n if (activityTree) {\n setTimeout(() => {\n activityTree.renderWhenVisible();\n activityTree.forceShow();\n }, 150);\n }\n }\n });\n\n // Check if activity tab is already active on load\n const activeTab = document.querySelector('.tab-button.active');\n if (activeTab && activeTab.getAttribute('data-tab') === 'activity') {\n console.log('Activity tab is active on load, initializing tree...');\n initializeActivityTree();\n }\n \n const activityPanel = document.getElementById('activity-tab');\n if (activityPanel && activityPanel.classList.contains('active')) {\n console.log('Activity panel is active on load, initializing tree...');\n if (!activityTree) {\n initializeActivityTree();\n }\n }\n};\n\n// Set up listeners when DOM is ready\nif (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', setupActivityTreeListeners);\n} else {\n setupActivityTreeListeners();\n}\n\nexport { ActivityTree };\nexport default ActivityTree;"],"names":["ActivityTree","constructor","this","container","events","processedEventIds","Set","sessions","Map","currentSession","selectedSessionFilter","timeRange","searchTerm","initialized","expandedSessions","expandedAgents","expandedTools","selectedItem","sessionFilterInitialized","renderTreeDebounced","debounce","renderTree","func","wait","timeout","args","clearTimeout","setTimeout","initialize","console","log","document","getElementById","error","tabPanel","classList","contains","setupControls","subscribeToEvents","createLinearTreeView","forceShow","renderWhenVisible","timeRangeSelect","addEventListener","e","target","value","detail","sessionId","window","sessionManager","currentFilter","getCurrentFilter","expandAllBtn","expandAllSessions","collapseAllBtn","collapseAllSessions","resetZoomBtn","style","display","resetZoom","searchInput","toLowerCase","innerHTML","treeContainer","createElement","id","className","appendChild","socketClient","warn","onEventUpdate","length","size","sessionData","entries","has","existingSession","get","timestamp","Date","lastActivity","startTime","eventCount","status","working_directory","git_branch","activitySession","expanded","agents","todos","userInstructions","tools","toolsMap","currentTodoTool","set","newEvents","filter","event","eventId","type","Math","random","forEach","add","processEvent","Array","from","socketState","getState","unprocessedEvents","clear","eventType","getEventType","isNaN","getTime","session_id","data","session","processUserInstruction","processSubagentStart","processSubagentStop","processToolUse","updateToolStatus","updateStats","hook_event_name","subtype","pre_tool","post_tool","subagent_start","subagent_stop","todo_write","promptText","prompt_text","prompt","instruction","now","text","preview","substring","toISOString","agent","values","delete","currentActiveAgent","push","slice","processTodoWrite","isArray","currentTodos","map","todo","content","activeForm","targetAgent","activeAgents","getAllAgents","sort","a","b","allAgents","pmAgent","find","isPM","todoWritesMap","todoWrites","existingTodoWrite","updateCount","todoWriteInstance","name","icon","params","agentName","agent_name","agent_type","agentSessionId","parentAgent","parent_agent","agentKey","existingAgent","instanceCount","getAgentIcon","subagents","includes","parent","ag","toolName","tool_name","tool","tool_parameters","parameters","toolKey","getToolKey","existingTool","callCount","currentTool","getToolIcon","createdAt","subagent_type","isSubagentTask","subagentType","unshift","key","file_path","pattern","completedAt","result","duration_ms","duration","sortedSessions","sessionElement","createSessionElement","isExpanded","sessionTime","sessionDate","toLocaleString","element","dataset","expandIcon","agentCount","todoCount","instructionCount","renderSessionContent","html","renderUserInstructionElement","renderToolElement","renderAgentElement","level","escapeJson","escapeHtml","renderTodoChecklistElement","checklistId","completedCount","inProgressCount","statusSummary","statusIcon","getCheckboxIcon","statusClass","displayText","replace","hasTools","hasSubagents","hasContent","selectedClass","instanceIndicator","collapsedStatus","parts","inProgress","t","join","subagent","getToolParams","getToolStatusIcon","statusLabel","getToolStatusLabel","callIndicator","command","cmd","url","getStatusIcon","pending","in_progress","completed","engineer","research","qa","ops","pm","architect","collectAgents","agentMap","renderTodoWriteElement","todoWrite","todoWriteId","currentTodo","currentIndicator","toggleTodoWrite","read","write","edit","bash","webfetch","grep","glob","todowrite","failed","active","toggleSession","keys","totalNodes","countTotalNodes","activeNodes","countActiveNodes","maxDepth","calculateMaxDepth","nodeCountEl","activeCountEl","depthEl","textContent","count","sessionDepth","max","toggleAgent","agentId","toggleTool","toolId","toggleTodoChecklist","renderPinnedTodosElement","pinnedTodos","selectItem","item","itemType","stopPropagation","displayItemData","unifiedViewer","UnifiedDataViewer","moduleHeader","querySelector","div","svg","zoom","transition","call","transform","d3","zoomIdentity","obj","JSON","stringify","setupActivityTreeListeners","activityTree","initializeActivityTree","activityTreeInstance","newTab","activeTab","getAttribute","activityPanel","readyState"],"mappings":"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"}