claude-mpm 4.20.3__py3-none-any.whl → 4.25.10__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 (454) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_PM.md +23 -6
  3. claude_mpm/agents/OUTPUT_STYLE.md +3 -48
  4. claude_mpm/agents/PM_INSTRUCTIONS.md +1783 -34
  5. claude_mpm/agents/WORKFLOW.md +75 -2
  6. claude_mpm/agents/base_agent.json +6 -3
  7. claude_mpm/agents/frontmatter_validator.py +1 -1
  8. claude_mpm/agents/templates/api_qa.json +5 -2
  9. claude_mpm/agents/templates/circuit_breakers.md +108 -2
  10. claude_mpm/agents/templates/documentation.json +33 -6
  11. claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
  12. claude_mpm/agents/templates/php-engineer.json +10 -4
  13. claude_mpm/agents/templates/pm_red_flags.md +89 -19
  14. claude_mpm/agents/templates/project_organizer.json +7 -3
  15. claude_mpm/agents/templates/qa.json +2 -1
  16. claude_mpm/agents/templates/react_engineer.json +1 -0
  17. claude_mpm/agents/templates/research.json +82 -12
  18. claude_mpm/agents/templates/security.json +4 -4
  19. claude_mpm/agents/templates/tauri_engineer.json +274 -0
  20. claude_mpm/agents/templates/ticketing.json +10 -6
  21. claude_mpm/agents/templates/version_control.json +4 -2
  22. claude_mpm/agents/templates/web_qa.json +2 -1
  23. claude_mpm/cli/README.md +253 -0
  24. claude_mpm/cli/__init__.py +11 -1
  25. claude_mpm/cli/commands/aggregate.py +1 -1
  26. claude_mpm/cli/commands/analyze.py +3 -3
  27. claude_mpm/cli/commands/cleanup.py +1 -1
  28. claude_mpm/cli/commands/configure_agent_display.py +4 -4
  29. claude_mpm/cli/commands/debug.py +12 -12
  30. claude_mpm/cli/commands/hook_errors.py +277 -0
  31. claude_mpm/cli/commands/mcp_install_commands.py +1 -1
  32. claude_mpm/cli/commands/mcp_install_commands.py.backup +284 -0
  33. claude_mpm/cli/commands/mpm_init/README.md +365 -0
  34. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  35. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  36. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  37. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  38. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  39. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  40. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  41. claude_mpm/cli/commands/mpm_init_handler.py +67 -1
  42. claude_mpm/cli/commands/run.py +124 -128
  43. claude_mpm/cli/commands/skills.py +522 -34
  44. claude_mpm/cli/executor.py +56 -0
  45. claude_mpm/cli/interactive/agent_wizard.py +5 -5
  46. claude_mpm/cli/parsers/base_parser.py +28 -0
  47. claude_mpm/cli/parsers/mpm_init_parser.py +42 -0
  48. claude_mpm/cli/parsers/skills_parser.py +138 -0
  49. claude_mpm/cli/startup.py +111 -8
  50. claude_mpm/cli/startup_display.py +480 -0
  51. claude_mpm/cli/utils.py +1 -1
  52. claude_mpm/cli_module/commands.py +1 -1
  53. claude_mpm/cli_module/refactoring_guide.md +253 -0
  54. claude_mpm/commands/mpm-help.md +3 -0
  55. claude_mpm/commands/mpm-init.md +19 -3
  56. claude_mpm/commands/mpm-resume.md +372 -0
  57. claude_mpm/commands/mpm-tickets.md +56 -7
  58. claude_mpm/commands/mpm.md +1 -0
  59. claude_mpm/config/agent_capabilities.yaml +658 -0
  60. claude_mpm/config/async_logging_config.yaml +145 -0
  61. claude_mpm/constants.py +12 -0
  62. claude_mpm/core/.claude-mpm/logs/hooks_20250730.log +34 -0
  63. claude_mpm/core/api_validator.py +1 -1
  64. claude_mpm/core/claude_runner.py +14 -1
  65. claude_mpm/core/config.py +8 -0
  66. claude_mpm/core/constants.py +1 -1
  67. claude_mpm/core/framework/processors/metadata_processor.py +1 -1
  68. claude_mpm/core/hook_error_memory.py +381 -0
  69. claude_mpm/core/hook_manager.py +41 -2
  70. claude_mpm/core/interactive_session.py +48 -3
  71. claude_mpm/core/interfaces.py +56 -1
  72. claude_mpm/core/logger.py +3 -1
  73. claude_mpm/core/oneshot_session.py +39 -0
  74. claude_mpm/d2/.gitignore +22 -0
  75. claude_mpm/d2/ARCHITECTURE_COMPARISON.md +273 -0
  76. claude_mpm/d2/FLASK_INTEGRATION.md +156 -0
  77. claude_mpm/d2/IMPLEMENTATION_SUMMARY.md +452 -0
  78. claude_mpm/d2/QUICKSTART.md +186 -0
  79. claude_mpm/d2/README.md +232 -0
  80. claude_mpm/d2/STORE_FIX_SUMMARY.md +167 -0
  81. claude_mpm/d2/SVELTE5_STORES_GUIDE.md +180 -0
  82. claude_mpm/d2/TESTING.md +288 -0
  83. claude_mpm/d2/index.html +118 -0
  84. claude_mpm/d2/package.json +19 -0
  85. claude_mpm/d2/src/App.svelte +110 -0
  86. claude_mpm/d2/src/components/Header.svelte +153 -0
  87. claude_mpm/d2/src/components/MainContent.svelte +74 -0
  88. claude_mpm/d2/src/components/Sidebar.svelte +85 -0
  89. claude_mpm/d2/src/components/tabs/EventsTab.svelte +326 -0
  90. claude_mpm/d2/src/lib/socketio.js +144 -0
  91. claude_mpm/d2/src/main.js +7 -0
  92. claude_mpm/d2/src/stores/events.js +114 -0
  93. claude_mpm/d2/src/stores/socket.js +108 -0
  94. claude_mpm/d2/src/stores/theme.js +65 -0
  95. claude_mpm/d2/svelte.config.js +12 -0
  96. claude_mpm/d2/vite.config.js +15 -0
  97. claude_mpm/dashboard/.claude-mpm/memories/README.md +36 -0
  98. claude_mpm/dashboard/BUILD_NUMBER +1 -0
  99. claude_mpm/dashboard/README.md +121 -0
  100. claude_mpm/dashboard/VERSION +1 -0
  101. claude_mpm/dashboard/react/components/DataInspector/DataInspector.tsx +273 -0
  102. claude_mpm/dashboard/react/components/ErrorBoundary.tsx +75 -0
  103. claude_mpm/dashboard/react/components/EventViewer/EventViewer.tsx +141 -0
  104. claude_mpm/dashboard/react/components/shared/ConnectionStatus.tsx +36 -0
  105. claude_mpm/dashboard/react/components/shared/FilterBar.tsx +89 -0
  106. claude_mpm/dashboard/react/contexts/DashboardContext.tsx +215 -0
  107. claude_mpm/dashboard/react/entries/events.tsx +165 -0
  108. claude_mpm/dashboard/react/hooks/useEvents.ts +191 -0
  109. claude_mpm/dashboard/react/hooks/useSocket.ts +225 -0
  110. claude_mpm/dashboard/static/built/REFACTORING_SUMMARY.md +170 -0
  111. claude_mpm/dashboard/static/built/components/activity-tree.js.map +1 -0
  112. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +101 -101
  113. claude_mpm/dashboard/static/built/components/agent-inference.js.map +1 -0
  114. claude_mpm/dashboard/static/built/components/build-tracker.js +59 -59
  115. claude_mpm/dashboard/static/built/components/code-simple.js +107 -107
  116. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +29 -29
  117. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +24 -24
  118. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +27 -27
  119. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +25 -25
  120. claude_mpm/dashboard/static/built/components/code-tree.js.map +1 -0
  121. claude_mpm/dashboard/static/built/components/code-viewer.js.map +1 -0
  122. claude_mpm/dashboard/static/built/components/connection-debug.js +101 -101
  123. claude_mpm/dashboard/static/built/components/diff-viewer.js +113 -113
  124. claude_mpm/dashboard/static/built/components/event-processor.js.map +1 -0
  125. claude_mpm/dashboard/static/built/components/event-viewer.js.map +1 -0
  126. claude_mpm/dashboard/static/built/components/export-manager.js.map +1 -0
  127. claude_mpm/dashboard/static/built/components/file-change-tracker.js +57 -57
  128. claude_mpm/dashboard/static/built/components/file-change-viewer.js +74 -74
  129. claude_mpm/dashboard/static/built/components/file-tool-tracker.js.map +1 -0
  130. claude_mpm/dashboard/static/built/components/file-viewer.js.map +1 -0
  131. claude_mpm/dashboard/static/built/components/hud-library-loader.js.map +1 -0
  132. claude_mpm/dashboard/static/built/components/hud-manager.js.map +1 -0
  133. claude_mpm/dashboard/static/built/components/hud-visualizer.js.map +1 -0
  134. claude_mpm/dashboard/static/built/components/module-viewer.js.map +1 -0
  135. claude_mpm/dashboard/static/built/components/session-manager.js.map +1 -0
  136. claude_mpm/dashboard/static/built/components/socket-manager.js.map +1 -0
  137. claude_mpm/dashboard/static/built/components/ui-state-manager.js.map +1 -0
  138. claude_mpm/dashboard/static/built/components/unified-data-viewer.js.map +1 -0
  139. claude_mpm/dashboard/static/built/components/working-directory.js.map +1 -0
  140. claude_mpm/dashboard/static/built/connection-manager.js +76 -76
  141. claude_mpm/dashboard/static/built/dashboard.js.map +1 -0
  142. claude_mpm/dashboard/static/built/extension-error-handler.js +22 -22
  143. claude_mpm/dashboard/static/built/react/events.js.map +1 -0
  144. claude_mpm/dashboard/static/built/shared/dom-helpers.js +9 -9
  145. claude_mpm/dashboard/static/built/shared/event-bus.js +5 -5
  146. claude_mpm/dashboard/static/built/shared/logger.js +16 -16
  147. claude_mpm/dashboard/static/built/shared/tooltip-service.js +6 -6
  148. claude_mpm/dashboard/static/built/socket-client.js.map +1 -0
  149. claude_mpm/dashboard/static/css/activity.css +69 -69
  150. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  151. claude_mpm/dashboard/static/css/dashboard.css +15 -15
  152. claude_mpm/dashboard/static/index.html +22 -22
  153. claude_mpm/dashboard/static/js/REFACTORING_SUMMARY.md +170 -0
  154. claude_mpm/dashboard/static/js/components/activity-tree.js +178 -178
  155. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +101 -101
  156. claude_mpm/dashboard/static/js/components/agent-inference.js +31 -31
  157. claude_mpm/dashboard/static/js/components/build-tracker.js +59 -59
  158. claude_mpm/dashboard/static/js/components/code-simple.js +107 -107
  159. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  160. claude_mpm/dashboard/static/js/components/diff-viewer.js +113 -113
  161. claude_mpm/dashboard/static/js/components/event-viewer.js +12 -12
  162. claude_mpm/dashboard/static/js/components/file-change-tracker.js +57 -57
  163. claude_mpm/dashboard/static/js/components/file-change-viewer.js +74 -74
  164. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +6 -6
  165. claude_mpm/dashboard/static/js/components/file-viewer.js +42 -42
  166. claude_mpm/dashboard/static/js/components/module-viewer.js +27 -27
  167. claude_mpm/dashboard/static/js/components/session-manager.js +14 -14
  168. claude_mpm/dashboard/static/js/components/socket-manager.js +1 -1
  169. claude_mpm/dashboard/static/js/components/ui-state-manager.js +14 -14
  170. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +110 -110
  171. claude_mpm/dashboard/static/js/components/working-directory.js +8 -8
  172. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  173. claude_mpm/dashboard/static/js/dashboard.js +76 -58
  174. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  175. claude_mpm/dashboard/static/js/shared/dom-helpers.js +9 -9
  176. claude_mpm/dashboard/static/js/shared/event-bus.js +5 -5
  177. claude_mpm/dashboard/static/js/shared/logger.js +16 -16
  178. claude_mpm/dashboard/static/js/shared/tooltip-service.js +6 -6
  179. claude_mpm/dashboard/static/js/socket-client.js +138 -121
  180. claude_mpm/dashboard/static/navigation-test-results.md +118 -0
  181. claude_mpm/dashboard/static/production/main.html +21 -21
  182. claude_mpm/dashboard/static/test-archive/dashboard.html +22 -22
  183. claude_mpm/dashboard/templates/.claude-mpm/memories/README.md +36 -0
  184. claude_mpm/dashboard/templates/.claude-mpm/memories/engineer_agent.md +39 -0
  185. claude_mpm/dashboard/templates/.claude-mpm/memories/version_control_agent.md +38 -0
  186. claude_mpm/dashboard/templates/code_simple.html +23 -23
  187. claude_mpm/dashboard/templates/index.html +18 -18
  188. claude_mpm/hooks/README.md +143 -0
  189. claude_mpm/hooks/claude_hooks/event_handlers.py +3 -1
  190. claude_mpm/hooks/claude_hooks/hook_handler.py +24 -7
  191. claude_mpm/hooks/claude_hooks/installer.py +45 -0
  192. claude_mpm/hooks/templates/README.md +180 -0
  193. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  194. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  195. claude_mpm/hooks/templates/settings.json.example +147 -0
  196. claude_mpm/schemas/agent_schema.json +596 -0
  197. claude_mpm/schemas/frontmatter_schema.json +165 -0
  198. claude_mpm/scripts/claude-hook-handler.sh +3 -3
  199. claude_mpm/scripts/start_activity_logging.py +3 -1
  200. claude_mpm/services/agents/deployment/agent_format_converter.py +1 -1
  201. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  202. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  203. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  204. claude_mpm/services/agents/loading/framework_agent_loader.py +8 -8
  205. claude_mpm/services/agents/local_template_manager.py +3 -1
  206. claude_mpm/services/cli/session_pause_manager.py +504 -0
  207. claude_mpm/services/cli/session_resume_helper.py +36 -16
  208. claude_mpm/services/cli/unified_dashboard_manager.py +1 -1
  209. claude_mpm/services/core/base.py +26 -11
  210. claude_mpm/services/core/interfaces.py +56 -1
  211. claude_mpm/services/core/models/agent_config.py +3 -0
  212. claude_mpm/services/core/models/process.py +4 -0
  213. claude_mpm/services/diagnostics/checks/agent_check.py +0 -2
  214. claude_mpm/services/diagnostics/checks/instructions_check.py +1 -2
  215. claude_mpm/services/diagnostics/checks/mcp_check.py +0 -1
  216. claude_mpm/services/diagnostics/checks/monitor_check.py +0 -1
  217. claude_mpm/services/diagnostics/doctor_reporter.py +6 -4
  218. claude_mpm/services/diagnostics/models.py +21 -0
  219. claude_mpm/services/event_bus/README.md +244 -0
  220. claude_mpm/services/event_bus/direct_relay.py +3 -3
  221. claude_mpm/services/event_bus/event_bus.py +36 -3
  222. claude_mpm/services/event_bus/relay.py +23 -7
  223. claude_mpm/services/events/README.md +303 -0
  224. claude_mpm/services/events/consumers/logging.py +1 -2
  225. claude_mpm/services/framework_claude_md_generator/README.md +119 -0
  226. claude_mpm/services/infrastructure/monitoring/resources.py +1 -1
  227. claude_mpm/services/local_ops/__init__.py +2 -0
  228. claude_mpm/services/local_ops/process_manager.py +1 -1
  229. claude_mpm/services/local_ops/resource_monitor.py +2 -2
  230. claude_mpm/services/mcp_gateway/README.md +185 -0
  231. claude_mpm/services/mcp_gateway/auto_configure.py +31 -25
  232. claude_mpm/services/mcp_gateway/config/configuration.py +1 -1
  233. claude_mpm/services/mcp_gateway/core/process_pool.py +19 -10
  234. claude_mpm/services/mcp_gateway/server/stdio_server.py +0 -2
  235. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +1 -1
  236. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +26 -21
  237. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +6 -2
  238. claude_mpm/services/memory/failure_tracker.py +19 -4
  239. claude_mpm/services/memory/optimizer.py +1 -1
  240. claude_mpm/services/model/model_router.py +8 -9
  241. claude_mpm/services/monitor/daemon.py +1 -1
  242. claude_mpm/services/monitor/server.py +2 -2
  243. claude_mpm/services/native_agent_converter.py +356 -0
  244. claude_mpm/services/port_manager.py +1 -1
  245. claude_mpm/services/project/documentation_manager.py +2 -1
  246. claude_mpm/services/project/toolchain_analyzer.py +3 -1
  247. claude_mpm/services/runner_configuration_service.py +1 -0
  248. claude_mpm/services/self_upgrade_service.py +165 -7
  249. claude_mpm/services/skills_config.py +547 -0
  250. claude_mpm/services/skills_deployer.py +955 -0
  251. claude_mpm/services/socketio/handlers/connection.py +1 -1
  252. claude_mpm/services/socketio/handlers/connection.py.backup +217 -0
  253. claude_mpm/services/socketio/handlers/git.py +2 -2
  254. claude_mpm/services/socketio/handlers/hook.py.backup +154 -0
  255. claude_mpm/services/static/.gitkeep +2 -0
  256. claude_mpm/services/system_instructions_service.py +1 -3
  257. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +0 -3
  258. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +0 -1
  259. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +1 -1
  260. claude_mpm/services/version_control/VERSION +1 -0
  261. claude_mpm/services/version_control/conflict_resolution.py +6 -4
  262. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  263. claude_mpm/skills/__init__.py +3 -3
  264. claude_mpm/skills/agent_skills_injector.py +42 -49
  265. claude_mpm/skills/bundled/.gitkeep +2 -0
  266. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +4 -0
  267. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +108 -114
  268. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  269. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  270. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  271. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  272. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  273. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +46 -41
  274. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  275. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  276. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +36 -73
  277. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  278. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  279. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +100 -125
  280. claude_mpm/skills/bundled/debugging/root-cause-tracing/find-polluter.sh +63 -0
  281. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  282. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  283. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  284. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  285. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +28 -72
  286. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +11 -0
  287. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  288. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  289. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +272 -0
  290. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  291. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  292. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  293. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  294. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  295. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  296. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  297. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  298. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  299. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  300. claude_mpm/skills/bundled/main/artifacts-builder/LICENSE.txt +202 -0
  301. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +13 -1
  302. claude_mpm/skills/bundled/main/artifacts-builder/scripts/bundle-artifact.sh +54 -0
  303. claude_mpm/skills/bundled/main/artifacts-builder/scripts/init-artifact.sh +322 -0
  304. claude_mpm/skills/bundled/main/artifacts-builder/scripts/shadcn-components.tar.gz +0 -0
  305. claude_mpm/skills/bundled/main/internal-comms/LICENSE.txt +202 -0
  306. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +11 -0
  307. claude_mpm/skills/bundled/main/mcp-builder/LICENSE.txt +202 -0
  308. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +109 -277
  309. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  310. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  311. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +17 -10
  312. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +92 -39
  313. claude_mpm/skills/bundled/main/mcp-builder/scripts/example_evaluation.xml +22 -0
  314. claude_mpm/skills/bundled/main/mcp-builder/scripts/requirements.txt +2 -0
  315. claude_mpm/skills/bundled/main/skill-creator/LICENSE.txt +202 -0
  316. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +135 -155
  317. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  318. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  319. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  320. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  321. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  322. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +13 -12
  323. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +5 -3
  324. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +19 -12
  325. claude_mpm/skills/bundled/performance-profiling.md +6 -0
  326. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  327. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  328. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  329. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  330. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  331. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  332. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  333. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  334. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  335. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  336. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  337. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  338. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  339. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  340. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  341. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  342. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  343. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  344. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  345. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  346. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  347. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  348. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  349. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  350. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  351. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  352. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +21 -25
  353. claude_mpm/skills/bundled/testing/condition-based-waiting/example.ts +158 -0
  354. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  355. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  356. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  357. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  358. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  359. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  360. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +86 -250
  361. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  362. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  363. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  364. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  365. claude_mpm/skills/bundled/testing/webapp-testing/LICENSE.txt +202 -0
  366. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +145 -57
  367. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  368. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +6 -6
  369. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +13 -9
  370. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +8 -8
  371. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  372. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  373. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +37 -15
  374. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  375. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  376. claude_mpm/skills/skills_registry.py +44 -48
  377. claude_mpm/skills/skills_service.py +117 -108
  378. claude_mpm/templates/questions/EXAMPLES.md +501 -0
  379. claude_mpm/templates/questions/__init__.py +43 -0
  380. claude_mpm/templates/questions/base.py +193 -0
  381. claude_mpm/templates/questions/pr_strategy.py +314 -0
  382. claude_mpm/templates/questions/project_init.py +388 -0
  383. claude_mpm/templates/questions/ticket_mgmt.py +397 -0
  384. claude_mpm/tools/README_SOCKETIO_DEBUG.md +224 -0
  385. claude_mpm/tools/__main__.py +8 -8
  386. claude_mpm/tools/code_tree_analyzer/README.md +64 -0
  387. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  388. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  389. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  390. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  391. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  392. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  393. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  394. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  395. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  396. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  397. claude_mpm/utils/agent_dependency_loader.py +3 -3
  398. claude_mpm/utils/dependency_cache.py +3 -1
  399. claude_mpm/utils/gitignore.py +241 -0
  400. claude_mpm/utils/log_cleanup.py +3 -3
  401. claude_mpm/utils/robust_installer.py +3 -5
  402. claude_mpm/utils/structured_questions.py +619 -0
  403. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/METADATA +218 -31
  404. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/RECORD +409 -246
  405. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  406. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  407. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  408. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +0 -400
  409. claude_mpm/cli/commands/mpm_init.py +0 -2093
  410. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  411. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +0 -61
  412. claude_mpm/dashboard/static/archive/test_activity_connection.html +0 -179
  413. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +0 -68
  414. claude_mpm/dashboard/static/archive/test_dashboard.html +0 -409
  415. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +0 -519
  416. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +0 -181
  417. claude_mpm/dashboard/static/archive/test_file_data.html +0 -315
  418. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +0 -243
  419. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +0 -234
  420. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +0 -117
  421. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +0 -115
  422. claude_mpm/dashboard/static/archive/test_file_viewer.html +0 -224
  423. claude_mpm/dashboard/static/archive/test_final_activity.html +0 -220
  424. claude_mpm/dashboard/static/archive/test_tab_fix.html +0 -139
  425. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +0 -1
  426. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  427. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  428. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  429. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  430. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  431. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  432. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  433. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  434. claude_mpm/dashboard/static/dist/components/file-viewer.js +0 -2
  435. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  436. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  437. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  438. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  439. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  440. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  441. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  442. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  443. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  444. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  445. claude_mpm/dashboard/static/dist/react/events.js +0 -30
  446. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  447. claude_mpm/dashboard/static/test-archive/test_debug.html +0 -25
  448. claude_mpm/skills/bundled/debugging/verification-before-completion/references/common-failures.md +0 -213
  449. claude_mpm/tools/code_tree_analyzer.py +0 -1825
  450. /claude_mpm/skills/bundled/collaboration/requesting-code-review/{code-reviewer.md → references/code-reviewer-template.md} +0 -0
  451. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/WHEEL +0 -0
  452. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/entry_points.txt +0 -0
  453. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/licenses/LICENSE +0 -0
  454. {claude_mpm-4.20.3.dist-info → claude_mpm-4.25.10.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,504 @@
1
+ """Session Pause Manager Service.
2
+
3
+ WHY: This service creates session pause documents that capture complete conversation
4
+ context, git state, todos, and working directory for seamless resume.
5
+
6
+ DESIGN DECISIONS:
7
+ - Three format output (JSON, YAML, Markdown) for different use cases
8
+ - Atomic file operations using StateStorage
9
+ - Git integration for automatic commits
10
+ - Compatible with SessionResumeHelper for resume workflow
11
+ - LATEST-SESSION.txt pointer for quick access
12
+ """
13
+
14
+ import subprocess
15
+ from datetime import datetime, timezone
16
+ from pathlib import Path
17
+ from typing import Any, Dict, Optional
18
+
19
+ import yaml
20
+
21
+ from claude_mpm.core.logger import get_logger
22
+ from claude_mpm.storage.state_storage import StateStorage
23
+
24
+ logger = get_logger(__name__)
25
+
26
+
27
+ class SessionPauseManager:
28
+ """Manages creating pause sessions and capturing state."""
29
+
30
+ def __init__(self, project_path: Optional[Path] = None):
31
+ """Initialize session pause manager.
32
+
33
+ Args:
34
+ project_path: Project root path (default: current directory)
35
+ """
36
+ self.project_path = (project_path or Path.cwd()).resolve()
37
+ # Use flattened structure: .claude-mpm/sessions/ instead of sessions/pause/
38
+ self.pause_dir = self.project_path / ".claude-mpm" / "sessions"
39
+ self.pause_dir.mkdir(parents=True, exist_ok=True)
40
+ self.storage = StateStorage(self.pause_dir)
41
+
42
+ def create_pause_session(
43
+ self,
44
+ message: Optional[str] = None,
45
+ skip_commit: bool = False,
46
+ export_path: Optional[str] = None,
47
+ ) -> str:
48
+ """Create a pause session with captured state.
49
+
50
+ Args:
51
+ message: Optional pause reason/context message
52
+ skip_commit: Skip git commit of session state
53
+ export_path: Optional export location for session file
54
+
55
+ Returns:
56
+ Session ID
57
+
58
+ Raises:
59
+ Exception: If session creation fails
60
+ """
61
+ logger.info("Creating pause session")
62
+
63
+ # Generate session ID
64
+ session_id = f"session-{datetime.now(timezone.utc).strftime('%Y%m%d-%H%M%S')}"
65
+
66
+ # Capture state
67
+ state = self._capture_state(session_id, message)
68
+
69
+ # Save JSON format
70
+ json_path = self.pause_dir / f"{session_id}.json"
71
+ if not self.storage.write_json(state, json_path, atomic=True):
72
+ raise RuntimeError(f"Failed to write JSON to {json_path}")
73
+ logger.debug(f"Saved JSON: {json_path}")
74
+
75
+ # Save YAML format
76
+ yaml_path = self.pause_dir / f"{session_id}.yaml"
77
+ self._save_yaml(state, yaml_path)
78
+ logger.debug(f"Saved YAML: {yaml_path}")
79
+
80
+ # Save Markdown format
81
+ md_path = self.pause_dir / f"{session_id}.md"
82
+ md_content = self._generate_markdown(state)
83
+ md_path.write_text(md_content)
84
+ logger.debug(f"Saved Markdown: {md_path}")
85
+
86
+ # Update LATEST-SESSION.txt pointer
87
+ self._update_latest_pointer(session_id)
88
+
89
+ # Optional export
90
+ if export_path:
91
+ export_file = Path(export_path).resolve()
92
+ if not self.storage.write_json(state, export_file, atomic=True):
93
+ logger.warning(f"Failed to export to {export_file}")
94
+ else:
95
+ logger.info(f"Exported session to {export_file}")
96
+
97
+ # Optional git commit
98
+ if not skip_commit and self._is_git_repo():
99
+ self._commit_pause_session(session_id, message)
100
+
101
+ logger.info(f"Pause session created: {session_id}")
102
+ return session_id
103
+
104
+ def _capture_state(self, session_id: str, message: Optional[str]) -> Dict[str, Any]:
105
+ """Capture current session state.
106
+
107
+ Args:
108
+ session_id: Session identifier
109
+ message: Optional context message
110
+
111
+ Returns:
112
+ Complete state dictionary
113
+ """
114
+ # Get git context
115
+ git_context = self._get_git_context()
116
+
117
+ # Build state dictionary
118
+ return {
119
+ "session_id": session_id,
120
+ "paused_at": datetime.now(timezone.utc).isoformat(),
121
+ "duration_hours": 0, # Can be calculated if session start time known
122
+ "context_usage": {
123
+ "tokens_used": 0, # Would need Claude API integration
124
+ "tokens_total": 200000,
125
+ "percentage": 0,
126
+ },
127
+ "conversation": {
128
+ "primary_task": "Manual pause - see message below",
129
+ "current_phase": "In progress",
130
+ "summary": message or "No summary provided",
131
+ "accomplishments": [],
132
+ "next_steps": [],
133
+ },
134
+ "git_context": git_context,
135
+ "active_context": {
136
+ "working_directory": str(self.project_path),
137
+ },
138
+ "important_reminders": [],
139
+ "resume_instructions": {
140
+ "quick_start": [
141
+ f"Read {session_id}.md for full context",
142
+ "Run: git status to check current state",
143
+ "Run: cat .claude-mpm/sessions/LATEST-SESSION.txt",
144
+ ],
145
+ "files_to_review": [],
146
+ "validation_commands": {
147
+ "check_git": "git status && git log -1 --stat",
148
+ "check_session": f"cat .claude-mpm/sessions/{session_id}.md",
149
+ },
150
+ },
151
+ "open_questions": [],
152
+ "performance_metrics": {},
153
+ "todos": {"active": [], "completed": []},
154
+ "version": self._get_project_version(),
155
+ "build": "current",
156
+ "project_path": str(self.project_path),
157
+ }
158
+
159
+ def _get_git_context(self) -> Dict[str, Any]:
160
+ """Get git repository context.
161
+
162
+ Returns:
163
+ Git context dictionary
164
+ """
165
+ if not self._is_git_repo():
166
+ return {
167
+ "is_git_repo": False,
168
+ "branch": None,
169
+ "recent_commits": [],
170
+ "status": {
171
+ "clean": True,
172
+ "modified_files": [],
173
+ "untracked_files": [],
174
+ },
175
+ }
176
+
177
+ try:
178
+ # Get current branch
179
+ branch = subprocess.check_output(
180
+ ["git", "branch", "--show-current"],
181
+ cwd=self.project_path,
182
+ text=True,
183
+ stderr=subprocess.DEVNULL,
184
+ ).strip()
185
+
186
+ # Get recent commits (last 5)
187
+ commit_log = subprocess.check_output(
188
+ ["git", "log", "-5", "--pretty=format:%h|%an|%ai|%s"],
189
+ cwd=self.project_path,
190
+ text=True,
191
+ stderr=subprocess.DEVNULL,
192
+ ).strip()
193
+
194
+ recent_commits = []
195
+ for line in commit_log.split("\n"):
196
+ if line:
197
+ parts = line.split("|", 3)
198
+ if len(parts) == 4:
199
+ recent_commits.append(
200
+ {
201
+ "sha": parts[0],
202
+ "author": parts[1],
203
+ "timestamp": parts[2],
204
+ "message": parts[3],
205
+ }
206
+ )
207
+
208
+ # Get status
209
+ status_output = subprocess.check_output(
210
+ ["git", "status", "--porcelain"],
211
+ cwd=self.project_path,
212
+ text=True,
213
+ stderr=subprocess.DEVNULL,
214
+ ).strip()
215
+
216
+ modified_files = []
217
+ untracked_files = []
218
+ if status_output:
219
+ for line in status_output.split("\n"):
220
+ if line.startswith("??"):
221
+ untracked_files.append(line[3:])
222
+ elif line:
223
+ modified_files.append(line[3:])
224
+
225
+ return {
226
+ "is_git_repo": True,
227
+ "branch": branch,
228
+ "recent_commits": recent_commits,
229
+ "status": {
230
+ "clean": len(modified_files) == 0 and len(untracked_files) == 0,
231
+ "modified_files": modified_files,
232
+ "untracked_files": untracked_files,
233
+ },
234
+ }
235
+
236
+ except subprocess.CalledProcessError as e:
237
+ logger.warning(f"Git command failed: {e}")
238
+ return {
239
+ "is_git_repo": True,
240
+ "branch": "unknown",
241
+ "recent_commits": [],
242
+ "status": {"clean": True, "modified_files": [], "untracked_files": []},
243
+ }
244
+
245
+ def _is_git_repo(self) -> bool:
246
+ """Check if directory is a git repository.
247
+
248
+ Returns:
249
+ True if git repository exists
250
+ """
251
+ return (self.project_path / ".git").exists()
252
+
253
+ def _save_yaml(self, state: Dict[str, Any], yaml_path: Path) -> None:
254
+ """Save state as YAML format.
255
+
256
+ Args:
257
+ state: State dictionary
258
+ yaml_path: Target YAML file path
259
+ """
260
+ try:
261
+ with yaml_path.open("w") as f:
262
+ yaml.dump(
263
+ state,
264
+ f,
265
+ default_flow_style=False,
266
+ allow_unicode=True,
267
+ sort_keys=False,
268
+ )
269
+ except Exception as e:
270
+ logger.error(f"Failed to write YAML to {yaml_path}: {e}")
271
+ raise
272
+
273
+ def _generate_markdown(self, state: Dict[str, Any]) -> str:
274
+ """Generate human-readable markdown format.
275
+
276
+ Args:
277
+ state: State dictionary
278
+
279
+ Returns:
280
+ Markdown formatted string
281
+ """
282
+ session_id = state["session_id"]
283
+ paused_at = state["paused_at"]
284
+ conversation = state["conversation"]
285
+ git_context = state["git_context"]
286
+ active_context = state["active_context"]
287
+
288
+ lines = [
289
+ "# Claude MPM Session Pause Document",
290
+ "",
291
+ "## Session Metadata",
292
+ "",
293
+ f"**Session ID**: `{session_id}`",
294
+ f"**Paused At**: {paused_at}",
295
+ f"**Project**: `{state['project_path']}`",
296
+ f"**Version**: {state.get('version', 'unknown')}",
297
+ "",
298
+ "## What You Were Working On",
299
+ "",
300
+ f"**Primary Task**: {conversation['primary_task']}",
301
+ f"**Current Phase**: {conversation['current_phase']}",
302
+ "",
303
+ "**Summary**:",
304
+ f"{conversation['summary']}",
305
+ "",
306
+ ]
307
+
308
+ # Accomplishments
309
+ if conversation.get("accomplishments"):
310
+ lines.append("## Accomplishments This Session")
311
+ lines.append("")
312
+ for item in conversation["accomplishments"]:
313
+ lines.append(f"- {item}")
314
+ lines.append("")
315
+
316
+ # Next steps
317
+ if conversation.get("next_steps"):
318
+ lines.append("## Next Steps (Priority Order)")
319
+ lines.append("")
320
+ for i, step in enumerate(conversation["next_steps"], 1):
321
+ if isinstance(step, dict):
322
+ lines.append(
323
+ f"{i}. **{step.get('task', 'Unknown task')}** (Priority: {step.get('priority', '?')})"
324
+ )
325
+ if step.get("estimated_hours"):
326
+ lines.append(f" - Est. time: {step['estimated_hours']}")
327
+ if step.get("status"):
328
+ lines.append(f" - Status: {step['status']}")
329
+ if step.get("notes"):
330
+ lines.append(f" - Notes: {step['notes']}")
331
+ else:
332
+ lines.append(f"{i}. {step}")
333
+ lines.append("")
334
+
335
+ # Active context
336
+ lines.extend(
337
+ [
338
+ "## Active Context",
339
+ "",
340
+ f"**Working Directory**: `{active_context['working_directory']}`",
341
+ "",
342
+ ]
343
+ )
344
+
345
+ # Git context
346
+ lines.append("## Git Context")
347
+ lines.append("")
348
+ if git_context["is_git_repo"]:
349
+ lines.append(f"**Branch**: `{git_context['branch']}`")
350
+ lines.append(
351
+ f"**Status**: {'Clean' if git_context['status']['clean'] else 'Modified'}"
352
+ )
353
+ lines.append("")
354
+
355
+ if git_context["status"]["modified_files"]:
356
+ lines.append("**Modified files**:")
357
+ for f in git_context["status"]["modified_files"][:10]:
358
+ lines.append(f"- `{f}`")
359
+ lines.append("")
360
+
361
+ if git_context["recent_commits"]:
362
+ lines.append("**Recent commits**:")
363
+ for commit in git_context["recent_commits"]:
364
+ lines.append(
365
+ f"- `{commit['sha']}` - {commit['message']} ({commit['author']})"
366
+ )
367
+ lines.append("")
368
+ else:
369
+ lines.append("*Not a git repository*")
370
+ lines.append("")
371
+
372
+ # Important reminders
373
+ if state.get("important_reminders"):
374
+ lines.append("## Important Reminders")
375
+ lines.append("")
376
+ for reminder in state["important_reminders"]:
377
+ lines.append(f"- {reminder}")
378
+ lines.append("")
379
+
380
+ # Resume instructions
381
+ lines.extend(
382
+ [
383
+ "## Resume Instructions",
384
+ "",
385
+ "### Quick Resume (5 minutes)",
386
+ "",
387
+ ]
388
+ )
389
+ for instruction in state["resume_instructions"]["quick_start"]:
390
+ lines.append(f"1. {instruction}")
391
+ lines.append("")
392
+
393
+ if state["resume_instructions"]["validation_commands"]:
394
+ lines.append("### Validation Commands")
395
+ lines.append("")
396
+ lines.append("```bash")
397
+ for cmd in state["resume_instructions"]["validation_commands"].values():
398
+ lines.append(cmd)
399
+ lines.append("```")
400
+ lines.append("")
401
+
402
+ # Footer
403
+ lines.extend(
404
+ [
405
+ "---",
406
+ "",
407
+ "Resume with: `/mpm-init resume` or `cat .claude-mpm/sessions/LATEST-SESSION.txt`",
408
+ "",
409
+ ]
410
+ )
411
+
412
+ return "\n".join(lines)
413
+
414
+ def _update_latest_pointer(self, session_id: str) -> None:
415
+ """Update LATEST-SESSION.txt pointer.
416
+
417
+ Args:
418
+ session_id: Session identifier
419
+ """
420
+ try:
421
+ latest_file = self.pause_dir / "LATEST-SESSION.txt"
422
+ content = f"""Latest Session: {session_id}
423
+ Paused At: {datetime.now(timezone.utc).strftime("%Y-%m-%d %H:%M:%S %Z")}
424
+ Project: {self.project_path}
425
+
426
+ Files:
427
+ - {session_id}.json (machine-readable)
428
+ - {session_id}.yaml (human-readable config)
429
+ - {session_id}.md (documentation)
430
+
431
+ Quick Resume:
432
+ /mpm-init resume
433
+
434
+ Full Context:
435
+ cat .claude-mpm/sessions/{session_id}.md
436
+
437
+ Validation:
438
+ git status && git log -1 --stat
439
+ """
440
+ latest_file.write_text(content)
441
+ logger.debug(f"Updated LATEST-SESSION.txt: {session_id}")
442
+ except Exception as e:
443
+ logger.warning(f"Failed to update LATEST-SESSION.txt: {e}")
444
+
445
+ def _commit_pause_session(self, session_id: str, message: Optional[str]) -> None:
446
+ """Create git commit for pause session.
447
+
448
+ Args:
449
+ session_id: Session identifier
450
+ message: Optional context message
451
+ """
452
+ try:
453
+ # Add session files
454
+ subprocess.run(
455
+ ["git", "add", ".claude-mpm/sessions/"],
456
+ cwd=self.project_path,
457
+ check=True,
458
+ capture_output=True,
459
+ )
460
+
461
+ # Build commit message
462
+ commit_msg = f"session: pause at {datetime.now(timezone.utc).strftime('%Y-%m-%d %H:%M:%S')}\n\nSession ID: {session_id}"
463
+ if message:
464
+ commit_msg += f"\nContext: {message}"
465
+
466
+ # Create commit
467
+ subprocess.run(
468
+ ["git", "commit", "-m", commit_msg],
469
+ cwd=self.project_path,
470
+ check=True,
471
+ capture_output=True,
472
+ )
473
+
474
+ logger.info(f"Created git commit for pause session: {session_id}")
475
+
476
+ except subprocess.CalledProcessError as e:
477
+ # Non-fatal - pause still succeeded
478
+ logger.warning(f"Failed to create git commit: {e.stderr.decode()}")
479
+
480
+ def _get_project_version(self) -> str:
481
+ """Get project version from pyproject.toml or package.
482
+
483
+ Returns:
484
+ Version string or 'unknown'
485
+ """
486
+ try:
487
+ # Try pyproject.toml
488
+ pyproject = self.project_path / "pyproject.toml"
489
+ if pyproject.exists():
490
+ content = pyproject.read_text()
491
+ for line in content.split("\n"):
492
+ if line.startswith("version"):
493
+ return line.split("=")[1].strip().strip('"')
494
+
495
+ # Try package __version__
496
+ import claude_mpm
497
+
498
+ if hasattr(claude_mpm, "__version__"):
499
+ return claude_mpm.__version__
500
+
501
+ except Exception:
502
+ pass
503
+
504
+ return "unknown"
@@ -5,7 +5,8 @@ It detects paused sessions, calculates git changes since pause, and presents res
5
5
  context to users.
6
6
 
7
7
  DESIGN DECISIONS:
8
- - Project-specific session storage (.claude-mpm/sessions/pause/)
8
+ - Project-specific session storage (.claude-mpm/sessions/)
9
+ - Backward compatibility with legacy .claude-mpm/sessions/pause/ location
9
10
  - Non-blocking detection with graceful degradation
10
11
  - Git change detection for context updates
11
12
  - User-friendly prompts with time elapsed information
@@ -33,7 +34,10 @@ class SessionResumeHelper:
33
34
  project_path: Project root path (default: current directory)
34
35
  """
35
36
  self.project_path = project_path or Path.cwd()
36
- self.pause_dir = self.project_path / ".claude-mpm" / "sessions" / "pause"
37
+ # Primary location: flattened structure
38
+ self.pause_dir = self.project_path / ".claude-mpm" / "sessions"
39
+ # Legacy location for backward compatibility
40
+ self.legacy_pause_dir = self.project_path / ".claude-mpm" / "sessions" / "pause"
37
41
 
38
42
  def has_paused_sessions(self) -> bool:
39
43
  """Check if there are any paused sessions.
@@ -41,11 +45,15 @@ class SessionResumeHelper:
41
45
  Returns:
42
46
  True if paused sessions exist, False otherwise
43
47
  """
44
- if not self.pause_dir.exists():
45
- return False
48
+ # Check both primary and legacy locations
49
+ session_files = []
50
+
51
+ if self.pause_dir.exists():
52
+ session_files.extend(list(self.pause_dir.glob("session-*.json")))
53
+
54
+ if self.legacy_pause_dir.exists():
55
+ session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
46
56
 
47
- # Look for session JSON files
48
- session_files = list(self.pause_dir.glob("session-*.json"))
49
57
  return len(session_files) > 0
50
58
 
51
59
  def get_most_recent_session(self) -> Optional[Dict[str, Any]]:
@@ -54,11 +62,15 @@ class SessionResumeHelper:
54
62
  Returns:
55
63
  Session data dictionary or None if no sessions found
56
64
  """
57
- if not self.pause_dir.exists():
58
- return None
65
+ # Find all session files from both locations
66
+ session_files = []
67
+
68
+ if self.pause_dir.exists():
69
+ session_files.extend(list(self.pause_dir.glob("session-*.json")))
70
+
71
+ if self.legacy_pause_dir.exists():
72
+ session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
59
73
 
60
- # Find all session files
61
- session_files = list(self.pause_dir.glob("session-*.json"))
62
74
  if not session_files:
63
75
  return None
64
76
 
@@ -316,10 +328,14 @@ class SessionResumeHelper:
316
328
  Returns:
317
329
  Number of paused sessions
318
330
  """
319
- if not self.pause_dir.exists():
320
- return 0
331
+ session_files = []
332
+
333
+ if self.pause_dir.exists():
334
+ session_files.extend(list(self.pause_dir.glob("session-*.json")))
335
+
336
+ if self.legacy_pause_dir.exists():
337
+ session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
321
338
 
322
- session_files = list(self.pause_dir.glob("session-*.json"))
323
339
  return len(session_files)
324
340
 
325
341
  def list_all_sessions(self) -> List[Dict[str, Any]]:
@@ -328,10 +344,14 @@ class SessionResumeHelper:
328
344
  Returns:
329
345
  List of session data dictionaries
330
346
  """
331
- if not self.pause_dir.exists():
332
- return []
347
+ session_files = []
348
+
349
+ if self.pause_dir.exists():
350
+ session_files.extend(list(self.pause_dir.glob("session-*.json")))
351
+
352
+ if self.legacy_pause_dir.exists():
353
+ session_files.extend(list(self.legacy_pause_dir.glob("session-*.json")))
333
354
 
334
- session_files = list(self.pause_dir.glob("session-*.json"))
335
355
  if not session_files:
336
356
  return []
337
357
 
@@ -392,7 +392,7 @@ class UnifiedDashboardManager(IUnifiedDashboardManager):
392
392
  port = self.find_available_port()
393
393
 
394
394
  # Use force_restart to ensure we're using the latest code
395
- success, browser_opened = self.start_dashboard(
395
+ success, _browser_opened = self.start_dashboard(
396
396
  port=port, background=True, open_browser=False, force_restart=force_restart
397
397
  )
398
398
 
@@ -9,6 +9,7 @@ and lifecycle management.
9
9
  Part of TSK-0046: Service Layer Architecture Reorganization
10
10
  """
11
11
 
12
+ import threading
12
13
  from abc import ABC, abstractmethod
13
14
  from typing import Any, Dict, Optional
14
15
 
@@ -221,29 +222,43 @@ class SingletonService(SyncBaseService):
221
222
  """
222
223
  Base class for singleton services.
223
224
 
224
- Ensures only one instance of the service exists.
225
+ Ensures only one instance of the service exists with thread-safe initialization.
226
+ Uses double-checked locking pattern to prevent race conditions.
225
227
  """
226
228
 
227
229
  _instances: Dict[type, "SingletonService"] = {}
230
+ _lock = threading.Lock()
228
231
 
229
232
  def __new__(cls, *args, **kwargs):
230
- """Ensure only one instance exists."""
233
+ """Ensure only one instance exists with thread-safe initialization."""
234
+ # Fast path - check without lock
231
235
  if cls not in cls._instances:
232
- cls._instances[cls] = super().__new__(cls)
236
+ # Slow path - acquire lock and double-check
237
+ with cls._lock:
238
+ if cls not in cls._instances:
239
+ cls._instances[cls] = super().__new__(cls)
233
240
  return cls._instances[cls]
234
241
 
235
242
  @classmethod
236
243
  def get_instance(cls) -> "SingletonService":
237
- """Get the singleton instance."""
244
+ """Get the singleton instance with thread-safe initialization."""
245
+ # Fast path - check without lock
238
246
  if cls not in cls._instances:
239
- cls._instances[cls] = cls()
247
+ # Slow path - acquire lock and double-check
248
+ with cls._lock:
249
+ if cls not in cls._instances:
250
+ cls._instances[cls] = cls()
240
251
  return cls._instances[cls]
241
252
 
242
253
  @classmethod
243
254
  def clear_instance(cls) -> None:
244
- """Clear the singleton instance (useful for testing)."""
245
- if cls in cls._instances:
246
- instance = cls._instances[cls]
247
- if hasattr(instance, "shutdown") and not instance.is_shutdown:
248
- instance.shutdown()
249
- del cls._instances[cls]
255
+ """Clear the singleton instance (useful for testing).
256
+
257
+ Thread-safe implementation ensures proper cleanup.
258
+ """
259
+ with cls._lock:
260
+ if cls in cls._instances:
261
+ instance = cls._instances[cls]
262
+ if hasattr(instance, "shutdown") and not instance.is_shutdown:
263
+ instance.shutdown()
264
+ del cls._instances[cls]