claude-mpm 4.20.3__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 (520) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +35 -6
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +1241 -667
  5. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  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 +1 -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 +959 -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 +924 -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/__init__.py +73 -0
  41. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  42. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  43. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  44. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  45. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  46. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  47. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  48. claude_mpm/cli/commands/postmortem.py +401 -0
  49. claude_mpm/cli/commands/run.py +125 -167
  50. claude_mpm/cli/commands/skill_source.py +694 -0
  51. claude_mpm/cli/commands/skills.py +835 -44
  52. claude_mpm/cli/executor.py +78 -3
  53. claude_mpm/cli/interactive/agent_wizard.py +1032 -47
  54. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  55. claude_mpm/cli/parsers/agents_parser.py +256 -4
  56. claude_mpm/cli/parsers/auto_configure_parser.py +13 -0
  57. claude_mpm/cli/parsers/base_parser.py +53 -0
  58. claude_mpm/cli/parsers/config_parser.py +96 -43
  59. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  60. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  61. claude_mpm/cli/parsers/skills_parser.py +145 -0
  62. claude_mpm/cli/parsers/source_parser.py +138 -0
  63. claude_mpm/cli/startup.py +564 -108
  64. claude_mpm/cli/startup_display.py +480 -0
  65. claude_mpm/cli/utils.py +1 -1
  66. claude_mpm/cli_module/commands.py +1 -1
  67. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  68. claude_mpm/commands/mpm-agents-detect.md +9 -0
  69. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  70. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  71. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  72. claude_mpm/commands/mpm-doctor.md +9 -0
  73. claude_mpm/commands/mpm-help.md +17 -2
  74. claude_mpm/commands/mpm-init.md +28 -3
  75. claude_mpm/commands/mpm-monitor.md +9 -0
  76. claude_mpm/commands/mpm-postmortem.md +123 -0
  77. claude_mpm/commands/mpm-session-resume.md +381 -0
  78. claude_mpm/commands/mpm-status.md +9 -0
  79. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  80. claude_mpm/commands/mpm-ticket-view.md +552 -0
  81. claude_mpm/commands/mpm-version.md +9 -0
  82. claude_mpm/commands/mpm.md +11 -0
  83. claude_mpm/config/agent_presets.py +488 -0
  84. claude_mpm/config/agent_sources.py +325 -0
  85. claude_mpm/config/skill_presets.py +392 -0
  86. claude_mpm/config/skill_sources.py +590 -0
  87. claude_mpm/constants.py +13 -0
  88. claude_mpm/core/api_validator.py +1 -1
  89. claude_mpm/core/claude_runner.py +19 -35
  90. claude_mpm/core/config.py +24 -0
  91. claude_mpm/core/constants.py +1 -1
  92. claude_mpm/core/framework/__init__.py +3 -16
  93. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  94. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  95. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  96. claude_mpm/core/hook_error_memory.py +381 -0
  97. claude_mpm/core/hook_manager.py +41 -2
  98. claude_mpm/core/interactive_session.py +131 -10
  99. claude_mpm/core/interfaces.py +56 -1
  100. claude_mpm/core/logger.py +3 -1
  101. claude_mpm/core/oneshot_session.py +110 -8
  102. claude_mpm/core/protocols/__init__.py +23 -0
  103. claude_mpm/core/protocols/runner_protocol.py +103 -0
  104. claude_mpm/core/protocols/session_protocol.py +131 -0
  105. claude_mpm/core/shared/singleton_manager.py +11 -4
  106. claude_mpm/core/system_context.py +38 -0
  107. claude_mpm/core/unified_config.py +22 -0
  108. claude_mpm/dashboard/static/css/activity.css +69 -69
  109. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  110. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  111. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  112. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  113. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  114. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  115. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  116. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  117. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  118. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  119. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  120. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  121. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  122. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  123. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  124. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  125. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  126. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  127. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  128. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  129. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  130. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  131. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  132. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  133. claude_mpm/dashboard/templates/code_simple.html +23 -23
  134. claude_mpm/dashboard/templates/index.html +18 -18
  135. claude_mpm/experimental/cli_enhancements.py +1 -5
  136. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  137. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  138. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  139. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  140. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  141. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  142. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  143. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  144. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  145. claude_mpm/hooks/claude_hooks/memory_integration.py +12 -1
  146. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  147. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  148. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  149. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  150. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  151. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  152. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  153. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  154. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  155. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  156. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  157. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  158. claude_mpm/models/git_repository.py +198 -0
  159. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  160. claude_mpm/scripts/start_activity_logging.py +3 -1
  161. claude_mpm/services/agents/agent_builder.py +45 -9
  162. claude_mpm/services/agents/agent_preset_service.py +238 -0
  163. claude_mpm/services/agents/agent_selection_service.py +484 -0
  164. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  165. claude_mpm/services/agents/cache_git_manager.py +621 -0
  166. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  167. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  168. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  169. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  170. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  171. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  172. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  173. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  174. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  175. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  176. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  177. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  178. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  179. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  180. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  181. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  182. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  183. claude_mpm/services/agents/git_source_manager.py +629 -0
  184. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  185. claude_mpm/services/agents/local_template_manager.py +50 -10
  186. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  187. claude_mpm/services/agents/sources/__init__.py +13 -0
  188. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  189. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  190. claude_mpm/services/agents/startup_sync.py +239 -0
  191. claude_mpm/services/agents/toolchain_detector.py +474 -0
  192. claude_mpm/services/analysis/__init__.py +25 -0
  193. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  194. claude_mpm/services/analysis/postmortem_service.py +765 -0
  195. claude_mpm/services/cli/session_pause_manager.py +504 -0
  196. claude_mpm/services/cli/session_resume_helper.py +36 -16
  197. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  198. claude_mpm/services/command_deployment_service.py +200 -6
  199. claude_mpm/services/core/base.py +31 -11
  200. claude_mpm/services/core/interfaces/__init__.py +1 -3
  201. claude_mpm/services/core/interfaces/health.py +1 -4
  202. claude_mpm/services/core/interfaces.py +56 -1
  203. claude_mpm/services/core/models/__init__.py +2 -11
  204. claude_mpm/services/core/models/agent_config.py +3 -0
  205. claude_mpm/services/core/models/process.py +4 -0
  206. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  207. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  208. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  209. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  210. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  211. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  212. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  213. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  214. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  215. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  216. claude_mpm/services/diagnostics/models.py +21 -0
  217. claude_mpm/services/event_bus/direct_relay.py +3 -3
  218. claude_mpm/services/event_bus/event_bus.py +36 -3
  219. claude_mpm/services/event_bus/relay.py +23 -7
  220. claude_mpm/services/events/consumers/logging.py +1 -2
  221. claude_mpm/services/git/__init__.py +21 -0
  222. claude_mpm/services/git/git_operations_service.py +494 -0
  223. claude_mpm/services/github/__init__.py +21 -0
  224. claude_mpm/services/github/github_cli_service.py +397 -0
  225. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  226. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  227. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  228. claude_mpm/services/instructions/__init__.py +9 -0
  229. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  230. claude_mpm/services/local_ops/__init__.py +5 -13
  231. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  232. claude_mpm/services/local_ops/health_manager.py +1 -4
  233. claude_mpm/services/local_ops/process_manager.py +1 -1
  234. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  235. claude_mpm/services/mcp_config_manager.py +75 -145
  236. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  237. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  238. claude_mpm/services/mcp_gateway/core/process_pool.py +41 -26
  239. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  240. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  241. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  242. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  243. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  244. claude_mpm/services/mcp_service_verifier.py +6 -3
  245. claude_mpm/services/memory/failure_tracker.py +19 -4
  246. claude_mpm/services/memory/optimizer.py +1 -1
  247. claude_mpm/services/model/model_router.py +8 -9
  248. claude_mpm/services/monitor/daemon.py +29 -9
  249. claude_mpm/services/monitor/daemon_manager.py +96 -19
  250. claude_mpm/services/monitor/server.py +2 -2
  251. claude_mpm/services/native_agent_converter.py +356 -0
  252. claude_mpm/services/port_manager.py +1 -1
  253. claude_mpm/services/pr/__init__.py +14 -0
  254. claude_mpm/services/pr/pr_template_service.py +329 -0
  255. claude_mpm/services/project/documentation_manager.py +2 -1
  256. claude_mpm/services/project/project_organizer.py +4 -0
  257. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  258. claude_mpm/services/runner_configuration_service.py +17 -3
  259. claude_mpm/services/self_upgrade_service.py +165 -7
  260. claude_mpm/services/session_management_service.py +16 -4
  261. claude_mpm/services/skills/__init__.py +18 -0
  262. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  263. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  264. claude_mpm/services/skills_config.py +547 -0
  265. claude_mpm/services/skills_deployer.py +955 -0
  266. claude_mpm/services/socketio/handlers/connection.py +1 -1
  267. claude_mpm/services/socketio/handlers/git.py +2 -2
  268. claude_mpm/services/socketio/server/core.py +1 -4
  269. claude_mpm/services/socketio/server/main.py +1 -3
  270. claude_mpm/services/system_instructions_service.py +1 -3
  271. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  272. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  273. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  274. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  275. claude_mpm/services/unified/unified_deployment.py +1 -5
  276. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  277. claude_mpm/services/visualization/__init__.py +1 -5
  278. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  279. claude_mpm/skills/__init__.py +3 -3
  280. claude_mpm/skills/agent_skills_injector.py +42 -49
  281. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  282. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
  283. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
  284. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
  285. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
  286. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
  287. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  288. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
  289. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
  290. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
  291. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
  292. claude_mpm/skills/skills_registry.py +44 -48
  293. claude_mpm/skills/skills_service.py +117 -108
  294. claude_mpm/templates/questions/__init__.py +38 -0
  295. claude_mpm/templates/questions/base.py +193 -0
  296. claude_mpm/templates/questions/pr_strategy.py +311 -0
  297. claude_mpm/templates/questions/project_init.py +385 -0
  298. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  299. claude_mpm/tools/__main__.py +8 -8
  300. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  301. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  302. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  303. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  304. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  305. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  306. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  307. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  308. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  309. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  310. claude_mpm/utils/agent_dependency_loader.py +80 -13
  311. claude_mpm/utils/agent_filters.py +288 -0
  312. claude_mpm/utils/dependency_cache.py +3 -1
  313. claude_mpm/utils/gitignore.py +244 -0
  314. claude_mpm/utils/log_cleanup.py +3 -3
  315. claude_mpm/utils/migration.py +372 -0
  316. claude_mpm/utils/progress.py +387 -0
  317. claude_mpm/utils/robust_installer.py +3 -5
  318. claude_mpm/utils/structured_questions.py +619 -0
  319. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/METADATA +496 -65
  320. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/RECORD +328 -416
  321. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  322. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  323. claude_mpm/agents/templates/agent-manager.json +0 -273
  324. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  325. claude_mpm/agents/templates/api_qa.json +0 -180
  326. claude_mpm/agents/templates/circuit_breakers.md +0 -638
  327. claude_mpm/agents/templates/clerk-ops.json +0 -235
  328. claude_mpm/agents/templates/code_analyzer.json +0 -101
  329. claude_mpm/agents/templates/content-agent.json +0 -358
  330. claude_mpm/agents/templates/dart_engineer.json +0 -307
  331. claude_mpm/agents/templates/data_engineer.json +0 -225
  332. claude_mpm/agents/templates/documentation.json +0 -211
  333. claude_mpm/agents/templates/engineer.json +0 -210
  334. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  335. claude_mpm/agents/templates/golang_engineer.json +0 -270
  336. claude_mpm/agents/templates/imagemagick.json +0 -264
  337. claude_mpm/agents/templates/java_engineer.json +0 -346
  338. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  339. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  340. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  341. claude_mpm/agents/templates/memory_manager.json +0 -158
  342. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  343. claude_mpm/agents/templates/ops.json +0 -185
  344. claude_mpm/agents/templates/php-engineer.json +0 -281
  345. claude_mpm/agents/templates/product_owner.json +0 -338
  346. claude_mpm/agents/templates/project_organizer.json +0 -140
  347. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  348. claude_mpm/agents/templates/python_engineer.json +0 -387
  349. claude_mpm/agents/templates/qa.json +0 -242
  350. claude_mpm/agents/templates/react_engineer.json +0 -238
  351. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  352. claude_mpm/agents/templates/research.json +0 -188
  353. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  354. claude_mpm/agents/templates/rust_engineer.json +0 -275
  355. claude_mpm/agents/templates/security.json +0 -202
  356. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  357. claude_mpm/agents/templates/ticketing.json +0 -177
  358. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  359. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  360. claude_mpm/agents/templates/version_control.json +0 -157
  361. claude_mpm/agents/templates/web_qa.json +0 -399
  362. claude_mpm/agents/templates/web_ui.json +0 -189
  363. claude_mpm/cli/commands/mpm_init.py +0 -2093
  364. claude_mpm/commands/mpm-tickets.md +0 -102
  365. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  366. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  367. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  368. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  369. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  370. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  371. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  372. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  373. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  374. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  375. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  376. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  377. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  378. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  379. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  380. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  381. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  382. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  383. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  384. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  385. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  386. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  387. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  388. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  389. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  390. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  391. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  392. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  393. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  394. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  395. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  396. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  397. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  398. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  399. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  400. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  401. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  402. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  403. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  404. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  405. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  406. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  407. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  408. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  409. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  410. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  411. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  412. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  413. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  414. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  415. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  416. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  417. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  418. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  419. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  420. claude_mpm/dashboard/static/built/react/events.js +0 -30
  421. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  422. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  423. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  424. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  425. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  426. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  427. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  428. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  429. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  430. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  431. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  432. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  433. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  434. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  435. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  436. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  437. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  438. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  439. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  440. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  441. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  442. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  443. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  444. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  445. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  446. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  447. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  448. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  449. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  450. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  451. claude_mpm/dashboard/static/events.html +0 -607
  452. claude_mpm/dashboard/static/index.html +0 -635
  453. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  454. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  455. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  456. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  457. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  458. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  459. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  460. claude_mpm/dashboard/static/legacy/files.html +0 -747
  461. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  462. claude_mpm/dashboard/static/monitors.html +0 -431
  463. claude_mpm/dashboard/static/production/events.html +0 -659
  464. claude_mpm/dashboard/static/production/main.html +0 -698
  465. claude_mpm/dashboard/static/production/monitors.html +0 -483
  466. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  467. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  468. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  469. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  470. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  471. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -75
  472. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -184
  473. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -107
  474. claude_mpm/skills/bundled/collaboration/requesting-code-review/code-reviewer.md +0 -146
  475. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -118
  476. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -177
  477. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  478. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  479. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  480. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  481. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  482. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  483. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  484. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  485. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  486. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  487. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -175
  488. claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
  489. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -314
  490. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -227
  491. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -74
  492. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -32
  493. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  494. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  495. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  496. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  497. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -328
  498. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  499. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  500. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  501. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  502. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -209
  503. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -123
  504. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  505. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  506. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  507. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  508. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  509. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  510. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -304
  511. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -96
  512. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  513. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  514. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  515. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  516. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  517. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/WHEEL +0 -0
  518. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/entry_points.txt +0 -0
  519. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/licenses/LICENSE +0 -0
  520. {claude_mpm-4.20.3.dist-info → claude_mpm-5.1.8.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,621 @@
1
+ """
2
+ Cache Git Manager - Git workflow integration for agent cache management.
3
+
4
+ Design Decision: Wrap existing GitOperationsService instead of duplicating code
5
+
6
+ Rationale: GitOperationsService already provides all necessary git operations
7
+ (status, pull, commit, push) with proper error handling. This wrapper adapts
8
+ it specifically for cache directory operations without code duplication.
9
+
10
+ Trade-offs:
11
+ - Code Reuse: Leverages 90% of existing GitOperationsService (~400 lines)
12
+ - Maintainability: Changes to git operations benefit all users
13
+ - Specificity: Adds cache-specific behavior (status reporting, sync workflow)
14
+ - Simplicity: Net new code ~150 lines vs ~400 for complete reimplementation
15
+
16
+ Performance:
17
+ - Time Complexity: O(1) for status checks, O(n) for file operations where n = number of changed files
18
+ - Expected Performance:
19
+ * Status check: ~100-200ms (git status + rev-list)
20
+ * Pull latest: ~1-2s (git pull from GitHub)
21
+ * Commit + push: ~2-3s (git commit + push)
22
+
23
+ Error Handling:
24
+ - Network unavailable: Warns user, continues with cached version
25
+ - Merge conflicts: Detects, displays files, guides user to manual resolution
26
+ - Detached HEAD: Warns user, provides recovery instructions
27
+ - Push rejected: Informs about remote changes, suggests pull first
28
+ - Uncommitted changes: Warns before pull, offers to continue or abort
29
+
30
+ Example:
31
+ >>> from pathlib import Path
32
+ >>> manager = CacheGitManager(Path.home() / ".claude-mpm/cache/remote-agents")
33
+ >>> if manager.is_git_repo():
34
+ ... status = manager.get_status()
35
+ ... print(f"Branch: {status['branch']}, Uncommitted: {len(status['uncommitted'])}")
36
+ ... success, msg = manager.pull_latest()
37
+ """
38
+
39
+ import logging
40
+ from pathlib import Path
41
+ from typing import Any, Dict, List, Optional, Tuple
42
+
43
+ from claude_mpm.services.git.git_operations_service import (
44
+ GitAuthenticationError,
45
+ GitConflictError,
46
+ GitOperationError,
47
+ GitOperationsService,
48
+ )
49
+
50
+ logger = logging.getLogger(__name__)
51
+
52
+
53
+ class CacheGitManager:
54
+ """
55
+ Git operations wrapper for agent cache directory.
56
+
57
+ Design Decision: Composition over inheritance
58
+
59
+ Rationale: Wraps GitOperationsService instead of inheriting to maintain
60
+ separation of concerns. Cache-specific logic (sync workflow, status
61
+ reporting) is independent from core git operations.
62
+
63
+ Provides high-level git workflows specifically for cache management:
64
+ - Pre-deploy git pull (sync latest agents)
65
+ - Status reporting with uncommitted/unpushed detection
66
+ - Full sync workflow (pull, handle conflicts, push)
67
+ - User-friendly error messages for cache context
68
+ """
69
+
70
+ def __init__(self, cache_path: Path, timeout: int = 30):
71
+ """
72
+ Initialize cache git manager.
73
+
74
+ Args:
75
+ cache_path: Path to cache directory (should contain .git)
76
+ timeout: Git command timeout in seconds (default: 30)
77
+
78
+ Example:
79
+ >>> cache_dir = Path.home() / ".claude-mpm/cache/remote-agents"
80
+ >>> manager = CacheGitManager(cache_dir)
81
+ """
82
+ self.cache_path = Path(cache_path)
83
+ self.git_ops = GitOperationsService(timeout=timeout)
84
+
85
+ # Find git repository root (cache_path or parent)
86
+ self.repo_path = self._find_git_root()
87
+
88
+ if self.repo_path:
89
+ logger.debug(f"Initialized CacheGitManager for repo: {self.repo_path}")
90
+ else:
91
+ logger.warning(f"Cache path is not a git repository: {cache_path}")
92
+
93
+ def _find_git_root(self) -> Optional[Path]:
94
+ """
95
+ Find git repository root starting from cache_path.
96
+
97
+ Searches cache_path and up to 3 parent directories for .git directory.
98
+ If not found upward, searches one level down into subdirectories.
99
+ This handles both cases:
100
+ - cache_path is inside repo (search upward)
101
+ - repo is nested in cache_path (search downward)
102
+
103
+ Returns:
104
+ Path to repository root, or None if not a git repo
105
+
106
+ Example:
107
+ >>> # Case 1: cache_path inside repo (searches upward)
108
+ >>> # cache_path: ~/.claude-mpm/cache/remote-agents/bobmatnyc/claude-mpm-agents/agents
109
+ >>> # Found at: ~/.claude-mpm/cache/remote-agents/bobmatnyc/claude-mpm-agents
110
+
111
+ >>> # Case 2: repo nested in cache_path (searches downward)
112
+ >>> # cache_path: ~/.claude-mpm/cache/remote-agents
113
+ >>> # Found at: ~/.claude-mpm/cache/remote-agents/bobmatnyc/claude-mpm-agents
114
+ """
115
+ # Strategy 1: Search upward (cache_path is inside repo)
116
+ current = self.cache_path
117
+ max_depth = 3
118
+
119
+ for _ in range(max_depth):
120
+ if self.git_ops.is_git_repo(current):
121
+ return current
122
+ parent = current.parent
123
+ if parent == current: # Reached filesystem root
124
+ break
125
+ current = parent
126
+
127
+ # Strategy 2: Search downward one level (repo nested in cache_path)
128
+ # Check immediate subdirectories for git repos
129
+ if self.cache_path.is_dir():
130
+ try:
131
+ for subdir in self.cache_path.iterdir():
132
+ if subdir.is_dir():
133
+ # Check if subdir itself is a git repo
134
+ if self.git_ops.is_git_repo(subdir):
135
+ return subdir
136
+
137
+ # Check one level deeper (handle org/repo structure)
138
+ try:
139
+ for nested_dir in subdir.iterdir():
140
+ if nested_dir.is_dir() and self.git_ops.is_git_repo(
141
+ nested_dir
142
+ ):
143
+ return nested_dir
144
+ except (OSError, PermissionError):
145
+ # Skip subdirectories we can't read
146
+ continue
147
+ except (OSError, PermissionError) as e:
148
+ logger.debug(f"Could not scan cache directory for git repos: {e}")
149
+
150
+ return None
151
+
152
+ def is_git_repo(self) -> bool:
153
+ """
154
+ Check if cache is a git repository.
155
+
156
+ Returns:
157
+ True if cache contains a valid git repository, False otherwise
158
+
159
+ Example:
160
+ >>> if not manager.is_git_repo():
161
+ ... print("Cache is not a git repo. Falling back to HTTP sync.")
162
+ """
163
+ return self.repo_path is not None
164
+
165
+ def get_status(self) -> Dict[str, Any]:
166
+ """
167
+ Get comprehensive git status for cache.
168
+
169
+ Returns dictionary with current branch, uncommitted changes, and
170
+ unpushed commits. Useful for warning users before destructive operations.
171
+
172
+ Returns:
173
+ Dictionary with status information:
174
+ {
175
+ "branch": "main",
176
+ "uncommitted": ["agents/engineer.md", "agents/research.md"],
177
+ "uncommitted_count": 2,
178
+ "unpushed": 3,
179
+ "is_clean": False,
180
+ "remote_url": "https://github.com/owner/repo",
181
+ "ahead": 3,
182
+ "behind": 0
183
+ }
184
+
185
+ Error Handling:
186
+ - Not a git repo: Returns error dict with "error" key
187
+ - Git command failure: Logs error, returns partial status
188
+
189
+ Example:
190
+ >>> status = manager.get_status()
191
+ >>> if status.get("uncommitted_count", 0) > 0:
192
+ ... print(f"Warning: {status['uncommitted_count']} uncommitted changes")
193
+ ... for file in status["uncommitted"]:
194
+ ... print(f" - {file}")
195
+ """
196
+ if not self.is_git_repo():
197
+ return {"error": "Not a git repository", "is_clean": True}
198
+
199
+ try:
200
+ # Get current branch
201
+ branch = self.git_ops.get_current_branch(self.repo_path)
202
+
203
+ # Get uncommitted changes
204
+ has_changes = self.git_ops.has_uncommitted_changes(self.repo_path)
205
+ uncommitted_files: List[str] = []
206
+
207
+ if has_changes:
208
+ # Parse git status --porcelain for file list
209
+ returncode, stdout, _stderr = self.git_ops._run_git_command(
210
+ ["git", "status", "--porcelain"], cwd=self.repo_path
211
+ )
212
+ if returncode == 0:
213
+ # Split without stripping first to preserve format
214
+ for line in stdout.split("\n"):
215
+ if line.strip():
216
+ # Extract filename from git status output (format: "XY filename")
217
+ # Skip first 3 characters (2 status + 1 space)
218
+ filename = (
219
+ line[3:].strip() if len(line) > 3 else line.strip()
220
+ )
221
+ if filename:
222
+ uncommitted_files.append(filename)
223
+
224
+ # Get unpushed commits (commits ahead of remote)
225
+ ahead = 0
226
+ behind = 0
227
+ try:
228
+ returncode, stdout, _stderr = self.git_ops._run_git_command(
229
+ [
230
+ "git",
231
+ "rev-list",
232
+ "--left-right",
233
+ "--count",
234
+ f"origin/{branch}...HEAD",
235
+ ],
236
+ cwd=self.repo_path,
237
+ )
238
+ if returncode == 0 and stdout.strip():
239
+ parts = stdout.strip().split()
240
+ if len(parts) == 2:
241
+ try:
242
+ behind, ahead = map(int, parts)
243
+ except ValueError:
244
+ # Parsing error, skip ahead/behind count
245
+ logger.debug(
246
+ f"Could not parse rev-list output: {stdout.strip()}"
247
+ )
248
+ except (GitOperationError, Exception) as e:
249
+ # No remote tracking branch configured or other error
250
+ logger.debug(f"Could not get ahead/behind count: {e}")
251
+
252
+ # Get remote URL
253
+ remote_url = self.git_ops.get_remote_url(self.repo_path)
254
+
255
+ return {
256
+ "branch": branch,
257
+ "uncommitted": uncommitted_files,
258
+ "uncommitted_count": len(uncommitted_files),
259
+ "unpushed": ahead,
260
+ "is_clean": not has_changes and ahead == 0,
261
+ "remote_url": remote_url,
262
+ "ahead": ahead,
263
+ "behind": behind,
264
+ }
265
+
266
+ except GitOperationError as e:
267
+ logger.error(f"Error getting git status: {e}")
268
+ return {
269
+ "error": str(e),
270
+ "is_clean": False,
271
+ }
272
+
273
+ def pull_latest(self, branch: str = "main") -> Tuple[bool, str]:
274
+ """
275
+ Pull latest changes from remote.
276
+
277
+ Design Decision: Non-blocking pull with informative messages
278
+
279
+ Rationale: Pull failures shouldn't stop deployment. Cache may be
280
+ outdated but still usable. HTTP sync provides fallback mechanism.
281
+
282
+ Args:
283
+ branch: Branch to pull (default: "main")
284
+
285
+ Returns:
286
+ Tuple of (success, message) where:
287
+ - success: True if pull succeeded, False if failed
288
+ - message: Human-readable status message
289
+
290
+ Error Handling:
291
+ - Merge conflicts: Returns (False, detailed conflict message)
292
+ - Network errors: Returns (False, network error message)
293
+ - Detached HEAD: Returns (False, recovery instructions)
294
+ - Success: Returns (True, summary of changes)
295
+
296
+ Example:
297
+ >>> success, msg = manager.pull_latest()
298
+ >>> if not success:
299
+ ... logger.warning(f"Pull failed: {msg}")
300
+ ... logger.info("Continuing with cached version")
301
+ """
302
+ if not self.is_git_repo():
303
+ return False, "Not a git repository"
304
+
305
+ try:
306
+ # Check for uncommitted changes first
307
+ if self.git_ops.has_uncommitted_changes(self.repo_path):
308
+ uncommitted_count = len(self.get_status().get("uncommitted", []))
309
+ logger.warning(
310
+ f"Cache has {uncommitted_count} uncommitted change(s). "
311
+ "Pull may fail or create merge conflicts."
312
+ )
313
+
314
+ # Perform pull
315
+ self.git_ops.pull(self.repo_path, branch)
316
+
317
+ logger.info(f"Successfully pulled latest changes from {branch}")
318
+ return True, f"Successfully pulled latest changes from {branch}"
319
+
320
+ except GitConflictError:
321
+ # Parse conflict details from error message
322
+ conflict_msg = (
323
+ f"Merge conflicts detected when pulling {branch}. "
324
+ "Manual resolution required.\n\n"
325
+ "To resolve:\n"
326
+ f" 1. cd {self.repo_path}\n"
327
+ " 2. Resolve conflicts in affected files\n"
328
+ " 3. git add <resolved-files>\n"
329
+ " 4. git commit\n"
330
+ " 5. Run sync again"
331
+ )
332
+ logger.error(conflict_msg)
333
+ return False, conflict_msg
334
+
335
+ except GitOperationError as e:
336
+ error_msg = f"Failed to pull {branch}: {e!s}"
337
+ logger.error(error_msg)
338
+ return False, error_msg
339
+
340
+ def commit_changes(
341
+ self, message: str, files: Optional[List[Path]] = None
342
+ ) -> Tuple[bool, str]:
343
+ """
344
+ Commit changes to cache.
345
+
346
+ Args:
347
+ message: Commit message (should follow conventional commits format)
348
+ files: Specific files to commit (None = all modified files)
349
+
350
+ Returns:
351
+ Tuple of (success, message)
352
+
353
+ Error Handling:
354
+ - No changes to commit: Returns (False, informative message)
355
+ - Git commit failure: Returns (False, error details)
356
+ - File staging error: Returns (False, staging error message)
357
+
358
+ Example:
359
+ >>> success, msg = manager.commit_changes(
360
+ ... "feat: update agents from local development",
361
+ ... files=[Path("agents/engineer.md")]
362
+ ... )
363
+ >>> if success:
364
+ ... print(f"Committed: {msg}")
365
+ """
366
+ if not self.is_git_repo():
367
+ return False, "Not a git repository"
368
+
369
+ try:
370
+ # Stage files
371
+ if files:
372
+ # Convert Path objects to strings relative to repo root
373
+ file_strs = [str(f.relative_to(self.repo_path)) for f in files]
374
+ self.git_ops.stage_files(self.repo_path, file_strs)
375
+ else:
376
+ # Stage all changes
377
+ self.git_ops.stage_files(self.repo_path, ["."])
378
+
379
+ # Commit
380
+ self.git_ops.commit(self.repo_path, message)
381
+
382
+ logger.info(f"Committed changes: {message[:50]}")
383
+ return True, "Successfully committed changes"
384
+
385
+ except GitOperationError as e:
386
+ error_msg = f"Failed to commit: {e!s}"
387
+ logger.error(error_msg)
388
+ return False, error_msg
389
+
390
+ def push_changes(self, branch: str = "main") -> Tuple[bool, str]:
391
+ """
392
+ Push committed changes to remote.
393
+
394
+ Args:
395
+ branch: Branch to push (default: "main")
396
+
397
+ Returns:
398
+ Tuple of (success, message)
399
+
400
+ Error Handling:
401
+ - Authentication failure: Returns (False, auth error with instructions)
402
+ - Push rejected: Returns (False, suggests pull first)
403
+ - Network error: Returns (False, network error message)
404
+
405
+ Example:
406
+ >>> success, msg = manager.push_changes()
407
+ >>> if not success:
408
+ ... if "authentication" in msg.lower():
409
+ ... print("Configure SSH keys or GitHub token")
410
+ """
411
+ if not self.is_git_repo():
412
+ return False, "Not a git repository"
413
+
414
+ try:
415
+ self.git_ops.push(self.repo_path, branch, set_upstream=True)
416
+
417
+ logger.info(f"Successfully pushed changes to {branch}")
418
+ return True, f"Successfully pushed changes to {branch}"
419
+
420
+ except GitAuthenticationError as e:
421
+ error_msg = (
422
+ f"Authentication failed: {e!s}\n\n"
423
+ "To fix:\n"
424
+ " 1. Configure SSH keys: ssh-keygen -t ed25519\n"
425
+ " 2. Add to GitHub: https://github.com/settings/keys\n"
426
+ " OR\n"
427
+ " 3. Use HTTPS with token: git remote set-url origin https://TOKEN@github.com/owner/repo"
428
+ )
429
+ logger.error(error_msg)
430
+ return False, error_msg
431
+
432
+ except GitOperationError as e:
433
+ # Check if push was rejected due to remote changes
434
+ if "rejected" in str(e).lower() or "non-fast-forward" in str(e).lower():
435
+ error_msg = (
436
+ "Push rejected: Remote has changes you don't have locally.\n\n"
437
+ "To fix:\n"
438
+ " 1. Pull latest changes: git pull origin main\n"
439
+ " 2. Resolve any conflicts\n"
440
+ " 3. Push again"
441
+ )
442
+ else:
443
+ error_msg = f"Failed to push: {e!s}"
444
+
445
+ logger.error(error_msg)
446
+ return False, error_msg
447
+
448
+ def has_uncommitted_changes(self) -> bool:
449
+ """
450
+ Check for uncommitted changes in cache.
451
+
452
+ Returns:
453
+ True if there are uncommitted changes, False otherwise
454
+
455
+ Example:
456
+ >>> if manager.has_uncommitted_changes():
457
+ ... print("⚠️ Uncommitted changes detected")
458
+ ... print("Commit changes before pushing")
459
+ """
460
+ if not self.is_git_repo():
461
+ return False
462
+
463
+ try:
464
+ return self.git_ops.has_uncommitted_changes(self.repo_path)
465
+ except GitOperationError:
466
+ return False
467
+
468
+ def has_unpushed_commits(self) -> bool:
469
+ """
470
+ Check for commits not pushed to remote.
471
+
472
+ Returns:
473
+ True if there are unpushed commits, False otherwise
474
+
475
+ Example:
476
+ >>> if manager.has_unpushed_commits():
477
+ ... print("📤 You have local commits not pushed to remote")
478
+ ... print("Run: claude-mpm agents cache-push")
479
+ """
480
+ status = self.get_status()
481
+ return status.get("unpushed", 0) > 0
482
+
483
+ def check_conflicts(self) -> List[Path]:
484
+ """
485
+ Check for merge conflicts after pull.
486
+
487
+ Scans working directory for Git conflict markers (<<<<<<, ======, >>>>>>).
488
+
489
+ Returns:
490
+ List of file paths with unresolved conflicts
491
+
492
+ Algorithm:
493
+ 1. Run git status --porcelain to find files with merge conflicts
494
+ 2. Look for "UU" status (both modified - conflict)
495
+ 3. Return relative paths for user-friendly display
496
+
497
+ Example:
498
+ >>> conflicts = manager.check_conflicts()
499
+ >>> if conflicts:
500
+ ... print("⚠️ Merge conflicts detected:")
501
+ ... for file in conflicts:
502
+ ... print(f" - {file}")
503
+ """
504
+ if not self.is_git_repo():
505
+ return []
506
+
507
+ try:
508
+ returncode, stdout, _stderr = self.git_ops._run_git_command(
509
+ ["git", "status", "--porcelain"], cwd=self.repo_path
510
+ )
511
+
512
+ if returncode != 0:
513
+ return []
514
+
515
+ # Parse git status output for conflict markers
516
+ conflicted_files: List[Path] = []
517
+ for line in stdout.strip().split("\n"):
518
+ if line.strip():
519
+ status = line[:2]
520
+ # "UU" means both modified (merge conflict)
521
+ # "AA" means both added
522
+ # "DD" means both deleted
523
+ if status in ["UU", "AA", "DD", "AU", "UA", "DU", "UD"]:
524
+ filename = line[3:].strip()
525
+ conflicted_files.append(Path(filename))
526
+
527
+ return conflicted_files
528
+
529
+ except GitOperationError as e:
530
+ logger.error(f"Error checking conflicts: {e}")
531
+ return []
532
+
533
+ def sync_with_remote(self) -> Tuple[bool, str]:
534
+ """
535
+ Full sync workflow: pull, handle conflicts, push if needed.
536
+
537
+ Design Decision: Three-phase sync with conflict detection
538
+
539
+ Rationale: Provides complete sync automation while protecting against
540
+ data loss. Detects issues (uncommitted changes, conflicts) and guides
541
+ user through resolution rather than silently failing.
542
+
543
+ Workflow:
544
+ 1. Check for uncommitted changes (warn user but continue)
545
+ 2. Pull latest from remote
546
+ 3. Detect and report conflicts (stops if found)
547
+ 4. Push local commits if any exist and no conflicts
548
+
549
+ Returns:
550
+ Tuple of (success, detailed_message)
551
+
552
+ Error Handling:
553
+ - Uncommitted changes: Warns user, continues with pull
554
+ - Conflicts: Stops sync, provides resolution instructions
555
+ - Network errors: Reports error, doesn't attempt push
556
+ - Push failures: Reports error with recovery instructions
557
+
558
+ Example:
559
+ >>> success, msg = manager.sync_with_remote()
560
+ >>> print(msg) # Detailed breakdown of sync process
561
+ >>> if not success:
562
+ ... logger.error("Sync failed, investigate manually")
563
+ """
564
+ if not self.is_git_repo():
565
+ return False, "Not a git repository"
566
+
567
+ status_log = []
568
+
569
+ # Phase 1: Check for uncommitted changes
570
+ status_log.append("Phase 1: Checking local changes...")
571
+ if self.has_uncommitted_changes():
572
+ uncommitted_count = self.get_status().get("uncommitted_count", 0)
573
+ warning = (
574
+ f"⚠️ Warning: {uncommitted_count} uncommitted change(s) detected.\n"
575
+ " Sync will continue, but you should commit these changes."
576
+ )
577
+ status_log.append(warning)
578
+ logger.warning(warning)
579
+
580
+ # Phase 2: Pull latest
581
+ status_log.append("\nPhase 2: Pulling latest changes...")
582
+ pull_success, pull_msg = self.pull_latest()
583
+
584
+ if not pull_success:
585
+ status_log.append(f"❌ Pull failed: {pull_msg}")
586
+ return False, "\n".join(status_log)
587
+
588
+ status_log.append(f"✅ {pull_msg}")
589
+
590
+ # Phase 3: Check for conflicts
591
+ status_log.append("\nPhase 3: Checking for conflicts...")
592
+ conflicts = self.check_conflicts()
593
+
594
+ if conflicts:
595
+ conflict_msg = (
596
+ f"❌ {len(conflicts)} merge conflict(s) detected:\n"
597
+ + "\n".join(f" - {file}" for file in conflicts)
598
+ + "\n\nResolve conflicts manually before continuing."
599
+ )
600
+ status_log.append(conflict_msg)
601
+ return False, "\n".join(status_log)
602
+
603
+ status_log.append("✅ No conflicts detected")
604
+
605
+ # Phase 4: Push if we have local commits
606
+ status_log.append("\nPhase 4: Checking for local commits...")
607
+ if self.has_unpushed_commits():
608
+ unpushed = self.get_status().get("unpushed", 0)
609
+ status_log.append(f"📤 Pushing {unpushed} local commit(s)...")
610
+
611
+ push_success, push_msg = self.push_changes()
612
+ if not push_success:
613
+ status_log.append(f"❌ Push failed: {push_msg}")
614
+ return False, "\n".join(status_log)
615
+
616
+ status_log.append(f"✅ {push_msg}")
617
+ else:
618
+ status_log.append("✅ No local commits to push")
619
+
620
+ status_log.append("\n✅ Sync complete!")
621
+ return True, "\n".join(status_log)