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,13 @@
1
+ """Git source sync services for agent templates.
2
+
3
+ This module provides services for syncing agent templates from remote
4
+ Git repositories, with ETag-based caching for efficient updates and
5
+ SQLite-based state tracking.
6
+ """
7
+
8
+ from claude_mpm.services.agents.sources.agent_sync_state import AgentSyncState
9
+ from claude_mpm.services.agents.sources.git_source_sync_service import (
10
+ GitSourceSyncService,
11
+ )
12
+
13
+ __all__ = ["AgentSyncState", "GitSourceSyncService"]
@@ -0,0 +1,516 @@
1
+ """SQLite-based state tracking for agent sync operations.
2
+
3
+ This service manages sync state for agent files from Git sources, providing:
4
+ - Per-file SHA-256 content hash tracking
5
+ - Source metadata (URLs, last commit SHA, ETags)
6
+ - Complete sync history audit trail
7
+ - Change detection for efficient incremental updates
8
+
9
+ Database Location: ~/.config/claude-mpm/agent_sync.db
10
+ Thread Safety: Uses connection-per-operation pattern (safe for single-threaded use)
11
+ Performance: Optimized with indexes; expected <10ms per operation
12
+ """
13
+
14
+ import logging
15
+ import sqlite3
16
+ from contextlib import contextmanager
17
+ from datetime import datetime, timedelta, timezone
18
+ from pathlib import Path
19
+ from typing import Any, Dict, List, Optional
20
+
21
+ logger = logging.getLogger(__name__)
22
+
23
+
24
+ class AgentSyncStateError(Exception):
25
+ """Base exception for sync state errors."""
26
+
27
+
28
+ class DatabaseError(AgentSyncStateError):
29
+ """Database operation errors."""
30
+
31
+
32
+ class AgentSyncState:
33
+ """Service for tracking agent sync state in SQLite database.
34
+
35
+ Responsibilities:
36
+ - Manage SQLite connection lifecycle
37
+ - Track per-file content hashes (SHA-256)
38
+ - Record sync history with timestamps
39
+ - Query file change status
40
+ - Provide migration utilities
41
+
42
+ Design Decision: Connection-per-operation pattern
43
+
44
+ Rationale: Simplifies connection management and prevents connection leaks.
45
+ SQLite allows concurrent reads but serializes writes, so connection pooling
46
+ provides minimal benefit for our read-heavy workload.
47
+
48
+ Trade-offs:
49
+ - Simplicity: No pool management overhead
50
+ - Safety: Automatic cleanup via context manager
51
+ - Performance: Negligible overhead (<1ms per connection)
52
+
53
+ Extension Points: Can add connection pooling if multi-threaded access needed.
54
+ """
55
+
56
+ # Schema version for migrations
57
+ SCHEMA_VERSION = 1
58
+
59
+ def __init__(self, db_path: Optional[Path] = None):
60
+ """Initialize sync state service.
61
+
62
+ Args:
63
+ db_path: Path to SQLite database (defaults to ~/.config/claude-mpm/agent_sync.db)
64
+ """
65
+ if db_path:
66
+ self.db_path = Path(db_path)
67
+ else:
68
+ # Default location: ~/.config/claude-mpm/agent_sync.db
69
+ config_dir = Path.home() / ".config" / "claude-mpm"
70
+ config_dir.mkdir(parents=True, exist_ok=True)
71
+ self.db_path = config_dir / "agent_sync.db"
72
+
73
+ # Initialize database
74
+ self._initialize_database()
75
+
76
+ @contextmanager
77
+ def _get_connection(self):
78
+ """Context manager for database connections.
79
+
80
+ Yields:
81
+ sqlite3.Connection with foreign keys enabled and row factory
82
+
83
+ Error Handling:
84
+ - Exception during transaction: Rolls back automatically
85
+ - Connection errors: Propagates to caller
86
+ - Cleanup: Always closes connection
87
+ """
88
+ conn = sqlite3.connect(str(self.db_path))
89
+ conn.row_factory = sqlite3.Row # Enable dict-like access
90
+ conn.execute("PRAGMA foreign_keys = ON") # Enable FK constraints
91
+ try:
92
+ yield conn
93
+ conn.commit()
94
+ except Exception:
95
+ conn.rollback()
96
+ raise
97
+ finally:
98
+ conn.close()
99
+
100
+ def _initialize_database(self):
101
+ """Initialize database schema if not exists.
102
+
103
+ Creates all tables, indexes, and metadata on first run.
104
+ Verifies schema version on subsequent runs.
105
+ """
106
+ with self._get_connection() as conn:
107
+ # Check if database exists and has schema
108
+ cursor = conn.execute(
109
+ "SELECT name FROM sqlite_master WHERE type='table' AND name='sources'"
110
+ )
111
+ if cursor.fetchone() is None:
112
+ # Database is new, create schema
113
+ self._create_schema(conn)
114
+ logger.info(f"Initialized sync state database: {self.db_path}")
115
+ else:
116
+ # Verify schema version
117
+ version = self._get_schema_version(conn)
118
+ if version != self.SCHEMA_VERSION:
119
+ logger.warning(
120
+ f"Schema version mismatch: expected {self.SCHEMA_VERSION}, found {version}"
121
+ )
122
+ # TODO: Implement migration in future ticket
123
+
124
+ def _create_schema(self, conn: sqlite3.Connection):
125
+ """Create database schema with all tables and indexes.
126
+
127
+ Schema Design:
128
+ - sources: Track Git repositories or file sources
129
+ - agent_files: Track individual files and content hashes
130
+ - sync_history: Audit trail of all sync operations
131
+ - schema_metadata: Schema versioning for migrations
132
+ """
133
+ conn.executescript(
134
+ """
135
+ -- Sources table: Track Git repositories or file sources
136
+ CREATE TABLE sources (
137
+ id TEXT PRIMARY KEY, -- Source identifier (e.g., "github-remote", "local-project")
138
+ url TEXT NOT NULL, -- Source URL or file path
139
+ last_sha TEXT, -- Last synced commit SHA (Git sources only)
140
+ last_sync_time TEXT, -- ISO 8601 timestamp of last sync
141
+ etag TEXT, -- HTTP ETag for GitHub raw URLs
142
+ enabled INTEGER DEFAULT 1, -- 0=disabled, 1=enabled
143
+ created_at TEXT DEFAULT CURRENT_TIMESTAMP,
144
+ updated_at TEXT DEFAULT CURRENT_TIMESTAMP
145
+ );
146
+
147
+ -- Agent files table: Track individual files and content hashes
148
+ CREATE TABLE agent_files (
149
+ source_id TEXT NOT NULL, -- FK to sources.id
150
+ file_path TEXT NOT NULL, -- Relative path (e.g., "research.md")
151
+ content_sha TEXT NOT NULL, -- SHA-256 hash of file content
152
+ local_path TEXT, -- Absolute path to cached file
153
+ synced_at TEXT NOT NULL, -- ISO 8601 timestamp when file was synced
154
+ file_size INTEGER, -- File size in bytes
155
+ PRIMARY KEY (source_id, file_path),
156
+ FOREIGN KEY (source_id) REFERENCES sources(id) ON DELETE CASCADE
157
+ );
158
+
159
+ -- Sync history table: Audit trail of all sync operations
160
+ CREATE TABLE sync_history (
161
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
162
+ source_id TEXT NOT NULL, -- FK to sources.id
163
+ sync_time TEXT NOT NULL, -- ISO 8601 timestamp
164
+ status TEXT NOT NULL, -- 'success', 'partial', 'error'
165
+ files_synced INTEGER DEFAULT 0, -- Number of files downloaded
166
+ files_cached INTEGER DEFAULT 0, -- Number of cache hits
167
+ files_failed INTEGER DEFAULT 0, -- Number of failed downloads
168
+ error_message TEXT, -- Error details if status='error'
169
+ duration_ms INTEGER, -- Sync duration in milliseconds
170
+ FOREIGN KEY (source_id) REFERENCES sources(id) ON DELETE CASCADE
171
+ );
172
+
173
+ -- Performance indexes
174
+ CREATE INDEX idx_agent_files_source ON agent_files(source_id);
175
+ CREATE INDEX idx_agent_files_path ON agent_files(file_path);
176
+ CREATE INDEX idx_sync_history_source_time ON sync_history(source_id, sync_time DESC);
177
+ CREATE INDEX idx_sync_history_status ON sync_history(status);
178
+
179
+ -- Metadata table for schema versioning
180
+ CREATE TABLE schema_metadata (
181
+ key TEXT PRIMARY KEY,
182
+ value TEXT NOT NULL
183
+ );
184
+
185
+ INSERT INTO schema_metadata (key, value) VALUES ('version', '1');
186
+ INSERT INTO schema_metadata (key, value) VALUES ('created_at', datetime('now'));
187
+ """
188
+ )
189
+
190
+ def _get_schema_version(self, conn: sqlite3.Connection) -> int:
191
+ """Get current schema version.
192
+
193
+ Args:
194
+ conn: Database connection
195
+
196
+ Returns:
197
+ Schema version number (0 if schema_metadata table doesn't exist)
198
+ """
199
+ try:
200
+ cursor = conn.execute(
201
+ "SELECT value FROM schema_metadata WHERE key = 'version'"
202
+ )
203
+ row = cursor.fetchone()
204
+ return int(row[0]) if row else 0
205
+ except sqlite3.OperationalError:
206
+ return 0
207
+
208
+ # ==============================================================================
209
+ # SOURCE MANAGEMENT
210
+ # ==============================================================================
211
+
212
+ def register_source(self, source_id: str, url: str, enabled: bool = True) -> None:
213
+ """Register or update a sync source.
214
+
215
+ Args:
216
+ source_id: Unique source identifier (e.g., "github-remote")
217
+ url: Source URL or file path
218
+ enabled: Whether source is enabled for sync
219
+
220
+ Example:
221
+ sync_state.register_source(
222
+ source_id="github-remote",
223
+ url="https://raw.githubusercontent.com/bobmatnyc/claude-mpm-agents/main",
224
+ enabled=True
225
+ )
226
+ """
227
+ with self._get_connection() as conn:
228
+ conn.execute(
229
+ """
230
+ INSERT INTO sources (id, url, enabled, updated_at)
231
+ VALUES (?, ?, ?, ?)
232
+ ON CONFLICT(id) DO UPDATE SET
233
+ url = excluded.url,
234
+ enabled = excluded.enabled,
235
+ updated_at = excluded.updated_at
236
+ """,
237
+ (source_id, url, int(enabled), datetime.now(timezone.utc).isoformat()),
238
+ )
239
+ logger.debug(f"Registered source: {source_id} -> {url}")
240
+
241
+ def update_source_sync_metadata(
242
+ self,
243
+ source_id: str,
244
+ last_sha: Optional[str] = None,
245
+ etag: Optional[str] = None,
246
+ ) -> None:
247
+ """Update source sync metadata (commit SHA, ETag).
248
+
249
+ Args:
250
+ source_id: Source identifier
251
+ last_sha: Latest commit SHA (Git sources)
252
+ etag: HTTP ETag (GitHub raw URLs)
253
+
254
+ Example:
255
+ sync_state.update_source_sync_metadata(
256
+ source_id="github-remote",
257
+ last_sha="abc123def456",
258
+ etag='"W/abc123"'
259
+ )
260
+ """
261
+ with self._get_connection() as conn:
262
+ conn.execute(
263
+ """
264
+ UPDATE sources
265
+ SET last_sha = ?, etag = ?, last_sync_time = ?, updated_at = ?
266
+ WHERE id = ?
267
+ """,
268
+ (
269
+ last_sha,
270
+ etag,
271
+ datetime.now(timezone.utc).isoformat(),
272
+ datetime.now(timezone.utc).isoformat(),
273
+ source_id,
274
+ ),
275
+ )
276
+ logger.debug(f"Updated source metadata: {source_id}")
277
+
278
+ def get_source_info(self, source_id: str) -> Optional[Dict[str, Any]]:
279
+ """Get source metadata.
280
+
281
+ Args:
282
+ source_id: Source identifier
283
+
284
+ Returns:
285
+ Source metadata dict or None if not found
286
+
287
+ Example:
288
+ >>> info = sync_state.get_source_info("github-remote")
289
+ >>> print(info["url"])
290
+ https://raw.githubusercontent.com/...
291
+ """
292
+ with self._get_connection() as conn:
293
+ cursor = conn.execute("SELECT * FROM sources WHERE id = ?", (source_id,))
294
+ row = cursor.fetchone()
295
+ return dict(row) if row else None
296
+
297
+ def get_all_sources(self, enabled_only: bool = False) -> List[Dict[str, Any]]:
298
+ """Get all registered sources.
299
+
300
+ Args:
301
+ enabled_only: Only return enabled sources
302
+
303
+ Returns:
304
+ List of source metadata dicts
305
+ """
306
+ with self._get_connection() as conn:
307
+ query = "SELECT * FROM sources"
308
+ if enabled_only:
309
+ query += " WHERE enabled = 1"
310
+ cursor = conn.execute(query)
311
+ return [dict(row) for row in cursor.fetchall()]
312
+
313
+ # ==============================================================================
314
+ # FILE TRACKING
315
+ # ==============================================================================
316
+
317
+ def track_file(
318
+ self,
319
+ source_id: str,
320
+ file_path: str,
321
+ content_sha: str,
322
+ local_path: Optional[str] = None,
323
+ file_size: Optional[int] = None,
324
+ ) -> None:
325
+ """Track agent file with content hash.
326
+
327
+ Args:
328
+ source_id: Source identifier
329
+ file_path: Relative file path (e.g., "research.md")
330
+ content_sha: SHA-256 hash of file content
331
+ local_path: Absolute path to cached file
332
+ file_size: File size in bytes
333
+
334
+ Example:
335
+ sync_state.track_file(
336
+ source_id="github-remote",
337
+ file_path="research.md",
338
+ content_sha="abc123def456...",
339
+ local_path="/home/user/.claude-mpm/cache/research.md",
340
+ file_size=2048
341
+ )
342
+ """
343
+ with self._get_connection() as conn:
344
+ conn.execute(
345
+ """
346
+ INSERT INTO agent_files (source_id, file_path, content_sha, local_path, synced_at, file_size)
347
+ VALUES (?, ?, ?, ?, ?, ?)
348
+ ON CONFLICT(source_id, file_path) DO UPDATE SET
349
+ content_sha = excluded.content_sha,
350
+ local_path = excluded.local_path,
351
+ synced_at = excluded.synced_at,
352
+ file_size = excluded.file_size
353
+ """,
354
+ (
355
+ source_id,
356
+ file_path,
357
+ content_sha,
358
+ local_path,
359
+ datetime.now(timezone.utc).isoformat(),
360
+ file_size,
361
+ ),
362
+ )
363
+ logger.debug(f"Tracked file: {source_id}/{file_path} -> {content_sha[:8]}...")
364
+
365
+ def get_file_hash(self, source_id: str, file_path: str) -> Optional[str]:
366
+ """Get stored content hash for file.
367
+
368
+ Args:
369
+ source_id: Source identifier
370
+ file_path: Relative file path
371
+
372
+ Returns:
373
+ SHA-256 hash or None if not tracked
374
+ """
375
+ with self._get_connection() as conn:
376
+ cursor = conn.execute(
377
+ "SELECT content_sha FROM agent_files WHERE source_id = ? AND file_path = ?",
378
+ (source_id, file_path),
379
+ )
380
+ row = cursor.fetchone()
381
+ return row["content_sha"] if row else None
382
+
383
+ def has_file_changed(
384
+ self, source_id: str, file_path: str, current_sha: str
385
+ ) -> bool:
386
+ """Check if file content has changed.
387
+
388
+ Args:
389
+ source_id: Source identifier
390
+ file_path: Relative file path
391
+ current_sha: Current SHA-256 hash
392
+
393
+ Returns:
394
+ True if changed or not tracked, False if unchanged
395
+
396
+ Example:
397
+ >>> changed = sync_state.has_file_changed(
398
+ ... "github-remote", "research.md", "abc123..."
399
+ ... )
400
+ >>> if changed:
401
+ ... print("File needs update")
402
+ """
403
+ stored_sha = self.get_file_hash(source_id, file_path)
404
+ if stored_sha is None:
405
+ return True # Not tracked = changed
406
+ return stored_sha != current_sha
407
+
408
+ # ==============================================================================
409
+ # SYNC HISTORY
410
+ # ==============================================================================
411
+
412
+ def record_sync_result(
413
+ self,
414
+ source_id: str,
415
+ status: str,
416
+ files_synced: int = 0,
417
+ files_cached: int = 0,
418
+ files_failed: int = 0,
419
+ error_message: Optional[str] = None,
420
+ duration_ms: Optional[int] = None,
421
+ ) -> int:
422
+ """Record sync operation result.
423
+
424
+ Args:
425
+ source_id: Source identifier
426
+ status: 'success', 'partial', or 'error'
427
+ files_synced: Number of files downloaded
428
+ files_cached: Number of cache hits
429
+ files_failed: Number of failed downloads
430
+ error_message: Error details if status='error'
431
+ duration_ms: Sync duration in milliseconds
432
+
433
+ Returns:
434
+ Sync history record ID
435
+
436
+ Example:
437
+ record_id = sync_state.record_sync_result(
438
+ source_id="github-remote",
439
+ status="success",
440
+ files_synced=5,
441
+ files_cached=3,
442
+ duration_ms=1500
443
+ )
444
+ """
445
+ with self._get_connection() as conn:
446
+ cursor = conn.execute(
447
+ """
448
+ INSERT INTO sync_history (
449
+ source_id, sync_time, status, files_synced, files_cached,
450
+ files_failed, error_message, duration_ms
451
+ )
452
+ VALUES (?, ?, ?, ?, ?, ?, ?, ?)
453
+ """,
454
+ (
455
+ source_id,
456
+ datetime.now(timezone.utc).isoformat(),
457
+ status,
458
+ files_synced,
459
+ files_cached,
460
+ files_failed,
461
+ error_message,
462
+ duration_ms,
463
+ ),
464
+ )
465
+ return cursor.lastrowid
466
+
467
+ def get_sync_history(self, source_id: str, limit: int = 10) -> List[Dict[str, Any]]:
468
+ """Get recent sync history for source.
469
+
470
+ Args:
471
+ source_id: Source identifier
472
+ limit: Maximum number of records
473
+
474
+ Returns:
475
+ List of sync history records (most recent first)
476
+
477
+ Example:
478
+ >>> history = sync_state.get_sync_history("github-remote", limit=5)
479
+ >>> for record in history:
480
+ ... print(f"{record['sync_time']}: {record['status']}")
481
+ """
482
+ with self._get_connection() as conn:
483
+ cursor = conn.execute(
484
+ """
485
+ SELECT * FROM sync_history
486
+ WHERE source_id = ?
487
+ ORDER BY sync_time DESC
488
+ LIMIT ?
489
+ """,
490
+ (source_id, limit),
491
+ )
492
+ return [dict(row) for row in cursor.fetchall()]
493
+
494
+ def cleanup_old_history(self, days: int = 30) -> int:
495
+ """Remove sync history older than specified days.
496
+
497
+ Args:
498
+ days: Number of days to retain
499
+
500
+ Returns:
501
+ Number of records deleted
502
+
503
+ Example:
504
+ deleted = sync_state.cleanup_old_history(days=30)
505
+ print(f"Cleaned up {deleted} old sync records")
506
+ """
507
+ cutoff = (datetime.now(timezone.utc) - timedelta(days=days)).isoformat()
508
+
509
+ with self._get_connection() as conn:
510
+ cursor = conn.execute(
511
+ "DELETE FROM sync_history WHERE sync_time < ?", (cutoff,)
512
+ )
513
+ deleted = cursor.rowcount
514
+
515
+ logger.info(f"Cleaned up {deleted} sync history records older than {days} days")
516
+ return deleted