claude-mpm 4.21.3__py3-none-any.whl → 5.1.9__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (517) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/{OUTPUT_STYLE.md → CLAUDE_MPM_OUTPUT_STYLE.md} +3 -48
  4. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +2002 -0
  5. claude_mpm/agents/PM_INSTRUCTIONS.md +1239 -674
  6. claude_mpm/agents/WORKFLOW.md +75 -2
  7. claude_mpm/agents/__init__.py +6 -0
  8. claude_mpm/agents/agent_loader.py +1 -4
  9. claude_mpm/agents/base_agent.json +6 -3
  10. claude_mpm/agents/base_agent_loader.py +10 -35
  11. claude_mpm/agents/frontmatter_validator.py +69 -1
  12. claude_mpm/agents/templates/circuit-breakers.md +1254 -0
  13. claude_mpm/agents/templates/context-management-examples.md +544 -0
  14. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +89 -19
  15. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  16. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  17. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  18. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  19. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  20. claude_mpm/cli/__init__.py +37 -2
  21. claude_mpm/cli/commands/__init__.py +2 -0
  22. claude_mpm/cli/commands/agent_source.py +774 -0
  23. claude_mpm/cli/commands/agent_state_manager.py +188 -30
  24. claude_mpm/cli/commands/agents.py +1128 -36
  25. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  26. claude_mpm/cli/commands/agents_discover.py +338 -0
  27. claude_mpm/cli/commands/aggregate.py +1 -1
  28. claude_mpm/cli/commands/analyze.py +3 -3
  29. claude_mpm/cli/commands/auto_configure.py +537 -239
  30. claude_mpm/cli/commands/cleanup.py +1 -1
  31. claude_mpm/cli/commands/config.py +7 -4
  32. claude_mpm/cli/commands/configure.py +935 -45
  33. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  34. claude_mpm/cli/commands/configure_navigation.py +63 -46
  35. claude_mpm/cli/commands/debug.py +12 -12
  36. claude_mpm/cli/commands/doctor.py +10 -2
  37. claude_mpm/cli/commands/hook_errors.py +277 -0
  38. claude_mpm/cli/commands/local_deploy.py +1 -4
  39. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  40. claude_mpm/cli/commands/mpm_init/core.py +50 -2
  41. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  42. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  43. claude_mpm/cli/commands/postmortem.py +401 -0
  44. claude_mpm/cli/commands/run.py +125 -167
  45. claude_mpm/cli/commands/skill_source.py +694 -0
  46. claude_mpm/cli/commands/skills.py +757 -20
  47. claude_mpm/cli/executor.py +78 -3
  48. claude_mpm/cli/interactive/agent_wizard.py +1032 -47
  49. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  50. claude_mpm/cli/parsers/agents_parser.py +310 -4
  51. claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
  52. claude_mpm/cli/parsers/base_parser.py +53 -0
  53. claude_mpm/cli/parsers/config_parser.py +96 -43
  54. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  55. claude_mpm/cli/parsers/skills_parser.py +145 -0
  56. claude_mpm/cli/parsers/source_parser.py +138 -0
  57. claude_mpm/cli/startup.py +564 -108
  58. claude_mpm/cli/startup_display.py +480 -0
  59. claude_mpm/cli/utils.py +1 -1
  60. claude_mpm/cli_module/commands.py +1 -1
  61. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  62. claude_mpm/commands/mpm-agents-detect.md +9 -0
  63. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  64. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  65. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  66. claude_mpm/commands/mpm-doctor.md +9 -0
  67. claude_mpm/commands/mpm-help.md +14 -2
  68. claude_mpm/commands/mpm-init.md +27 -2
  69. claude_mpm/commands/mpm-monitor.md +9 -0
  70. claude_mpm/commands/mpm-postmortem.md +123 -0
  71. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  72. claude_mpm/commands/mpm-status.md +9 -0
  73. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  74. claude_mpm/commands/mpm-ticket-view.md +552 -0
  75. claude_mpm/commands/mpm-version.md +9 -0
  76. claude_mpm/commands/mpm.md +10 -0
  77. claude_mpm/config/agent_presets.py +488 -0
  78. claude_mpm/config/agent_sources.py +325 -0
  79. claude_mpm/config/skill_presets.py +392 -0
  80. claude_mpm/config/skill_sources.py +590 -0
  81. claude_mpm/constants.py +13 -0
  82. claude_mpm/core/api_validator.py +1 -1
  83. claude_mpm/core/claude_runner.py +19 -35
  84. claude_mpm/core/config.py +24 -0
  85. claude_mpm/core/constants.py +1 -1
  86. claude_mpm/core/framework/__init__.py +3 -16
  87. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  88. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  89. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  90. claude_mpm/core/hook_error_memory.py +381 -0
  91. claude_mpm/core/hook_manager.py +41 -2
  92. claude_mpm/core/interactive_session.py +131 -10
  93. claude_mpm/core/logger.py +3 -1
  94. claude_mpm/core/oneshot_session.py +110 -8
  95. claude_mpm/core/output_style_manager.py +173 -43
  96. claude_mpm/core/protocols/__init__.py +23 -0
  97. claude_mpm/core/protocols/runner_protocol.py +103 -0
  98. claude_mpm/core/protocols/session_protocol.py +131 -0
  99. claude_mpm/core/shared/singleton_manager.py +11 -4
  100. claude_mpm/core/system_context.py +38 -0
  101. claude_mpm/core/unified_agent_registry.py +129 -1
  102. claude_mpm/core/unified_config.py +22 -0
  103. claude_mpm/dashboard/static/css/activity.css +69 -69
  104. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  105. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  106. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  107. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  108. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  109. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  110. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  111. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  112. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  113. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  114. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  115. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  116. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  117. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  118. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  119. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  120. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  121. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  122. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  123. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  124. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  125. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  126. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  127. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  128. claude_mpm/dashboard/templates/code_simple.html +23 -23
  129. claude_mpm/dashboard/templates/index.html +18 -18
  130. claude_mpm/experimental/cli_enhancements.py +1 -5
  131. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  132. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  133. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  134. claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
  135. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  136. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  137. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  138. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  139. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  140. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  141. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  142. claude_mpm/models/agent_definition.py +7 -0
  143. claude_mpm/models/git_repository.py +198 -0
  144. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  145. claude_mpm/scripts/start_activity_logging.py +3 -1
  146. claude_mpm/services/agents/agent_builder.py +45 -9
  147. claude_mpm/services/agents/agent_preset_service.py +238 -0
  148. claude_mpm/services/agents/agent_selection_service.py +484 -0
  149. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  150. claude_mpm/services/agents/cache_git_manager.py +621 -0
  151. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  152. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  153. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  154. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  155. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  156. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  157. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  158. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  159. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  160. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  161. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +225 -18
  162. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  163. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  164. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +557 -0
  165. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  166. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  167. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  168. claude_mpm/services/agents/git_source_manager.py +629 -0
  169. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  170. claude_mpm/services/agents/local_template_manager.py +50 -10
  171. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  172. claude_mpm/services/agents/sources/__init__.py +13 -0
  173. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  174. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  175. claude_mpm/services/agents/startup_sync.py +239 -0
  176. claude_mpm/services/agents/toolchain_detector.py +474 -0
  177. claude_mpm/services/analysis/__init__.py +25 -0
  178. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  179. claude_mpm/services/analysis/postmortem_service.py +765 -0
  180. claude_mpm/services/cli/session_pause_manager.py +1 -1
  181. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  182. claude_mpm/services/command_deployment_service.py +200 -6
  183. claude_mpm/services/core/base.py +7 -2
  184. claude_mpm/services/core/interfaces/__init__.py +1 -3
  185. claude_mpm/services/core/interfaces/health.py +1 -4
  186. claude_mpm/services/core/models/__init__.py +2 -11
  187. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  188. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  189. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  190. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  191. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  192. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  193. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  194. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  195. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  196. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  197. claude_mpm/services/event_bus/direct_relay.py +3 -3
  198. claude_mpm/services/event_bus/event_bus.py +36 -3
  199. claude_mpm/services/events/consumers/logging.py +1 -2
  200. claude_mpm/services/git/__init__.py +21 -0
  201. claude_mpm/services/git/git_operations_service.py +494 -0
  202. claude_mpm/services/github/__init__.py +21 -0
  203. claude_mpm/services/github/github_cli_service.py +397 -0
  204. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  205. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  206. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  207. claude_mpm/services/instructions/__init__.py +9 -0
  208. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  209. claude_mpm/services/local_ops/__init__.py +3 -13
  210. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  211. claude_mpm/services/local_ops/health_manager.py +1 -4
  212. claude_mpm/services/local_ops/process_manager.py +1 -1
  213. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  214. claude_mpm/services/mcp_config_manager.py +75 -145
  215. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  216. claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
  217. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  218. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  219. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  220. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  221. claude_mpm/services/mcp_service_verifier.py +6 -3
  222. claude_mpm/services/memory/optimizer.py +1 -1
  223. claude_mpm/services/model/model_router.py +8 -9
  224. claude_mpm/services/monitor/daemon.py +29 -9
  225. claude_mpm/services/monitor/daemon_manager.py +96 -19
  226. claude_mpm/services/monitor/server.py +2 -2
  227. claude_mpm/services/native_agent_converter.py +356 -0
  228. claude_mpm/services/port_manager.py +1 -1
  229. claude_mpm/services/pr/__init__.py +14 -0
  230. claude_mpm/services/pr/pr_template_service.py +329 -0
  231. claude_mpm/services/project/documentation_manager.py +2 -1
  232. claude_mpm/services/project/project_organizer.py +4 -0
  233. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  234. claude_mpm/services/runner_configuration_service.py +17 -3
  235. claude_mpm/services/self_upgrade_service.py +165 -7
  236. claude_mpm/services/session_management_service.py +16 -4
  237. claude_mpm/services/skills/__init__.py +18 -0
  238. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  239. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  240. claude_mpm/services/skills_config.py +547 -0
  241. claude_mpm/services/skills_deployer.py +955 -0
  242. claude_mpm/services/socketio/handlers/connection.py +1 -1
  243. claude_mpm/services/socketio/handlers/git.py +2 -2
  244. claude_mpm/services/socketio/server/core.py +1 -4
  245. claude_mpm/services/socketio/server/main.py +1 -3
  246. claude_mpm/services/system_instructions_service.py +1 -3
  247. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  248. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  249. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  250. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  251. claude_mpm/services/unified/unified_deployment.py +1 -5
  252. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  253. claude_mpm/services/visualization/__init__.py +1 -5
  254. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  255. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  256. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  257. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  258. claude_mpm/skills/skills_registry.py +0 -1
  259. claude_mpm/templates/questions/__init__.py +38 -0
  260. claude_mpm/templates/questions/base.py +193 -0
  261. claude_mpm/templates/questions/pr_strategy.py +311 -0
  262. claude_mpm/templates/questions/project_init.py +385 -0
  263. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  264. claude_mpm/tools/__main__.py +8 -8
  265. claude_mpm/tools/code_tree_analyzer/analysis.py +1 -1
  266. claude_mpm/utils/agent_dependency_loader.py +80 -13
  267. claude_mpm/utils/agent_filters.py +288 -0
  268. claude_mpm/utils/dependency_cache.py +3 -1
  269. claude_mpm/utils/gitignore.py +244 -0
  270. claude_mpm/utils/log_cleanup.py +3 -3
  271. claude_mpm/utils/migration.py +372 -0
  272. claude_mpm/utils/progress.py +387 -0
  273. claude_mpm/utils/robust_installer.py +3 -5
  274. claude_mpm/utils/structured_questions.py +619 -0
  275. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/METADATA +496 -65
  276. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/RECORD +284 -443
  277. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  278. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  279. claude_mpm/agents/templates/agent-manager.json +0 -273
  280. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  281. claude_mpm/agents/templates/api_qa.json +0 -180
  282. claude_mpm/agents/templates/circuit_breakers.md +0 -638
  283. claude_mpm/agents/templates/clerk-ops.json +0 -235
  284. claude_mpm/agents/templates/code_analyzer.json +0 -101
  285. claude_mpm/agents/templates/content-agent.json +0 -358
  286. claude_mpm/agents/templates/dart_engineer.json +0 -307
  287. claude_mpm/agents/templates/data_engineer.json +0 -225
  288. claude_mpm/agents/templates/documentation.json +0 -211
  289. claude_mpm/agents/templates/engineer.json +0 -210
  290. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  291. claude_mpm/agents/templates/golang_engineer.json +0 -270
  292. claude_mpm/agents/templates/imagemagick.json +0 -264
  293. claude_mpm/agents/templates/java_engineer.json +0 -346
  294. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  295. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  296. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  297. claude_mpm/agents/templates/memory_manager.json +0 -158
  298. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  299. claude_mpm/agents/templates/ops.json +0 -185
  300. claude_mpm/agents/templates/php-engineer.json +0 -287
  301. claude_mpm/agents/templates/product_owner.json +0 -338
  302. claude_mpm/agents/templates/project_organizer.json +0 -140
  303. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  304. claude_mpm/agents/templates/python_engineer.json +0 -387
  305. claude_mpm/agents/templates/qa.json +0 -242
  306. claude_mpm/agents/templates/react_engineer.json +0 -238
  307. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  308. claude_mpm/agents/templates/research.json +0 -188
  309. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  310. claude_mpm/agents/templates/rust_engineer.json +0 -275
  311. claude_mpm/agents/templates/security.json +0 -202
  312. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  313. claude_mpm/agents/templates/ticketing.json +0 -177
  314. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  315. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  316. claude_mpm/agents/templates/version_control.json +0 -157
  317. claude_mpm/agents/templates/web_qa.json +0 -399
  318. claude_mpm/agents/templates/web_ui.json +0 -189
  319. claude_mpm/commands/mpm-tickets.md +0 -102
  320. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  321. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  322. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  323. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  324. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  325. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  326. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  327. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  328. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  329. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  330. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  331. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  332. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  333. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  334. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  335. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  336. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  337. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  338. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  339. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  340. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  341. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  342. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  343. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  344. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  345. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  346. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  347. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  348. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  349. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  350. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  351. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  352. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  353. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  354. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  355. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  356. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  357. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  358. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  359. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  360. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  361. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  362. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  363. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  364. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  365. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  366. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  367. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  368. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  369. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  370. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  371. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  372. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  373. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  374. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  375. claude_mpm/dashboard/static/built/react/events.js +0 -30
  376. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  377. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  378. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  379. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  380. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  381. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  382. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  383. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  384. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  385. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  386. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  387. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  388. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  389. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  390. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  391. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  392. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  393. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  394. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  395. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  396. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  397. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  398. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  399. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  400. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  401. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  402. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  403. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  404. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  405. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  406. claude_mpm/dashboard/static/events.html +0 -607
  407. claude_mpm/dashboard/static/index.html +0 -635
  408. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  409. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  410. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  411. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  412. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  413. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  414. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  415. claude_mpm/dashboard/static/legacy/files.html +0 -747
  416. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  417. claude_mpm/dashboard/static/monitors.html +0 -431
  418. claude_mpm/dashboard/static/production/events.html +0 -659
  419. claude_mpm/dashboard/static/production/main.html +0 -698
  420. claude_mpm/dashboard/static/production/monitors.html +0 -483
  421. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  422. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  423. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  424. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  425. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  426. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  427. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  428. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  429. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  430. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  431. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  432. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  433. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  434. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  435. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  436. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  437. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  438. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  439. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  440. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  441. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  442. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  443. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  444. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  445. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  446. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  447. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  448. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  449. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  450. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  451. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  452. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  453. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  454. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  455. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  456. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  457. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  458. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  459. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  460. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  461. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  462. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  463. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  464. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  465. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  466. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  467. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  468. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  469. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  470. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  471. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  472. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  473. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  474. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  475. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  476. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  477. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  478. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  479. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  480. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  481. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  482. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  483. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  484. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  485. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  486. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  487. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  488. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  489. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  490. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  491. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  492. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  493. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  494. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  495. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  496. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  497. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  498. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  499. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  500. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  501. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  502. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  503. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  504. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  505. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  506. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  507. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  508. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  509. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  510. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  511. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  512. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  513. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  514. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/WHEEL +0 -0
  515. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/entry_points.txt +0 -0
  516. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/licenses/LICENSE +0 -0
  517. {claude_mpm-4.21.3.dist-info → claude_mpm-5.1.9.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,288 @@
1
+ """
2
+ Agent filtering utilities for claude-mpm.
3
+
4
+ WHY: This module provides centralized filtering logic to remove non-deployable
5
+ agents (BASE_AGENT) and already-deployed agents from user-facing displays.
6
+
7
+ DESIGN DECISIONS:
8
+ - BASE_AGENT is a build tool, not a deployable agent - filter everywhere
9
+ - Deployed agent detection supports both new (.claude-mpm/agents/) and
10
+ legacy (.claude/agents/)
11
+ - Case-insensitive BASE_AGENT detection for robustness
12
+ - Pure functions for easy testing and reuse
13
+
14
+ IMPLEMENTATION NOTES:
15
+ - Related to ticket 1M-502 Phase 1: UX improvements for agent filtering
16
+ - Addresses user confusion from seeing BASE_AGENT and deployed agents in lists
17
+ """
18
+
19
+ from pathlib import Path
20
+ from typing import Dict, List, Optional, Set
21
+
22
+
23
+ def is_base_agent(agent_id: str) -> bool:
24
+ """Check if agent is BASE_AGENT (build tool, not deployable).
25
+
26
+ BASE_AGENT is an internal build tool used to construct other agents.
27
+ It should never appear in user-facing agent lists or deployment menus.
28
+
29
+ Args:
30
+ agent_id: Agent identifier to check (may include path like "qa/BASE-AGENT")
31
+
32
+ Returns:
33
+ True if agent is BASE_AGENT (case-insensitive), False otherwise
34
+
35
+ Examples:
36
+ >>> is_base_agent("BASE_AGENT")
37
+ True
38
+ >>> is_base_agent("base-agent")
39
+ True
40
+ >>> is_base_agent("qa/BASE-AGENT")
41
+ True
42
+ >>> is_base_agent("ENGINEER")
43
+ False
44
+ """
45
+ if not agent_id:
46
+ return False
47
+
48
+ # Extract filename from path (handle cases like "qa/BASE-AGENT")
49
+ # 1M-502: Remote agents may have path prefixes like "qa/", "pm/", etc.
50
+ agent_name = agent_id.split("/")[-1]
51
+
52
+ normalized_id = agent_name.lower().replace("-", "").replace("_", "")
53
+ return normalized_id == "baseagent"
54
+
55
+
56
+ def filter_base_agents(agents: List[Dict]) -> List[Dict]:
57
+ """Remove BASE_AGENT from agent list.
58
+
59
+ Filters out any agent with agent_id matching BASE_AGENT (case-insensitive).
60
+ This prevents users from seeing or selecting the internal build tool.
61
+
62
+ Args:
63
+ agents: List of agent dictionaries, each containing at least 'agent_id' key
64
+
65
+ Returns:
66
+ Filtered list with BASE_AGENT removed
67
+
68
+ Examples:
69
+ >>> agents = [
70
+ ... {"agent_id": "ENGINEER", "name": "Engineer"},
71
+ ... {"agent_id": "BASE_AGENT", "name": "Base Agent"},
72
+ ... {"agent_id": "PM", "name": "PM"}
73
+ ... ]
74
+ >>> filtered = filter_base_agents(agents)
75
+ >>> len(filtered)
76
+ 2
77
+ >>> "BASE_AGENT" in [a["agent_id"] for a in filtered]
78
+ False
79
+ """
80
+ return [a for a in agents if not is_base_agent(a.get("agent_id", ""))]
81
+
82
+
83
+ def get_deployed_agent_ids(project_dir: Optional[Path] = None) -> Set[str]:
84
+ """Get set of currently deployed agent IDs.
85
+
86
+ Checks virtual deployment state (.mpm_deployment_state) first, then falls back
87
+ to physical .md files for backward compatibility. This ensures agents are detected
88
+ whether deployed virtually or as physical files.
89
+
90
+ Args:
91
+ project_dir: Project directory to check, defaults to current working directory
92
+
93
+ Returns:
94
+ Set of deployed agent IDs (leaf names like "python-engineer", "qa")
95
+
96
+ Examples:
97
+ >>> deployed = get_deployed_agent_ids()
98
+ >>> "python-engineer" in deployed # If agent exists in deployment state
99
+ True
100
+ >>> "ENGINEER" in deployed # If ENGINEER.md exists
101
+ True
102
+
103
+ Design Rationale:
104
+ - Primary detection: Virtual deployment state (.mpm_deployment_state)
105
+ - Fallback detection: Physical .md files (.claude-mpm/agents/, .claude/agents/)
106
+ - Returns leaf names for consistent comparison with agent_id formats
107
+ - Combines both detection methods for complete coverage
108
+ - Graceful error handling for malformed or missing state files
109
+
110
+ Related:
111
+ - Fixes checkbox interface showing all agents as "○ [Available]" instead of "● [Installed]"
112
+ - Matches detection logic from _is_agent_deployed() in agent_state_manager.py
113
+ - Related to ticket 1M-502: Virtual deployment state detection
114
+ """
115
+ deployed = set()
116
+
117
+ # Track if project_dir was explicitly provided
118
+ explicit_project_dir = project_dir is not None
119
+
120
+ if project_dir is None:
121
+ project_dir = Path.cwd()
122
+
123
+ # NEW: Check virtual deployment state (primary method)
124
+ # This is the current deployment model used by Claude Code
125
+ deployment_state_paths = [
126
+ project_dir / ".claude" / "agents" / ".mpm_deployment_state",
127
+ ]
128
+
129
+ # Only check user-level state if using default project directory
130
+ # This prevents test isolation issues when explicit project_dir is provided
131
+ if not explicit_project_dir:
132
+ deployment_state_paths.append(
133
+ Path.home() / ".claude" / "agents" / ".mpm_deployment_state"
134
+ )
135
+
136
+ for state_path in deployment_state_paths:
137
+ if state_path.exists():
138
+ try:
139
+ import json
140
+
141
+ with state_path.open() as f:
142
+ state = json.load(f)
143
+
144
+ # Extract agent IDs from deployment state
145
+ # Agent IDs are leaf names (e.g., "python-engineer", "qa")
146
+ agents = state.get("last_check_results", {}).get("agents", {})
147
+ deployed.update(agents.keys())
148
+
149
+ except (json.JSONDecodeError, KeyError) as e:
150
+ # Log error but continue - don't break if state file is malformed
151
+ import logging
152
+
153
+ logger = logging.getLogger(__name__)
154
+ logger.debug(f"Failed to read deployment state from {state_path}: {e}")
155
+ continue
156
+ except Exception as e:
157
+ # Catch unexpected errors - fail gracefully
158
+ import logging
159
+
160
+ logger = logging.getLogger(__name__)
161
+ logger.debug(f"Unexpected error reading deployment state: {e}")
162
+ continue
163
+
164
+ # EXISTING: Check physical .md files (fallback for backward compatibility)
165
+ # Check new architecture
166
+ new_agents_dir = project_dir / ".claude-mpm" / "agents"
167
+ if new_agents_dir.exists():
168
+ for file in new_agents_dir.glob("*.md"):
169
+ if file.stem not in {"BASE-AGENT", ".DS_Store"}:
170
+ deployed.add(file.stem)
171
+
172
+ # Check legacy architecture
173
+ legacy_agents_dir = project_dir / ".claude" / "agents"
174
+ if legacy_agents_dir.exists():
175
+ for file in legacy_agents_dir.glob("*.md"):
176
+ if file.stem not in {"BASE-AGENT", ".DS_Store"}:
177
+ deployed.add(file.stem)
178
+
179
+ # Check .claude/templates/ directory (where agents are actually deployed)
180
+ templates_dir = project_dir / ".claude" / "templates"
181
+ if templates_dir.exists():
182
+ for file in templates_dir.glob("*.md"):
183
+ if file.stem not in {
184
+ "BASE-AGENT",
185
+ ".DS_Store",
186
+ "README",
187
+ "circuit-breakers",
188
+ }:
189
+ # Skip template/example files
190
+ if not any(x in file.stem for x in ["example", "template", "pm-"]):
191
+ deployed.add(file.stem)
192
+
193
+ # Check user-level directory only if using default project directory
194
+ # This prevents test isolation issues when explicit project_dir is provided
195
+ if not explicit_project_dir:
196
+ user_agents_dir = Path.home() / ".claude" / "agents"
197
+ if user_agents_dir.exists():
198
+ for file in user_agents_dir.glob("*.md"):
199
+ if file.stem not in {"BASE-AGENT", ".DS_Store"}:
200
+ deployed.add(file.stem)
201
+
202
+ return deployed
203
+
204
+
205
+ def filter_deployed_agents(
206
+ agents: List[Dict], project_dir: Optional[Path] = None
207
+ ) -> List[Dict]:
208
+ """Remove already-deployed agents from list.
209
+
210
+ Filters agent list to show only agents that are not currently deployed.
211
+ This prevents users from attempting to re-deploy existing agents and
212
+ reduces confusion in deployment menus.
213
+
214
+ Args:
215
+ agents: List of agent dictionaries, each containing at least 'agent_id' key
216
+ project_dir: Project directory to check, defaults to current working directory
217
+
218
+ Returns:
219
+ Filtered list containing only non-deployed agents
220
+
221
+ Examples:
222
+ >>> agents = [
223
+ ... {"agent_id": "ENGINEER", "name": "Engineer"},
224
+ ... {"agent_id": "PM", "name": "PM"},
225
+ ... {"agent_id": "QA", "name": "QA"}
226
+ ... ]
227
+ >>> # Assuming ENGINEER is deployed
228
+ >>> filtered = filter_deployed_agents(agents)
229
+ >>> "ENGINEER" not in [a["agent_id"] for a in filtered]
230
+ True
231
+
232
+ Design Rationale:
233
+ - Checks filesystem for actual deployed files (source of truth)
234
+ - Supports both new and legacy agent directory structures
235
+ - Preserves agent order for consistent UX
236
+ """
237
+ deployed_ids = get_deployed_agent_ids(project_dir)
238
+ return [a for a in agents if a.get("agent_id") not in deployed_ids]
239
+
240
+
241
+ def apply_all_filters(
242
+ agents: List[Dict],
243
+ project_dir: Optional[Path] = None,
244
+ filter_base: bool = True,
245
+ filter_deployed: bool = False,
246
+ ) -> List[Dict]:
247
+ """Apply multiple filters to agent list in correct order.
248
+
249
+ Convenience function to apply common filtering combinations. Filters are
250
+ applied in this order:
251
+ 1. BASE_AGENT filtering (if enabled)
252
+ 2. Deployed agent filtering (if enabled)
253
+
254
+ Args:
255
+ agents: List of agent dictionaries to filter
256
+ project_dir: Project directory for deployment checks
257
+ filter_base: Remove BASE_AGENT from list (default: True)
258
+ filter_deployed: Remove deployed agents from list (default: False)
259
+
260
+ Returns:
261
+ Filtered agent list
262
+
263
+ Examples:
264
+ >>> agents = get_all_agents()
265
+ >>> # For display/info purposes - remove only BASE_AGENT
266
+ >>> filtered = apply_all_filters(
267
+ ... agents, filter_base=True, filter_deployed=False
268
+ ... )
269
+ >>> # For deployment menus - remove BASE_AGENT and deployed agents
270
+ >>> deployable = apply_all_filters(
271
+ ... agents, filter_base=True, filter_deployed=True
272
+ ... )
273
+
274
+ Usage Guidelines:
275
+ - Use filter_base=True (default) for all user-facing displays
276
+ - Use filter_deployed=True when showing deployment options
277
+ - Use filter_deployed=False when showing all available agents
278
+ (info/list commands)
279
+ """
280
+ result = agents
281
+
282
+ if filter_base:
283
+ result = filter_base_agents(result)
284
+
285
+ if filter_deployed:
286
+ result = filter_deployed_agents(result, project_dir)
287
+
288
+ return result
@@ -333,7 +333,9 @@ class SmartDependencyChecker:
333
333
  return True, "No valid cache, checking needed"
334
334
 
335
335
  def get_or_check_dependencies(
336
- self, loader, force_check: bool = False # AgentDependencyLoader instance
336
+ self,
337
+ loader,
338
+ force_check: bool = False, # AgentDependencyLoader instance
337
339
  ) -> Tuple[Dict, bool]:
338
340
  """
339
341
  Get dependency results from cache or perform check.
@@ -0,0 +1,244 @@
1
+ """GitIgnore management utilities.
2
+
3
+ This module provides functionality to safely manage .gitignore entries,
4
+ ensuring claude-mpm configuration directories are excluded from version control.
5
+
6
+ Design Decisions:
7
+ - In-memory set for duplicate detection (O(1) lookups)
8
+ - Preserves existing file formatting and comments
9
+ - Adds section headers for clarity
10
+ - Handles edge cases (missing newlines, empty files, etc.)
11
+
12
+ Trade-offs:
13
+ - Simplicity: File append vs. full parse/rewrite (chosen append for safety)
14
+ - Performance: Read entire file vs. streaming (file is small, simplicity wins)
15
+ - Safety: Non-destructive append only, never modifies existing entries
16
+ """
17
+
18
+ from pathlib import Path
19
+ from typing import List, Set, Tuple
20
+
21
+ from claude_mpm.core.logging_utils import get_logger
22
+
23
+ logger = get_logger(__name__)
24
+
25
+
26
+ class GitIgnoreManager:
27
+ """Manages .gitignore file updates safely and non-destructively.
28
+
29
+ Design Pattern: Builder pattern for fluent API
30
+ - Initialize with project directory
31
+ - Call ensure_entries() to add patterns
32
+ - Returns summary of changes made
33
+
34
+ Performance:
35
+ - Time Complexity: O(n) where n = existing .gitignore lines
36
+ - Space Complexity: O(n) for storing unique entries in set
37
+ - Expected Performance: <1ms for typical .gitignore files (<1000 lines)
38
+
39
+ Error Handling:
40
+ - FileNotFoundError: Creates new .gitignore if missing
41
+ - PermissionError: Propagated to caller for appropriate handling
42
+ - UnicodeDecodeError: Logged and treated as binary file (skip)
43
+ """
44
+
45
+ def __init__(self, project_dir: Path):
46
+ """Initialize with project directory.
47
+
48
+ Args:
49
+ project_dir: Path to project root (where .gitignore lives)
50
+ """
51
+ self.project_dir = Path(project_dir)
52
+ self.gitignore_path = self.project_dir / ".gitignore"
53
+
54
+ def ensure_entries(self, entries: List[str]) -> Tuple[List[str], List[str]]:
55
+ """Ensure specified entries exist in .gitignore.
56
+
57
+ Non-destructive operation that:
58
+ 1. Reads existing entries (if file exists)
59
+ 2. Identifies which entries are missing
60
+ 3. Appends only missing entries with section header
61
+ 4. Preserves all existing content and formatting
62
+
63
+ Args:
64
+ entries: List of gitignore patterns to add (e.g., [".claude-mpm/"])
65
+
66
+ Returns:
67
+ Tuple of (added_entries, existing_entries)
68
+ - added_entries: Patterns that were added to .gitignore
69
+ - existing_entries: Patterns that were already present
70
+
71
+ Example:
72
+ >>> manager = GitIgnoreManager(Path("."))
73
+ >>> added, existing = manager.ensure_entries([".claude-mpm/"])
74
+ >>> print(f"Added: {added}, Already present: {existing}")
75
+ Added: ['.claude-mpm/'], Already present: []
76
+ """
77
+ # Read existing entries
78
+ existing = self._read_existing_entries()
79
+
80
+ # Determine what needs to be added
81
+ to_add = [e for e in entries if e not in existing]
82
+ already_present = [e for e in entries if e in existing]
83
+
84
+ if to_add:
85
+ self._append_entries(to_add)
86
+ logger.info(f"Added {len(to_add)} entries to .gitignore: {to_add}")
87
+
88
+ if already_present:
89
+ logger.debug(f"Entries already in .gitignore: {already_present}")
90
+
91
+ return to_add, already_present
92
+
93
+ def _read_existing_entries(self) -> Set[str]:
94
+ """Read existing .gitignore entries.
95
+
96
+ Parses .gitignore file and extracts all non-comment, non-blank patterns.
97
+ Handles edge cases:
98
+ - File doesn't exist -> returns empty set
99
+ - File is binary -> logs warning, returns empty set
100
+ - File has no newline at end -> handled correctly
101
+
102
+ Returns:
103
+ Set of existing gitignore patterns (stripped, normalized)
104
+ """
105
+ if not self.gitignore_path.exists():
106
+ logger.debug(".gitignore does not exist, will create new file")
107
+ return set()
108
+
109
+ try:
110
+ with open(self.gitignore_path, encoding="utf-8") as f:
111
+ # Strip whitespace and comments, filter blanks
112
+ entries = {
113
+ line.strip()
114
+ for line in f
115
+ if line.strip() and not line.strip().startswith("#")
116
+ }
117
+
118
+ logger.debug(f"Found {len(entries)} existing entries in .gitignore")
119
+ return entries
120
+
121
+ except UnicodeDecodeError:
122
+ logger.warning(
123
+ f".gitignore appears to be binary, cannot parse: {self.gitignore_path}"
124
+ )
125
+ return set()
126
+ except Exception as e:
127
+ logger.error(f"Error reading .gitignore: {e}")
128
+ raise
129
+
130
+ def _append_entries(self, entries: List[str]) -> None:
131
+ """Append entries to .gitignore with proper formatting.
132
+
133
+ Handles formatting edge cases:
134
+ - Ensures blank line before new section (if file exists and isn't empty)
135
+ - Adds section header comment for clarity
136
+ - Ensures each entry on its own line
137
+ - Handles missing trailing newline in existing file
138
+
139
+ Args:
140
+ entries: List of patterns to append
141
+
142
+ Raises:
143
+ PermissionError: If cannot write to .gitignore
144
+ OSError: If disk is full or other I/O error
145
+ """
146
+ mode = "a" if self.gitignore_path.exists() else "w"
147
+
148
+ try:
149
+ with open(self.gitignore_path, mode, encoding="utf-8") as f:
150
+ # Add blank line before entries if file exists and isn't empty
151
+ if mode == "a" and self.gitignore_path.stat().st_size > 0:
152
+ # Check if last line has newline
153
+ with open(self.gitignore_path, "rb") as check:
154
+ check.seek(-1, 2) # Seek to last byte
155
+ last_byte = check.read(1)
156
+ if last_byte != b"\n":
157
+ f.write("\n")
158
+
159
+ f.write("\n# Claude MPM configuration\n")
160
+ else:
161
+ # New file or empty file - add header without extra blank line
162
+ f.write("# Claude MPM configuration\n")
163
+
164
+ for entry in entries:
165
+ f.write(f"{entry}\n")
166
+
167
+ logger.info(f"Updated .gitignore at {self.gitignore_path}")
168
+
169
+ except PermissionError:
170
+ logger.error(
171
+ f"Permission denied writing to .gitignore: {self.gitignore_path}"
172
+ )
173
+ raise
174
+ except OSError as e:
175
+ logger.error(f"I/O error writing to .gitignore: {e}")
176
+ raise
177
+
178
+
179
+ def ensure_claude_mpm_gitignore(project_dir: str = ".") -> dict:
180
+ """Ensure claude-mpm directories are in .gitignore.
181
+
182
+ Convenience function that wraps GitIgnoreManager to add standard
183
+ claude-mpm configuration directories to .gitignore.
184
+
185
+ Standard Entries Added:
186
+ - .claude-mpm/: Main configuration directory
187
+ - .claude/agents/: Agent runtime files
188
+
189
+ Args:
190
+ project_dir: Project directory path (default: current directory)
191
+
192
+ Returns:
193
+ Dictionary with operation results:
194
+ - added: List of patterns that were added
195
+ - existing: List of patterns that were already present
196
+ - gitignore_path: Path to the .gitignore file
197
+
198
+ Example:
199
+ >>> result = ensure_claude_mpm_gitignore()
200
+ >>> if result["added"]:
201
+ ... print(f"Added {len(result['added'])} entries to .gitignore")
202
+
203
+ Error Handling:
204
+ - PermissionError: Returns error dict with status="error"
205
+ - FileNotFoundError on parent dir: Returns error dict
206
+ - All other exceptions: Propagated to caller
207
+ """
208
+ try:
209
+ manager = GitIgnoreManager(Path(project_dir))
210
+
211
+ # Standard claude-mpm entries
212
+ entries_to_add = [
213
+ ".claude-mpm/",
214
+ ".claude/agents/",
215
+ ".mcp.json",
216
+ ".claude.json",
217
+ ".claude/",
218
+ ]
219
+
220
+ added, existing = manager.ensure_entries(entries_to_add)
221
+
222
+ return {
223
+ "status": "success",
224
+ "added": added,
225
+ "existing": existing,
226
+ "gitignore_path": str(manager.gitignore_path),
227
+ }
228
+
229
+ except PermissionError as e:
230
+ logger.error(f"Permission denied updating .gitignore: {e}")
231
+ return {
232
+ "status": "error",
233
+ "error": f"Permission denied: {e}",
234
+ "added": [],
235
+ "existing": [],
236
+ }
237
+ except FileNotFoundError as e:
238
+ logger.error(f"Project directory not found: {e}")
239
+ return {
240
+ "status": "error",
241
+ "error": f"Directory not found: {e}",
242
+ "added": [],
243
+ "existing": [],
244
+ }
@@ -496,15 +496,15 @@ class LogCleanupUtility:
496
496
  }
497
497
 
498
498
  # Cleanup operations
499
- sessions_removed, sessions_space = self.cleanup_old_sessions(
499
+ _sessions_removed, _sessions_space = self.cleanup_old_sessions(
500
500
  session_max_age_days, dry_run
501
501
  )
502
502
 
503
- archives_removed, archives_space = self.cleanup_archived_logs(
503
+ _archives_removed, _archives_space = self.cleanup_archived_logs(
504
504
  archive_max_age_days, dry_run
505
505
  )
506
506
 
507
- logs_removed, logs_space = self.cleanup_old_logs(log_max_age_days, dry_run)
507
+ _logs_removed, _logs_space = self.cleanup_old_logs(log_max_age_days, dry_run)
508
508
 
509
509
  # Optional compression
510
510
  if compress_age_days is not None: