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

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

Potentially problematic release.


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

Files changed (502) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +12 -0
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +721 -911
  5. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  6. claude_mpm/agents/WORKFLOW.md +4 -4
  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 → circuit-breakers.md} +370 -3
  13. claude_mpm/agents/templates/context-management-examples.md +544 -0
  14. claude_mpm/agents/templates/{pm_red_flags.md → pm-red-flags.md} +48 -0
  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 +38 -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 +2 -6
  30. claude_mpm/cli/commands/config.py +7 -4
  31. claude_mpm/cli/commands/configure.py +769 -45
  32. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  33. claude_mpm/cli/commands/configure_navigation.py +63 -46
  34. claude_mpm/cli/commands/debug.py +12 -12
  35. claude_mpm/cli/commands/doctor.py +10 -2
  36. claude_mpm/cli/commands/hook_errors.py +277 -0
  37. claude_mpm/cli/commands/local_deploy.py +1 -4
  38. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  39. claude_mpm/cli/commands/mpm_init/core.py +49 -1
  40. claude_mpm/cli/commands/mpm_init/git_activity.py +10 -10
  41. claude_mpm/cli/commands/mpm_init/prompts.py +6 -6
  42. claude_mpm/cli/commands/postmortem.py +401 -0
  43. claude_mpm/cli/commands/run.py +123 -165
  44. claude_mpm/cli/commands/skill_source.py +694 -0
  45. claude_mpm/cli/commands/skills.py +757 -20
  46. claude_mpm/cli/executor.py +78 -3
  47. claude_mpm/cli/interactive/agent_wizard.py +955 -45
  48. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  49. claude_mpm/cli/parsers/agents_parser.py +256 -4
  50. claude_mpm/cli/parsers/base_parser.py +53 -0
  51. claude_mpm/cli/parsers/config_parser.py +96 -43
  52. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  53. claude_mpm/cli/parsers/skills_parser.py +145 -0
  54. claude_mpm/cli/parsers/source_parser.py +138 -0
  55. claude_mpm/cli/startup.py +538 -106
  56. claude_mpm/cli/startup_display.py +480 -0
  57. claude_mpm/cli/utils.py +1 -1
  58. claude_mpm/cli_module/commands.py +1 -1
  59. claude_mpm/commands/{mpm-auto-configure.md → mpm-agents-auto-configure.md} +9 -0
  60. claude_mpm/commands/mpm-agents-detect.md +9 -0
  61. claude_mpm/commands/{mpm-agents.md → mpm-agents-list.md} +9 -0
  62. claude_mpm/commands/mpm-agents-recommend.md +9 -0
  63. claude_mpm/commands/{mpm-config.md → mpm-config-view.md} +9 -0
  64. claude_mpm/commands/mpm-doctor.md +9 -0
  65. claude_mpm/commands/mpm-help.md +14 -2
  66. claude_mpm/commands/mpm-init.md +27 -2
  67. claude_mpm/commands/mpm-monitor.md +9 -0
  68. claude_mpm/commands/mpm-postmortem.md +123 -0
  69. claude_mpm/commands/{mpm-resume.md → mpm-session-resume.md} +9 -0
  70. claude_mpm/commands/mpm-status.md +9 -0
  71. claude_mpm/commands/{mpm-organize.md → mpm-ticket-organize.md} +9 -0
  72. claude_mpm/commands/mpm-ticket-view.md +552 -0
  73. claude_mpm/commands/mpm-version.md +9 -0
  74. claude_mpm/commands/mpm.md +10 -0
  75. claude_mpm/config/agent_presets.py +488 -0
  76. claude_mpm/config/agent_sources.py +325 -0
  77. claude_mpm/config/skill_presets.py +392 -0
  78. claude_mpm/config/skill_sources.py +590 -0
  79. claude_mpm/constants.py +13 -0
  80. claude_mpm/core/claude_runner.py +5 -34
  81. claude_mpm/core/config.py +16 -0
  82. claude_mpm/core/constants.py +1 -1
  83. claude_mpm/core/framework/__init__.py +3 -16
  84. claude_mpm/core/framework/loaders/file_loader.py +54 -101
  85. claude_mpm/core/framework/loaders/instruction_loader.py +25 -5
  86. claude_mpm/core/hook_error_memory.py +381 -0
  87. claude_mpm/core/hook_manager.py +41 -2
  88. claude_mpm/core/interactive_session.py +91 -10
  89. claude_mpm/core/logger.py +3 -1
  90. claude_mpm/core/oneshot_session.py +71 -8
  91. claude_mpm/core/protocols/__init__.py +23 -0
  92. claude_mpm/core/protocols/runner_protocol.py +103 -0
  93. claude_mpm/core/protocols/session_protocol.py +131 -0
  94. claude_mpm/core/shared/singleton_manager.py +11 -4
  95. claude_mpm/core/system_context.py +38 -0
  96. claude_mpm/dashboard/static/css/activity.css +69 -69
  97. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  98. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  99. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  100. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  101. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  102. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  103. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  104. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  105. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  106. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  107. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  108. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  109. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  110. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  111. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  112. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  113. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  114. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  115. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  116. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  117. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  118. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  119. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  120. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  121. claude_mpm/dashboard/templates/code_simple.html +23 -23
  122. claude_mpm/dashboard/templates/index.html +18 -18
  123. claude_mpm/experimental/cli_enhancements.py +1 -5
  124. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  125. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  126. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  127. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  128. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  129. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  130. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  131. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  132. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  133. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  134. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  135. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  136. claude_mpm/hooks/failure_learning/__init__.py +2 -8
  137. claude_mpm/hooks/failure_learning/failure_detection_hook.py +1 -6
  138. claude_mpm/hooks/failure_learning/fix_detection_hook.py +1 -6
  139. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +1 -6
  140. claude_mpm/hooks/kuzu_response_hook.py +1 -5
  141. claude_mpm/models/git_repository.py +198 -0
  142. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  143. claude_mpm/scripts/start_activity_logging.py +3 -1
  144. claude_mpm/services/agents/agent_builder.py +45 -9
  145. claude_mpm/services/agents/agent_preset_service.py +238 -0
  146. claude_mpm/services/agents/agent_selection_service.py +484 -0
  147. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  148. claude_mpm/services/agents/cache_git_manager.py +621 -0
  149. claude_mpm/services/agents/deployment/agent_deployment.py +126 -2
  150. claude_mpm/services/agents/deployment/agent_discovery_service.py +105 -73
  151. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  152. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +1 -5
  153. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  154. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  155. claude_mpm/services/agents/deployment/agent_template_builder.py +236 -15
  156. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  157. claude_mpm/services/agents/deployment/async_agent_deployment.py +2 -1
  158. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  159. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +115 -15
  160. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  161. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +1 -4
  162. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  163. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  164. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -46
  165. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  166. claude_mpm/services/agents/git_source_manager.py +629 -0
  167. claude_mpm/services/agents/loading/framework_agent_loader.py +9 -12
  168. claude_mpm/services/agents/local_template_manager.py +50 -10
  169. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  170. claude_mpm/services/agents/sources/__init__.py +13 -0
  171. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  172. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  173. claude_mpm/services/agents/startup_sync.py +239 -0
  174. claude_mpm/services/agents/toolchain_detector.py +474 -0
  175. claude_mpm/services/analysis/__init__.py +25 -0
  176. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  177. claude_mpm/services/analysis/postmortem_service.py +765 -0
  178. claude_mpm/services/cli/session_pause_manager.py +1 -1
  179. claude_mpm/services/command_deployment_service.py +200 -6
  180. claude_mpm/services/core/base.py +7 -2
  181. claude_mpm/services/core/interfaces/__init__.py +1 -3
  182. claude_mpm/services/core/interfaces/health.py +1 -4
  183. claude_mpm/services/core/models/__init__.py +2 -11
  184. claude_mpm/services/diagnostics/checks/__init__.py +4 -0
  185. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  186. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  187. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  188. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  189. claude_mpm/services/diagnostics/checks/mcp_services_check.py +7 -15
  190. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  191. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  192. claude_mpm/services/diagnostics/diagnostic_runner.py +9 -0
  193. claude_mpm/services/diagnostics/doctor_reporter.py +40 -10
  194. claude_mpm/services/event_bus/direct_relay.py +3 -3
  195. claude_mpm/services/events/consumers/logging.py +1 -2
  196. claude_mpm/services/git/__init__.py +21 -0
  197. claude_mpm/services/git/git_operations_service.py +494 -0
  198. claude_mpm/services/github/__init__.py +21 -0
  199. claude_mpm/services/github/github_cli_service.py +397 -0
  200. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -5
  201. claude_mpm/services/infrastructure/monitoring/aggregator.py +1 -6
  202. claude_mpm/services/instructions/__init__.py +9 -0
  203. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  204. claude_mpm/services/local_ops/__init__.py +3 -13
  205. claude_mpm/services/local_ops/health_checks/__init__.py +1 -3
  206. claude_mpm/services/local_ops/health_manager.py +1 -4
  207. claude_mpm/services/local_ops/resource_monitor.py +1 -1
  208. claude_mpm/services/mcp_config_manager.py +75 -145
  209. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  210. claude_mpm/services/mcp_gateway/core/process_pool.py +22 -16
  211. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +1 -6
  212. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  213. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  214. claude_mpm/services/mcp_service_verifier.py +6 -3
  215. claude_mpm/services/model/model_router.py +1 -2
  216. claude_mpm/services/monitor/daemon.py +29 -9
  217. claude_mpm/services/monitor/daemon_manager.py +96 -19
  218. claude_mpm/services/monitor/server.py +2 -2
  219. claude_mpm/services/port_manager.py +1 -1
  220. claude_mpm/services/pr/__init__.py +14 -0
  221. claude_mpm/services/pr/pr_template_service.py +329 -0
  222. claude_mpm/services/project/documentation_manager.py +2 -1
  223. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  224. claude_mpm/services/runner_configuration_service.py +16 -3
  225. claude_mpm/services/session_management_service.py +16 -4
  226. claude_mpm/services/skills/__init__.py +18 -0
  227. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  228. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  229. claude_mpm/services/skills_config.py +547 -0
  230. claude_mpm/services/skills_deployer.py +955 -0
  231. claude_mpm/services/socketio/handlers/connection.py +1 -1
  232. claude_mpm/services/socketio/handlers/git.py +1 -1
  233. claude_mpm/services/socketio/server/core.py +1 -4
  234. claude_mpm/services/socketio/server/main.py +1 -3
  235. claude_mpm/services/system_instructions_service.py +1 -3
  236. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  237. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  238. claude_mpm/services/unified/deployment_strategies/vercel.py +1 -5
  239. claude_mpm/services/unified/unified_deployment.py +1 -5
  240. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  241. claude_mpm/services/visualization/__init__.py +1 -5
  242. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  243. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +2 -2
  244. claude_mpm/skills/skills_registry.py +0 -1
  245. claude_mpm/templates/questions/__init__.py +38 -0
  246. claude_mpm/templates/questions/base.py +193 -0
  247. claude_mpm/templates/questions/pr_strategy.py +311 -0
  248. claude_mpm/templates/questions/project_init.py +385 -0
  249. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  250. claude_mpm/tools/__main__.py +8 -8
  251. claude_mpm/utils/agent_dependency_loader.py +77 -10
  252. claude_mpm/utils/agent_filters.py +288 -0
  253. claude_mpm/utils/dependency_cache.py +3 -1
  254. claude_mpm/utils/gitignore.py +241 -0
  255. claude_mpm/utils/migration.py +372 -0
  256. claude_mpm/utils/progress.py +387 -0
  257. claude_mpm/utils/robust_installer.py +2 -4
  258. claude_mpm/utils/structured_questions.py +619 -0
  259. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/METADATA +396 -43
  260. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/RECORD +268 -422
  261. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  262. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  263. claude_mpm/agents/templates/agent-manager.json +0 -273
  264. claude_mpm/agents/templates/agentic-coder-optimizer.json +0 -248
  265. claude_mpm/agents/templates/api_qa.json +0 -183
  266. claude_mpm/agents/templates/clerk-ops.json +0 -235
  267. claude_mpm/agents/templates/code_analyzer.json +0 -101
  268. claude_mpm/agents/templates/content-agent.json +0 -358
  269. claude_mpm/agents/templates/dart_engineer.json +0 -307
  270. claude_mpm/agents/templates/data_engineer.json +0 -225
  271. claude_mpm/agents/templates/documentation.json +0 -238
  272. claude_mpm/agents/templates/engineer.json +0 -210
  273. claude_mpm/agents/templates/gcp_ops_agent.json +0 -253
  274. claude_mpm/agents/templates/golang_engineer.json +0 -270
  275. claude_mpm/agents/templates/imagemagick.json +0 -264
  276. claude_mpm/agents/templates/java_engineer.json +0 -346
  277. claude_mpm/agents/templates/javascript_engineer_agent.json +0 -380
  278. claude_mpm/agents/templates/local_ops_agent.json +0 -1840
  279. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  280. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  281. claude_mpm/agents/templates/memory_manager.json +0 -158
  282. claude_mpm/agents/templates/nextjs_engineer.json +0 -285
  283. claude_mpm/agents/templates/ops.json +0 -185
  284. claude_mpm/agents/templates/php-engineer.json +0 -287
  285. claude_mpm/agents/templates/product_owner.json +0 -338
  286. claude_mpm/agents/templates/project_organizer.json +0 -144
  287. claude_mpm/agents/templates/prompt-engineer.json +0 -737
  288. claude_mpm/agents/templates/python_engineer.json +0 -387
  289. claude_mpm/agents/templates/qa.json +0 -243
  290. claude_mpm/agents/templates/react_engineer.json +0 -239
  291. claude_mpm/agents/templates/refactoring_engineer.json +0 -276
  292. claude_mpm/agents/templates/research.json +0 -188
  293. claude_mpm/agents/templates/ruby-engineer.json +0 -280
  294. claude_mpm/agents/templates/rust_engineer.json +0 -275
  295. claude_mpm/agents/templates/security.json +0 -202
  296. claude_mpm/agents/templates/svelte-engineer.json +0 -225
  297. claude_mpm/agents/templates/tauri_engineer.json +0 -274
  298. claude_mpm/agents/templates/ticketing.json +0 -178
  299. claude_mpm/agents/templates/typescript_engineer.json +0 -285
  300. claude_mpm/agents/templates/vercel_ops_agent.json +0 -412
  301. claude_mpm/agents/templates/version_control.json +0 -159
  302. claude_mpm/agents/templates/web_qa.json +0 -400
  303. claude_mpm/agents/templates/web_ui.json +0 -189
  304. claude_mpm/commands/mpm-tickets.md +0 -151
  305. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  306. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +0 -188
  307. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +0 -156
  308. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +0 -38
  309. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +0 -92
  310. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +0 -248
  311. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  312. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  313. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  314. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  315. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  316. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  317. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  318. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  319. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  320. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  321. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  322. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  323. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  324. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  325. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +0 -1
  326. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  327. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +0 -777
  328. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  329. claude_mpm/dashboard/static/built/components/build-tracker.js +0 -333
  330. claude_mpm/dashboard/static/built/components/code-simple.js +0 -857
  331. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +0 -353
  332. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +0 -235
  333. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +0 -409
  334. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +0 -435
  335. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  336. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  337. claude_mpm/dashboard/static/built/components/connection-debug.js +0 -654
  338. claude_mpm/dashboard/static/built/components/diff-viewer.js +0 -891
  339. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  340. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  341. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  342. claude_mpm/dashboard/static/built/components/file-change-tracker.js +0 -443
  343. claude_mpm/dashboard/static/built/components/file-change-viewer.js +0 -690
  344. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  345. claude_mpm/dashboard/static/built/components/file-viewer.js +0 -2
  346. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  347. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  348. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  349. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  350. claude_mpm/dashboard/static/built/components/nav-bar.js +0 -145
  351. claude_mpm/dashboard/static/built/components/page-structure.js +0 -429
  352. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  353. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  354. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  355. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  356. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  357. claude_mpm/dashboard/static/built/connection-manager.js +0 -536
  358. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  359. claude_mpm/dashboard/static/built/extension-error-handler.js +0 -164
  360. claude_mpm/dashboard/static/built/react/events.js +0 -30
  361. claude_mpm/dashboard/static/built/shared/dom-helpers.js +0 -396
  362. claude_mpm/dashboard/static/built/shared/event-bus.js +0 -330
  363. claude_mpm/dashboard/static/built/shared/event-filter-service.js +0 -540
  364. claude_mpm/dashboard/static/built/shared/logger.js +0 -385
  365. claude_mpm/dashboard/static/built/shared/page-structure.js +0 -249
  366. claude_mpm/dashboard/static/built/shared/tooltip-service.js +0 -253
  367. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  368. claude_mpm/dashboard/static/built/tab-isolation-fix.js +0 -185
  369. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  370. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  371. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  372. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  373. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  374. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  375. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  376. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  377. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  378. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  379. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  380. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  381. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  382. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  383. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  384. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  385. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  386. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  387. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  388. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  389. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  390. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  391. claude_mpm/dashboard/static/events.html +0 -607
  392. claude_mpm/dashboard/static/index.html +0 -635
  393. claude_mpm/dashboard/static/js/shared/dom-helpers.js +0 -396
  394. claude_mpm/dashboard/static/js/shared/event-bus.js +0 -330
  395. claude_mpm/dashboard/static/js/shared/logger.js +0 -385
  396. claude_mpm/dashboard/static/js/shared/tooltip-service.js +0 -253
  397. claude_mpm/dashboard/static/js/stores/dashboard-store.js +0 -562
  398. claude_mpm/dashboard/static/legacy/activity.html +0 -736
  399. claude_mpm/dashboard/static/legacy/agents.html +0 -786
  400. claude_mpm/dashboard/static/legacy/files.html +0 -747
  401. claude_mpm/dashboard/static/legacy/tools.html +0 -831
  402. claude_mpm/dashboard/static/monitors.html +0 -431
  403. claude_mpm/dashboard/static/production/events.html +0 -659
  404. claude_mpm/dashboard/static/production/main.html +0 -698
  405. claude_mpm/dashboard/static/production/monitors.html +0 -483
  406. claude_mpm/dashboard/static/test-archive/dashboard.html +0 -635
  407. claude_mpm/dashboard/static/test-archive/debug-events.html +0 -147
  408. claude_mpm/dashboard/static/test-archive/test-navigation.html +0 -256
  409. claude_mpm/dashboard/static/test-archive/test-react-exports.html +0 -180
  410. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  411. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +0 -79
  412. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +0 -178
  413. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +0 -577
  414. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +0 -467
  415. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +0 -537
  416. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +0 -730
  417. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +0 -112
  418. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +0 -146
  419. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +0 -412
  420. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +0 -81
  421. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +0 -362
  422. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +0 -312
  423. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +0 -152
  424. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +0 -668
  425. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +0 -587
  426. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +0 -438
  427. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +0 -391
  428. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +0 -119
  429. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +0 -148
  430. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +0 -483
  431. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +0 -452
  432. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +0 -449
  433. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +0 -411
  434. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +0 -14
  435. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +0 -58
  436. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +0 -68
  437. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +0 -69
  438. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +0 -131
  439. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +0 -325
  440. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +0 -490
  441. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +0 -425
  442. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +0 -499
  443. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +0 -86
  444. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +0 -43
  445. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +0 -47
  446. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +0 -65
  447. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +0 -30
  448. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +0 -16
  449. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +0 -160
  450. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +0 -412
  451. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +0 -602
  452. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +0 -915
  453. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +0 -916
  454. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +0 -752
  455. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +0 -1237
  456. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +0 -189
  457. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +0 -500
  458. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +0 -464
  459. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +0 -619
  460. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +0 -437
  461. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +0 -231
  462. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +0 -170
  463. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +0 -602
  464. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +0 -821
  465. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +0 -742
  466. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +0 -726
  467. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +0 -764
  468. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +0 -831
  469. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +0 -226
  470. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +0 -901
  471. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +0 -901
  472. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +0 -775
  473. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +0 -937
  474. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +0 -770
  475. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +0 -961
  476. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +0 -119
  477. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +0 -253
  478. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +0 -145
  479. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +0 -543
  480. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +0 -741
  481. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +0 -470
  482. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +0 -458
  483. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +0 -639
  484. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +0 -140
  485. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +0 -572
  486. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +0 -411
  487. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +0 -569
  488. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +0 -695
  489. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +0 -184
  490. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +0 -459
  491. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +0 -479
  492. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +0 -687
  493. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +0 -758
  494. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +0 -868
  495. /claude_mpm/agents/templates/{git_file_tracking.md → git-file-tracking.md} +0 -0
  496. /claude_mpm/agents/templates/{pm_examples.md → pm-examples.md} +0 -0
  497. /claude_mpm/agents/templates/{response_format.md → response-format.md} +0 -0
  498. /claude_mpm/agents/templates/{validation_templates.md → validation-templates.md} +0 -0
  499. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/WHEEL +0 -0
  500. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/entry_points.txt +0 -0
  501. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.dist-info}/licenses/LICENSE +0 -0
  502. {claude_mpm-4.24.0.dist-info → claude_mpm-5.0.9.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