claude-mpm 4.1.26__py3-none-any.whl → 4.24.0__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 (845) hide show
  1. claude_mpm/BUILD_NUMBER +1 -1
  2. claude_mpm/VERSION +1 -1
  3. claude_mpm/__init__.py +20 -5
  4. claude_mpm/agents/BASE_AGENT_TEMPLATE.md +118 -0
  5. claude_mpm/agents/BASE_DOCUMENTATION.md +53 -0
  6. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  7. claude_mpm/agents/BASE_OPS.md +219 -0
  8. claude_mpm/agents/BASE_PM.md +420 -158
  9. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +787 -0
  10. claude_mpm/agents/BASE_QA.md +167 -0
  11. claude_mpm/agents/BASE_RESEARCH.md +53 -0
  12. claude_mpm/agents/OUTPUT_STYLE.md +299 -29
  13. claude_mpm/agents/PM_INSTRUCTIONS.md +1159 -0
  14. claude_mpm/agents/WORKFLOW.md +355 -191
  15. claude_mpm/agents/agent_loader.py +40 -10
  16. claude_mpm/agents/agent_loader_integration.py +3 -2
  17. claude_mpm/agents/async_agent_loader.py +3 -3
  18. claude_mpm/agents/base_agent_loader.py +11 -9
  19. claude_mpm/agents/frontmatter_validator.py +291 -251
  20. claude_mpm/agents/system_agent_config.py +3 -2
  21. claude_mpm/agents/templates/README.md +465 -0
  22. claude_mpm/agents/templates/agent-manager.json +7 -4
  23. claude_mpm/agents/templates/{agentic_coder_optimizer.json → agentic-coder-optimizer.json} +33 -7
  24. claude_mpm/agents/templates/api_qa.json +16 -4
  25. claude_mpm/agents/templates/circuit_breakers.md +638 -0
  26. claude_mpm/agents/templates/clerk-ops.json +235 -0
  27. claude_mpm/agents/templates/code_analyzer.json +10 -4
  28. claude_mpm/agents/templates/content-agent.json +358 -0
  29. claude_mpm/agents/templates/dart_engineer.json +307 -0
  30. claude_mpm/agents/templates/data_engineer.json +87 -14
  31. claude_mpm/agents/templates/documentation.json +76 -13
  32. claude_mpm/agents/templates/engineer.json +43 -9
  33. claude_mpm/agents/templates/gcp_ops_agent.json +253 -0
  34. claude_mpm/agents/templates/git_file_tracking.md +584 -0
  35. claude_mpm/agents/templates/golang_engineer.json +270 -0
  36. claude_mpm/agents/templates/imagemagick.json +5 -2
  37. claude_mpm/agents/templates/java_engineer.json +346 -0
  38. claude_mpm/agents/templates/javascript_engineer_agent.json +380 -0
  39. claude_mpm/agents/templates/local_ops_agent.json +1840 -0
  40. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250901_010124_142.md +400 -0
  41. claude_mpm/agents/templates/memory_manager.json +6 -3
  42. claude_mpm/agents/templates/nextjs_engineer.json +285 -0
  43. claude_mpm/agents/templates/ops.json +14 -4
  44. claude_mpm/agents/templates/php-engineer.json +287 -0
  45. claude_mpm/agents/templates/pm_examples.md +474 -0
  46. claude_mpm/agents/templates/pm_red_flags.md +262 -0
  47. claude_mpm/agents/templates/product_owner.json +338 -0
  48. claude_mpm/agents/templates/project_organizer.json +19 -5
  49. claude_mpm/agents/templates/prompt-engineer.json +737 -0
  50. claude_mpm/agents/templates/python_engineer.json +387 -0
  51. claude_mpm/agents/templates/qa.json +25 -5
  52. claude_mpm/agents/templates/react_engineer.json +239 -0
  53. claude_mpm/agents/templates/refactoring_engineer.json +15 -5
  54. claude_mpm/agents/templates/research.json +46 -21
  55. claude_mpm/agents/templates/response_format.md +583 -0
  56. claude_mpm/agents/templates/ruby-engineer.json +280 -0
  57. claude_mpm/agents/templates/rust_engineer.json +275 -0
  58. claude_mpm/agents/templates/security.json +59 -10
  59. claude_mpm/agents/templates/svelte-engineer.json +225 -0
  60. claude_mpm/agents/templates/tauri_engineer.json +274 -0
  61. claude_mpm/agents/templates/ticketing.json +16 -7
  62. claude_mpm/agents/templates/typescript_engineer.json +285 -0
  63. claude_mpm/agents/templates/validation_templates.md +312 -0
  64. claude_mpm/agents/templates/vercel_ops_agent.json +164 -33
  65. claude_mpm/agents/templates/version_control.json +16 -4
  66. claude_mpm/agents/templates/web_qa.json +167 -21
  67. claude_mpm/agents/templates/web_ui.json +18 -5
  68. claude_mpm/cli/__init__.py +38 -378
  69. claude_mpm/cli/commands/__init__.py +2 -0
  70. claude_mpm/cli/commands/agent_manager.py +675 -20
  71. claude_mpm/cli/commands/agent_state_manager.py +186 -0
  72. claude_mpm/cli/commands/agents.py +722 -150
  73. claude_mpm/cli/commands/agents_detect.py +380 -0
  74. claude_mpm/cli/commands/agents_recommend.py +309 -0
  75. claude_mpm/cli/commands/aggregate.py +10 -6
  76. claude_mpm/cli/commands/analyze.py +15 -10
  77. claude_mpm/cli/commands/analyze_code.py +8 -4
  78. claude_mpm/cli/commands/auto_configure.py +570 -0
  79. claude_mpm/cli/commands/cleanup.py +12 -12
  80. claude_mpm/cli/commands/config.py +47 -13
  81. claude_mpm/cli/commands/configure.py +469 -1064
  82. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  83. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  84. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  85. claude_mpm/cli/commands/configure_models.py +18 -0
  86. claude_mpm/cli/commands/configure_navigation.py +167 -0
  87. claude_mpm/cli/commands/configure_paths.py +104 -0
  88. claude_mpm/cli/commands/configure_persistence.py +254 -0
  89. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  90. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  91. claude_mpm/cli/commands/configure_validators.py +73 -0
  92. claude_mpm/cli/commands/dashboard.py +50 -52
  93. claude_mpm/cli/commands/debug.py +7 -7
  94. claude_mpm/cli/commands/doctor.py +43 -7
  95. claude_mpm/cli/commands/info.py +3 -4
  96. claude_mpm/cli/commands/local_deploy.py +537 -0
  97. claude_mpm/cli/commands/mcp.py +17 -10
  98. claude_mpm/cli/commands/mcp_command_router.py +11 -0
  99. claude_mpm/cli/commands/mcp_config.py +154 -0
  100. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  101. claude_mpm/cli/commands/mcp_install_commands.py +101 -32
  102. claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
  103. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  104. claude_mpm/cli/commands/memory.py +55 -21
  105. claude_mpm/cli/commands/monitor.py +160 -70
  106. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  107. claude_mpm/cli/commands/mpm_init/core.py +525 -0
  108. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  109. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  110. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  111. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  112. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  113. claude_mpm/cli/commands/mpm_init_handler.py +114 -4
  114. claude_mpm/cli/commands/run.py +169 -42
  115. claude_mpm/cli/commands/search.py +458 -0
  116. claude_mpm/cli/commands/skills.py +488 -0
  117. claude_mpm/cli/commands/uninstall.py +176 -0
  118. claude_mpm/cli/commands/upgrade.py +152 -0
  119. claude_mpm/cli/commands/verify.py +119 -0
  120. claude_mpm/cli/executor.py +204 -0
  121. claude_mpm/cli/helpers.py +105 -0
  122. claude_mpm/cli/interactive/__init__.py +21 -0
  123. claude_mpm/cli/interactive/agent_wizard.py +962 -0
  124. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  125. claude_mpm/cli/parser.py +79 -2
  126. claude_mpm/cli/parsers/__init__.py +7 -1
  127. claude_mpm/cli/parsers/agent_manager_parser.py +161 -1
  128. claude_mpm/cli/parsers/agents_parser.py +116 -0
  129. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  130. claude_mpm/cli/parsers/base_parser.py +143 -3
  131. claude_mpm/cli/parsers/configure_parser.py +11 -15
  132. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  133. claude_mpm/cli/parsers/mcp_parser.py +15 -0
  134. claude_mpm/cli/parsers/monitor_parser.py +12 -2
  135. claude_mpm/cli/parsers/mpm_init_parser.py +179 -9
  136. claude_mpm/cli/parsers/run_parser.py +5 -0
  137. claude_mpm/cli/parsers/search_parser.py +245 -0
  138. claude_mpm/cli/parsers/skills_parser.py +137 -0
  139. claude_mpm/cli/shared/argument_patterns.py +20 -13
  140. claude_mpm/cli/shared/base_command.py +2 -2
  141. claude_mpm/cli/shared/output_formatters.py +28 -19
  142. claude_mpm/cli/startup.py +562 -0
  143. claude_mpm/cli/startup_logging.py +179 -13
  144. claude_mpm/cli/utils.py +53 -2
  145. claude_mpm/commands/mpm-agents-detect.md +168 -0
  146. claude_mpm/commands/mpm-agents-recommend.md +214 -0
  147. claude_mpm/commands/mpm-agents.md +118 -8
  148. claude_mpm/commands/mpm-auto-configure.md +269 -0
  149. claude_mpm/commands/mpm-config.md +137 -14
  150. claude_mpm/commands/mpm-help.md +285 -5
  151. claude_mpm/commands/mpm-init.md +374 -15
  152. claude_mpm/commands/mpm-monitor.md +409 -0
  153. claude_mpm/commands/mpm-organize.md +295 -0
  154. claude_mpm/commands/mpm-resume.md +372 -0
  155. claude_mpm/commands/mpm-status.md +71 -9
  156. claude_mpm/commands/mpm-tickets.md +56 -7
  157. claude_mpm/commands/mpm-version.md +113 -0
  158. claude_mpm/commands/mpm.md +2 -0
  159. claude_mpm/config/agent_config.py +4 -4
  160. claude_mpm/config/experimental_features.py +7 -7
  161. claude_mpm/config/model_config.py +428 -0
  162. claude_mpm/config/paths.py +3 -2
  163. claude_mpm/config/socketio_config.py +3 -3
  164. claude_mpm/constants.py +15 -1
  165. claude_mpm/core/__init__.py +53 -17
  166. claude_mpm/core/agent_name_normalizer.py +3 -2
  167. claude_mpm/core/agent_registry.py +2 -2
  168. claude_mpm/core/agent_session_manager.py +10 -10
  169. claude_mpm/core/api_validator.py +330 -0
  170. claude_mpm/core/base_service.py +33 -23
  171. claude_mpm/core/cache.py +9 -9
  172. claude_mpm/core/claude_runner.py +19 -8
  173. claude_mpm/core/config.py +85 -8
  174. claude_mpm/core/config_aliases.py +7 -6
  175. claude_mpm/core/constants.py +65 -0
  176. claude_mpm/core/container.py +11 -5
  177. claude_mpm/core/enums.py +452 -0
  178. claude_mpm/core/error_handler.py +623 -0
  179. claude_mpm/core/factories.py +1 -1
  180. claude_mpm/core/file_utils.py +764 -0
  181. claude_mpm/core/framework/__init__.py +38 -0
  182. claude_mpm/core/framework/formatters/__init__.py +11 -0
  183. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  184. claude_mpm/core/framework/formatters/content_formatter.py +288 -0
  185. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  186. claude_mpm/core/framework/loaders/__init__.py +13 -0
  187. claude_mpm/core/framework/loaders/agent_loader.py +210 -0
  188. claude_mpm/core/framework/loaders/file_loader.py +223 -0
  189. claude_mpm/core/framework/loaders/instruction_loader.py +161 -0
  190. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  191. claude_mpm/core/framework/processors/__init__.py +11 -0
  192. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  193. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  194. claude_mpm/core/framework/processors/template_processor.py +244 -0
  195. claude_mpm/core/framework_loader.py +321 -1631
  196. claude_mpm/core/hook_manager.py +8 -6
  197. claude_mpm/core/injectable_service.py +11 -8
  198. claude_mpm/core/instruction_reinforcement_hook.py +4 -3
  199. claude_mpm/core/interactive_session.py +55 -8
  200. claude_mpm/core/interfaces.py +56 -1
  201. claude_mpm/core/lazy.py +3 -3
  202. claude_mpm/core/log_manager.py +92 -23
  203. claude_mpm/core/logger.py +19 -14
  204. claude_mpm/core/logging_config.py +6 -2
  205. claude_mpm/core/logging_utils.py +520 -0
  206. claude_mpm/core/oneshot_session.py +51 -7
  207. claude_mpm/core/optimized_agent_loader.py +9 -9
  208. claude_mpm/core/optimized_startup.py +1 -1
  209. claude_mpm/core/output_style_manager.py +12 -192
  210. claude_mpm/core/pm_hook_interceptor.py +18 -12
  211. claude_mpm/core/service_registry.py +7 -3
  212. claude_mpm/core/session_manager.py +14 -12
  213. claude_mpm/core/shared/config_loader.py +1 -1
  214. claude_mpm/core/socketio_pool.py +15 -15
  215. claude_mpm/core/tool_access_control.py +3 -2
  216. claude_mpm/core/types.py +4 -11
  217. claude_mpm/core/typing_utils.py +7 -6
  218. claude_mpm/core/unified_agent_registry.py +115 -11
  219. claude_mpm/core/unified_config.py +6 -6
  220. claude_mpm/core/unified_paths.py +23 -20
  221. claude_mpm/dashboard/analysis_runner.py +4 -4
  222. claude_mpm/dashboard/api/simple_directory.py +261 -0
  223. claude_mpm/dashboard/react/components/DataInspector/DataInspector.module.css +188 -0
  224. claude_mpm/dashboard/react/components/EventViewer/EventViewer.module.css +156 -0
  225. claude_mpm/dashboard/react/components/shared/ConnectionStatus.module.css +38 -0
  226. claude_mpm/dashboard/react/components/shared/FilterBar.module.css +92 -0
  227. claude_mpm/dashboard/static/archive/activity_dashboard_fixed.html +248 -0
  228. claude_mpm/dashboard/static/archive/activity_dashboard_test.html +61 -0
  229. claude_mpm/dashboard/static/archive/test_activity_connection.html +179 -0
  230. claude_mpm/dashboard/static/archive/test_claude_tree_tab.html +68 -0
  231. claude_mpm/dashboard/static/archive/test_dashboard.html +409 -0
  232. claude_mpm/dashboard/static/archive/test_dashboard_fixed.html +519 -0
  233. claude_mpm/dashboard/static/archive/test_dashboard_verification.html +181 -0
  234. claude_mpm/dashboard/static/archive/test_file_data.html +315 -0
  235. claude_mpm/dashboard/static/archive/test_file_tree_empty_state.html +243 -0
  236. claude_mpm/dashboard/static/archive/test_file_tree_fix.html +234 -0
  237. claude_mpm/dashboard/static/archive/test_file_tree_rename.html +117 -0
  238. claude_mpm/dashboard/static/archive/test_file_tree_tab.html +115 -0
  239. claude_mpm/dashboard/static/archive/test_file_viewer.html +224 -0
  240. claude_mpm/dashboard/static/archive/test_final_activity.html +220 -0
  241. claude_mpm/dashboard/static/archive/test_tab_fix.html +139 -0
  242. claude_mpm/dashboard/static/built/assets/events.DjpNxWNo.css +1 -0
  243. claude_mpm/dashboard/static/built/components/activity-tree.js +1 -1
  244. claude_mpm/dashboard/static/built/components/agent-hierarchy.js +777 -0
  245. claude_mpm/dashboard/static/built/components/agent-inference.js +1 -1
  246. claude_mpm/dashboard/static/built/components/build-tracker.js +333 -0
  247. claude_mpm/dashboard/static/built/components/code-simple.js +857 -0
  248. claude_mpm/dashboard/static/built/components/code-tree/tree-breadcrumb.js +353 -0
  249. claude_mpm/dashboard/static/built/components/code-tree/tree-constants.js +235 -0
  250. claude_mpm/dashboard/static/built/components/code-tree/tree-search.js +409 -0
  251. claude_mpm/dashboard/static/built/components/code-tree/tree-utils.js +435 -0
  252. claude_mpm/dashboard/static/built/components/code-tree.js +1 -1
  253. claude_mpm/dashboard/static/built/components/code-viewer.js +1 -1
  254. claude_mpm/dashboard/static/built/components/connection-debug.js +654 -0
  255. claude_mpm/dashboard/static/built/components/diff-viewer.js +891 -0
  256. claude_mpm/dashboard/static/built/components/event-processor.js +1 -1
  257. claude_mpm/dashboard/static/built/components/event-viewer.js +1 -1
  258. claude_mpm/dashboard/static/built/components/export-manager.js +1 -1
  259. claude_mpm/dashboard/static/built/components/file-change-tracker.js +443 -0
  260. claude_mpm/dashboard/static/built/components/file-change-viewer.js +690 -0
  261. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +1 -1
  262. claude_mpm/dashboard/static/built/components/file-viewer.js +2 -0
  263. claude_mpm/dashboard/static/built/components/module-viewer.js +1 -1
  264. claude_mpm/dashboard/static/built/components/nav-bar.js +145 -0
  265. claude_mpm/dashboard/static/built/components/page-structure.js +429 -0
  266. claude_mpm/dashboard/static/built/components/session-manager.js +1 -1
  267. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +1 -1
  268. claude_mpm/dashboard/static/built/components/working-directory.js +1 -1
  269. claude_mpm/dashboard/static/built/connection-manager.js +536 -0
  270. claude_mpm/dashboard/static/built/dashboard.js +1 -1
  271. claude_mpm/dashboard/static/built/extension-error-handler.js +164 -0
  272. claude_mpm/dashboard/static/built/react/events.js +30 -0
  273. claude_mpm/dashboard/static/built/shared/dom-helpers.js +396 -0
  274. claude_mpm/dashboard/static/built/shared/event-bus.js +330 -0
  275. claude_mpm/dashboard/static/built/shared/event-filter-service.js +540 -0
  276. claude_mpm/dashboard/static/built/shared/logger.js +385 -0
  277. claude_mpm/dashboard/static/built/shared/page-structure.js +249 -0
  278. claude_mpm/dashboard/static/built/shared/tooltip-service.js +253 -0
  279. claude_mpm/dashboard/static/built/socket-client.js +1 -1
  280. claude_mpm/dashboard/static/built/tab-isolation-fix.js +185 -0
  281. claude_mpm/dashboard/static/css/dashboard.css +588 -6
  282. claude_mpm/dashboard/static/dist/assets/events.DjpNxWNo.css +1 -0
  283. claude_mpm/dashboard/static/dist/components/activity-tree.js +1 -1
  284. claude_mpm/dashboard/static/dist/components/agent-inference.js +1 -1
  285. claude_mpm/dashboard/static/dist/components/code-tree.js +1 -1
  286. claude_mpm/dashboard/static/dist/components/code-viewer.js +1 -1
  287. claude_mpm/dashboard/static/dist/components/event-processor.js +1 -1
  288. claude_mpm/dashboard/static/dist/components/event-viewer.js +1 -1
  289. claude_mpm/dashboard/static/dist/components/export-manager.js +1 -1
  290. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +1 -1
  291. claude_mpm/dashboard/static/dist/components/file-viewer.js +2 -0
  292. claude_mpm/dashboard/static/dist/components/module-viewer.js +1 -1
  293. claude_mpm/dashboard/static/dist/components/session-manager.js +1 -1
  294. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +1 -1
  295. claude_mpm/dashboard/static/dist/components/working-directory.js +1 -1
  296. claude_mpm/dashboard/static/dist/dashboard.js +1 -1
  297. claude_mpm/dashboard/static/dist/react/events.js +30 -0
  298. claude_mpm/dashboard/static/dist/socket-client.js +1 -1
  299. claude_mpm/dashboard/static/events.html +607 -0
  300. claude_mpm/dashboard/static/index.html +635 -0
  301. claude_mpm/dashboard/static/js/components/activity-tree.js +3 -17
  302. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +4 -1
  303. claude_mpm/dashboard/static/js/components/agent-inference.js +3 -0
  304. claude_mpm/dashboard/static/js/components/build-tracker.js +8 -0
  305. claude_mpm/dashboard/static/js/components/code-simple.js +857 -0
  306. claude_mpm/dashboard/static/js/components/diff-viewer.js +891 -0
  307. claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
  308. claude_mpm/dashboard/static/js/components/event-viewer.js +39 -2
  309. claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
  310. claude_mpm/dashboard/static/js/components/file-change-tracker.js +443 -0
  311. claude_mpm/dashboard/static/js/components/file-change-viewer.js +690 -0
  312. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +30 -10
  313. claude_mpm/dashboard/static/js/components/file-viewer.js +580 -0
  314. claude_mpm/dashboard/static/js/components/module-viewer.js +26 -0
  315. claude_mpm/dashboard/static/js/components/session-manager.js +7 -7
  316. claude_mpm/dashboard/static/js/components/socket-manager.js +4 -0
  317. claude_mpm/dashboard/static/js/components/ui-state-manager.js +356 -41
  318. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +455 -23
  319. claude_mpm/dashboard/static/js/components/working-directory.js +44 -9
  320. claude_mpm/dashboard/static/js/dashboard.js +245 -132
  321. claude_mpm/dashboard/static/js/shared/dom-helpers.js +396 -0
  322. claude_mpm/dashboard/static/js/shared/event-bus.js +330 -0
  323. claude_mpm/dashboard/static/js/shared/logger.js +385 -0
  324. claude_mpm/dashboard/static/js/shared/tooltip-service.js +253 -0
  325. claude_mpm/dashboard/static/js/socket-client.js +49 -22
  326. claude_mpm/dashboard/static/js/stores/dashboard-store.js +562 -0
  327. claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
  328. claude_mpm/dashboard/static/legacy/activity.html +736 -0
  329. claude_mpm/dashboard/static/legacy/agents.html +786 -0
  330. claude_mpm/dashboard/static/legacy/files.html +747 -0
  331. claude_mpm/dashboard/static/legacy/tools.html +831 -0
  332. claude_mpm/dashboard/static/monitors.html +431 -0
  333. claude_mpm/dashboard/static/production/events.html +659 -0
  334. claude_mpm/dashboard/static/production/main.html +698 -0
  335. claude_mpm/dashboard/static/production/monitors.html +483 -0
  336. claude_mpm/dashboard/static/socket.io.min.js +7 -0
  337. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
  338. claude_mpm/dashboard/static/test-archive/dashboard.html +635 -0
  339. claude_mpm/dashboard/static/test-archive/debug-events.html +147 -0
  340. claude_mpm/dashboard/static/test-archive/test-navigation.html +256 -0
  341. claude_mpm/dashboard/static/test-archive/test-react-exports.html +180 -0
  342. claude_mpm/dashboard/static/test-archive/test_debug.html +25 -0
  343. claude_mpm/dashboard/templates/code_simple.html +153 -0
  344. claude_mpm/dashboard/templates/index.html +112 -109
  345. claude_mpm/experimental/cli_enhancements.py +4 -2
  346. claude_mpm/generators/agent_profile_generator.py +5 -3
  347. claude_mpm/hooks/__init__.py +37 -1
  348. claude_mpm/hooks/base_hook.py +5 -4
  349. claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
  350. claude_mpm/hooks/claude_hooks/event_handlers.py +21 -18
  351. claude_mpm/hooks/claude_hooks/hook_handler.py +29 -22
  352. claude_mpm/hooks/claude_hooks/installer.py +67 -22
  353. claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
  354. claude_mpm/hooks/claude_hooks/response_tracking.py +57 -17
  355. claude_mpm/hooks/claude_hooks/services/connection_manager.py +62 -64
  356. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +140 -76
  357. claude_mpm/hooks/claude_hooks/services/state_manager.py +11 -9
  358. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
  359. claude_mpm/hooks/failure_learning/__init__.py +60 -0
  360. claude_mpm/hooks/failure_learning/failure_detection_hook.py +235 -0
  361. claude_mpm/hooks/failure_learning/fix_detection_hook.py +217 -0
  362. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +286 -0
  363. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  364. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  365. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  366. claude_mpm/hooks/kuzu_response_hook.py +183 -0
  367. claude_mpm/hooks/memory_integration_hook.py +1 -1
  368. claude_mpm/hooks/session_resume_hook.py +121 -0
  369. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  370. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  371. claude_mpm/hooks/tool_call_interceptor.py +8 -5
  372. claude_mpm/hooks/validation_hooks.py +3 -3
  373. claude_mpm/init.py +23 -4
  374. claude_mpm/models/agent_session.py +8 -6
  375. claude_mpm/models/resume_log.py +340 -0
  376. claude_mpm/scripts/claude-hook-handler.sh +33 -7
  377. claude_mpm/scripts/launch_monitor.py +85 -0
  378. claude_mpm/scripts/mcp_server.py +3 -5
  379. claude_mpm/scripts/mpm_doctor.py +3 -2
  380. claude_mpm/scripts/socketio_daemon.py +159 -512
  381. claude_mpm/services/__init__.py +144 -160
  382. claude_mpm/services/agents/__init__.py +18 -5
  383. claude_mpm/services/agents/agent_builder.py +13 -11
  384. claude_mpm/services/agents/auto_config_manager.py +796 -0
  385. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  386. claude_mpm/services/agents/deployment/agent_deployment.py +38 -15
  387. claude_mpm/services/agents/deployment/agent_discovery_service.py +125 -7
  388. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +5 -5
  389. claude_mpm/services/agents/deployment/agent_format_converter.py +56 -12
  390. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +4 -2
  391. claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
  392. claude_mpm/services/agents/deployment/agent_record_service.py +4 -4
  393. claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
  394. claude_mpm/services/agents/deployment/agent_template_builder.py +715 -47
  395. claude_mpm/services/agents/deployment/agent_validator.py +31 -7
  396. claude_mpm/services/agents/deployment/agent_version_manager.py +8 -5
  397. claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
  398. claude_mpm/services/agents/deployment/async_agent_deployment.py +1 -1
  399. claude_mpm/services/agents/deployment/deployment_config_loader.py +131 -7
  400. claude_mpm/services/agents/deployment/deployment_type_detector.py +10 -14
  401. claude_mpm/services/agents/deployment/deployment_wrapper.py +58 -0
  402. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  403. claude_mpm/services/agents/deployment/local_template_deployment.py +360 -0
  404. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +134 -38
  405. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +8 -7
  406. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  407. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  408. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +7 -5
  409. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  410. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +9 -6
  411. claude_mpm/services/agents/deployment/system_instructions_deployer.py +9 -6
  412. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  413. claude_mpm/services/agents/deployment/validation/template_validator.py +64 -44
  414. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  415. claude_mpm/services/agents/loading/agent_profile_loader.py +10 -9
  416. claude_mpm/services/agents/loading/base_agent_manager.py +16 -6
  417. claude_mpm/services/agents/loading/framework_agent_loader.py +2 -2
  418. claude_mpm/services/agents/local_template_manager.py +744 -0
  419. claude_mpm/services/agents/management/agent_capabilities_generator.py +3 -2
  420. claude_mpm/services/agents/management/agent_management_service.py +5 -5
  421. claude_mpm/services/agents/memory/agent_memory_manager.py +32 -29
  422. claude_mpm/services/agents/memory/content_manager.py +17 -9
  423. claude_mpm/services/agents/memory/memory_categorization_service.py +4 -2
  424. claude_mpm/services/agents/memory/memory_file_service.py +32 -6
  425. claude_mpm/services/agents/memory/memory_format_service.py +6 -4
  426. claude_mpm/services/agents/memory/memory_limits_service.py +4 -2
  427. claude_mpm/services/agents/memory/template_generator.py +3 -3
  428. claude_mpm/services/agents/observers.py +547 -0
  429. claude_mpm/services/agents/recommender.py +615 -0
  430. claude_mpm/services/agents/registry/deployed_agent_discovery.py +3 -3
  431. claude_mpm/services/agents/registry/modification_tracker.py +30 -19
  432. claude_mpm/services/async_session_logger.py +141 -98
  433. claude_mpm/services/claude_session_logger.py +82 -74
  434. claude_mpm/services/cli/agent_cleanup_service.py +5 -0
  435. claude_mpm/services/cli/agent_listing_service.py +5 -5
  436. claude_mpm/services/cli/agent_validation_service.py +3 -1
  437. claude_mpm/services/cli/memory_crud_service.py +12 -7
  438. claude_mpm/services/cli/memory_output_formatter.py +2 -2
  439. claude_mpm/services/cli/resume_service.py +617 -0
  440. claude_mpm/services/cli/session_manager.py +104 -13
  441. claude_mpm/services/cli/session_pause_manager.py +504 -0
  442. claude_mpm/services/cli/session_resume_helper.py +372 -0
  443. claude_mpm/services/cli/startup_checker.py +13 -10
  444. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  445. claude_mpm/services/command_deployment_service.py +9 -7
  446. claude_mpm/services/command_handler_service.py +11 -5
  447. claude_mpm/services/core/__init__.py +33 -1
  448. claude_mpm/services/core/base.py +26 -11
  449. claude_mpm/services/core/interfaces/__init__.py +90 -3
  450. claude_mpm/services/core/interfaces/agent.py +184 -0
  451. claude_mpm/services/core/interfaces/health.py +172 -0
  452. claude_mpm/services/core/interfaces/model.py +281 -0
  453. claude_mpm/services/core/interfaces/process.py +372 -0
  454. claude_mpm/services/core/interfaces/project.py +121 -0
  455. claude_mpm/services/core/interfaces/restart.py +307 -0
  456. claude_mpm/services/core/interfaces/stability.py +260 -0
  457. claude_mpm/services/core/interfaces.py +56 -1
  458. claude_mpm/services/core/memory_manager.py +92 -47
  459. claude_mpm/services/core/models/__init__.py +79 -0
  460. claude_mpm/services/core/models/agent_config.py +384 -0
  461. claude_mpm/services/core/models/health.py +162 -0
  462. claude_mpm/services/core/models/process.py +239 -0
  463. claude_mpm/services/core/models/restart.py +302 -0
  464. claude_mpm/services/core/models/stability.py +264 -0
  465. claude_mpm/services/core/models/toolchain.py +306 -0
  466. claude_mpm/services/core/path_resolver.py +36 -14
  467. claude_mpm/services/diagnostics/__init__.py +2 -2
  468. claude_mpm/services/diagnostics/checks/__init__.py +4 -2
  469. claude_mpm/services/diagnostics/checks/agent_check.py +30 -32
  470. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  471. claude_mpm/services/diagnostics/checks/common_issues_check.py +28 -27
  472. claude_mpm/services/diagnostics/checks/configuration_check.py +26 -25
  473. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  474. claude_mpm/services/diagnostics/checks/installation_check.py +165 -60
  475. claude_mpm/services/diagnostics/checks/instructions_check.py +20 -19
  476. claude_mpm/services/diagnostics/checks/mcp_check.py +57 -43
  477. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1066 -0
  478. claude_mpm/services/diagnostics/checks/monitor_check.py +24 -23
  479. claude_mpm/services/diagnostics/checks/startup_log_check.py +14 -11
  480. claude_mpm/services/diagnostics/diagnostic_runner.py +22 -13
  481. claude_mpm/services/diagnostics/doctor_reporter.py +275 -47
  482. claude_mpm/services/diagnostics/models.py +37 -21
  483. claude_mpm/services/event_aggregator.py +5 -3
  484. claude_mpm/services/event_bus/direct_relay.py +8 -4
  485. claude_mpm/services/event_bus/event_bus.py +51 -9
  486. claude_mpm/services/event_bus/relay.py +33 -14
  487. claude_mpm/services/events/consumers/dead_letter.py +7 -5
  488. claude_mpm/services/events/core.py +5 -6
  489. claude_mpm/services/events/producers/hook.py +6 -6
  490. claude_mpm/services/events/producers/system.py +8 -8
  491. claude_mpm/services/exceptions.py +5 -5
  492. claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
  493. claude_mpm/services/framework_claude_md_generator/content_assembler.py +5 -5
  494. claude_mpm/services/framework_claude_md_generator/content_validator.py +2 -2
  495. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
  496. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
  497. claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
  498. claude_mpm/services/hook_installer_service.py +506 -0
  499. claude_mpm/services/hook_service.py +5 -6
  500. claude_mpm/services/infrastructure/context_preservation.py +13 -11
  501. claude_mpm/services/infrastructure/daemon_manager.py +9 -9
  502. claude_mpm/services/infrastructure/logging.py +2 -2
  503. claude_mpm/services/infrastructure/monitoring/__init__.py +1 -1
  504. claude_mpm/services/infrastructure/monitoring/aggregator.py +12 -12
  505. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  506. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  507. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  508. claude_mpm/services/infrastructure/monitoring/resources.py +8 -7
  509. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  510. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  511. claude_mpm/services/local_ops/__init__.py +165 -0
  512. claude_mpm/services/local_ops/crash_detector.py +257 -0
  513. claude_mpm/services/local_ops/health_checks/__init__.py +28 -0
  514. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  515. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  516. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  517. claude_mpm/services/local_ops/health_manager.py +430 -0
  518. claude_mpm/services/local_ops/log_monitor.py +396 -0
  519. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  520. claude_mpm/services/local_ops/process_manager.py +595 -0
  521. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  522. claude_mpm/services/local_ops/restart_manager.py +401 -0
  523. claude_mpm/services/local_ops/restart_policy.py +387 -0
  524. claude_mpm/services/local_ops/state_manager.py +372 -0
  525. claude_mpm/services/local_ops/unified_manager.py +600 -0
  526. claude_mpm/services/mcp_config_manager.py +1612 -0
  527. claude_mpm/services/mcp_gateway/__init__.py +97 -93
  528. claude_mpm/services/mcp_gateway/auto_configure.py +43 -38
  529. claude_mpm/services/mcp_gateway/config/config_loader.py +3 -3
  530. claude_mpm/services/mcp_gateway/config/configuration.py +23 -4
  531. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  532. claude_mpm/services/mcp_gateway/core/base.py +20 -33
  533. claude_mpm/services/mcp_gateway/core/process_pool.py +585 -31
  534. claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
  535. claude_mpm/services/mcp_gateway/core/startup_verification.py +3 -3
  536. claude_mpm/services/mcp_gateway/main.py +90 -15
  537. claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
  538. claude_mpm/services/mcp_gateway/registry/tool_registry.py +12 -9
  539. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +4 -4
  540. claude_mpm/services/mcp_gateway/server/stdio_server.py +9 -15
  541. claude_mpm/services/mcp_gateway/tools/__init__.py +14 -2
  542. claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
  543. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +10 -9
  544. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +654 -0
  545. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +36 -34
  546. claude_mpm/services/mcp_gateway/tools/hello_world.py +8 -8
  547. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +551 -0
  548. claude_mpm/services/mcp_gateway/utils/__init__.py +14 -0
  549. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +160 -0
  550. claude_mpm/services/mcp_gateway/utils/update_preferences.py +170 -0
  551. claude_mpm/services/mcp_service_verifier.py +729 -0
  552. claude_mpm/services/memory/builder.py +9 -8
  553. claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
  554. claude_mpm/services/memory/cache/simple_cache.py +2 -2
  555. claude_mpm/services/memory/failure_tracker.py +578 -0
  556. claude_mpm/services/memory/indexed_memory.py +8 -8
  557. claude_mpm/services/memory/optimizer.py +8 -9
  558. claude_mpm/services/memory/router.py +3 -3
  559. claude_mpm/services/memory_hook_service.py +165 -4
  560. claude_mpm/services/model/__init__.py +147 -0
  561. claude_mpm/services/model/base_provider.py +365 -0
  562. claude_mpm/services/model/claude_provider.py +412 -0
  563. claude_mpm/services/model/model_router.py +453 -0
  564. claude_mpm/services/model/ollama_provider.py +415 -0
  565. claude_mpm/services/monitor/__init__.py +20 -0
  566. claude_mpm/services/monitor/daemon.py +671 -0
  567. claude_mpm/services/monitor/daemon_manager.py +963 -0
  568. claude_mpm/services/monitor/event_emitter.py +350 -0
  569. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  570. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  571. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  572. claude_mpm/services/monitor/handlers/file.py +264 -0
  573. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  574. claude_mpm/services/monitor/management/__init__.py +18 -0
  575. claude_mpm/services/monitor/management/health.py +124 -0
  576. claude_mpm/services/monitor/management/lifecycle.py +724 -0
  577. claude_mpm/services/monitor/server.py +817 -0
  578. claude_mpm/services/monitor_build_service.py +2 -2
  579. claude_mpm/services/native_agent_converter.py +356 -0
  580. claude_mpm/services/orphan_detection.py +786 -0
  581. claude_mpm/services/port_manager.py +2 -2
  582. claude_mpm/services/project/__init__.py +23 -0
  583. claude_mpm/services/project/analyzer.py +3 -3
  584. claude_mpm/services/project/architecture_analyzer.py +5 -5
  585. claude_mpm/services/project/archive_manager.py +1045 -0
  586. claude_mpm/services/project/dependency_analyzer.py +4 -4
  587. claude_mpm/services/project/detection_strategies.py +719 -0
  588. claude_mpm/services/project/documentation_manager.py +553 -0
  589. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  590. claude_mpm/services/project/metrics_collector.py +4 -4
  591. claude_mpm/services/project/project_organizer.py +1005 -0
  592. claude_mpm/services/project/registry.py +13 -7
  593. claude_mpm/services/project/toolchain_analyzer.py +581 -0
  594. claude_mpm/services/project_port_allocator.py +596 -0
  595. claude_mpm/services/response_tracker.py +21 -10
  596. claude_mpm/services/runner_configuration_service.py +1 -0
  597. claude_mpm/services/self_upgrade_service.py +500 -0
  598. claude_mpm/services/session_management_service.py +7 -5
  599. claude_mpm/services/session_manager.py +380 -0
  600. claude_mpm/services/shared/__init__.py +2 -1
  601. claude_mpm/services/shared/async_service_base.py +16 -27
  602. claude_mpm/services/shared/config_service_base.py +17 -14
  603. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  604. claude_mpm/services/shared/service_factory.py +8 -5
  605. claude_mpm/services/socketio/client_proxy.py +60 -5
  606. claude_mpm/services/socketio/dashboard_server.py +361 -0
  607. claude_mpm/services/socketio/event_normalizer.py +10 -6
  608. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  609. claude_mpm/services/socketio/handlers/base.py +2 -2
  610. claude_mpm/services/socketio/handlers/code_analysis.py +90 -27
  611. claude_mpm/services/socketio/handlers/connection.py +21 -40
  612. claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
  613. claude_mpm/services/socketio/handlers/file.py +46 -10
  614. claude_mpm/services/socketio/handlers/git.py +8 -8
  615. claude_mpm/services/socketio/handlers/hook.py +29 -17
  616. claude_mpm/services/socketio/handlers/registry.py +4 -2
  617. claude_mpm/services/socketio/monitor_client.py +364 -0
  618. claude_mpm/services/socketio/server/broadcaster.py +9 -7
  619. claude_mpm/services/socketio/server/connection_manager.py +2 -2
  620. claude_mpm/services/socketio/server/core.py +141 -4
  621. claude_mpm/services/socketio/server/eventbus_integration.py +20 -14
  622. claude_mpm/services/socketio/server/main.py +23 -21
  623. claude_mpm/services/socketio_client_manager.py +4 -4
  624. claude_mpm/services/subprocess_launcher_service.py +19 -15
  625. claude_mpm/services/system_instructions_service.py +2 -2
  626. claude_mpm/services/ticket_services/formatter_service.py +1 -1
  627. claude_mpm/services/ticket_services/validation_service.py +5 -5
  628. claude_mpm/services/unified/__init__.py +65 -0
  629. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  630. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  631. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  632. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +903 -0
  633. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +746 -0
  634. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  635. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  636. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  637. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  638. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  639. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  640. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  641. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  642. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  643. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  644. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  645. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  646. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  647. claude_mpm/services/unified/deployment_strategies/vercel.py +475 -0
  648. claude_mpm/services/unified/interfaces.py +475 -0
  649. claude_mpm/services/unified/migration.py +509 -0
  650. claude_mpm/services/unified/strategies.py +534 -0
  651. claude_mpm/services/unified/unified_analyzer.py +542 -0
  652. claude_mpm/services/unified/unified_config.py +691 -0
  653. claude_mpm/services/unified/unified_deployment.py +470 -0
  654. claude_mpm/services/utility_service.py +6 -3
  655. claude_mpm/services/version_control/branch_strategy.py +2 -2
  656. claude_mpm/services/version_control/conflict_resolution.py +8 -4
  657. claude_mpm/services/version_control/git_operations.py +26 -24
  658. claude_mpm/services/version_control/semantic_versioning.py +14 -14
  659. claude_mpm/services/version_control/version_parser.py +14 -11
  660. claude_mpm/services/version_service.py +104 -1
  661. claude_mpm/skills/__init__.py +42 -0
  662. claude_mpm/skills/agent_skills_injector.py +324 -0
  663. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  664. claude_mpm/skills/bundled/__init__.py +6 -0
  665. claude_mpm/skills/bundled/api-documentation.md +393 -0
  666. claude_mpm/skills/bundled/async-testing.md +571 -0
  667. claude_mpm/skills/bundled/code-review.md +143 -0
  668. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  669. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  670. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  671. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  672. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  673. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  674. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  675. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  676. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  677. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  678. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  679. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  680. claude_mpm/skills/bundled/database-migration.md +199 -0
  681. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  682. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  683. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  684. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  685. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  686. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  687. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  688. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  689. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  690. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  691. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  692. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  693. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  694. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  695. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  696. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  697. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  698. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  699. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  700. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  701. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  702. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  703. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  704. claude_mpm/skills/bundled/git-workflow.md +414 -0
  705. claude_mpm/skills/bundled/imagemagick.md +204 -0
  706. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  707. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  708. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  709. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  710. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  711. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  712. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  713. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  714. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  715. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  716. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  717. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  718. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  719. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  720. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  721. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  722. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  723. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  724. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  725. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  726. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  727. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  728. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  729. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  730. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  731. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  732. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  733. claude_mpm/skills/bundled/pdf.md +141 -0
  734. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  735. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  736. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  737. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  738. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  739. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  740. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  741. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  742. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  743. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  744. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  745. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  746. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  747. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  748. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  749. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  750. claude_mpm/skills/bundled/security-scanning.md +327 -0
  751. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  752. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  753. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  754. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  755. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  756. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  757. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  758. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  759. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  760. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  761. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  762. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  763. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  764. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  765. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  766. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  767. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  768. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  769. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  770. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  771. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  772. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  773. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  774. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  775. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  776. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  777. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  778. claude_mpm/skills/bundled/xlsx.md +157 -0
  779. claude_mpm/skills/registry.py +286 -0
  780. claude_mpm/skills/skill_manager.py +310 -0
  781. claude_mpm/skills/skills_registry.py +348 -0
  782. claude_mpm/skills/skills_service.py +739 -0
  783. claude_mpm/storage/state_storage.py +31 -31
  784. claude_mpm/tools/__main__.py +1 -1
  785. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  786. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  787. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  788. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  789. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  790. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  791. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  792. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  793. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  794. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  795. claude_mpm/tools/code_tree_builder.py +6 -6
  796. claude_mpm/tools/code_tree_events.py +14 -10
  797. claude_mpm/tools/socketio_debug.py +11 -11
  798. claude_mpm/utils/agent_dependency_loader.py +108 -27
  799. claude_mpm/utils/common.py +544 -0
  800. claude_mpm/utils/config_manager.py +12 -6
  801. claude_mpm/utils/database_connector.py +298 -0
  802. claude_mpm/utils/dependency_cache.py +2 -2
  803. claude_mpm/utils/dependency_strategies.py +15 -10
  804. claude_mpm/utils/display_helper.py +260 -0
  805. claude_mpm/utils/environment_context.py +4 -3
  806. claude_mpm/utils/error_handler.py +5 -3
  807. claude_mpm/utils/file_utils.py +13 -14
  808. claude_mpm/utils/git_analyzer.py +407 -0
  809. claude_mpm/utils/log_cleanup.py +627 -0
  810. claude_mpm/utils/path_operations.py +7 -4
  811. claude_mpm/utils/robust_installer.py +133 -24
  812. claude_mpm/utils/session_logging.py +2 -2
  813. claude_mpm/utils/subprocess_utils.py +9 -8
  814. claude_mpm/validation/agent_validator.py +6 -6
  815. claude_mpm/validation/frontmatter_validator.py +6 -6
  816. claude_mpm-4.24.0.dist-info/METADATA +675 -0
  817. claude_mpm-4.24.0.dist-info/RECORD +1018 -0
  818. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/entry_points.txt +1 -0
  819. claude_mpm/agents/INSTRUCTIONS.md +0 -261
  820. claude_mpm/agents/templates/agent-manager.md +0 -619
  821. claude_mpm/cli/commands/configure_tui.py +0 -1927
  822. claude_mpm/cli/commands/mpm_init.py +0 -594
  823. claude_mpm/cli/commands/socketio_monitor.py +0 -233
  824. claude_mpm/dashboard/static/css/code-tree.css +0 -1408
  825. claude_mpm/dashboard/static/js/components/code-tree.js +0 -3220
  826. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -480
  827. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  828. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1040
  829. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  830. claude_mpm/scripts/socketio_daemon_hardened.py +0 -937
  831. claude_mpm/scripts/socketio_daemon_wrapper.py +0 -78
  832. claude_mpm/scripts/socketio_server_manager.py +0 -349
  833. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  834. claude_mpm/services/cli/dashboard_launcher.py +0 -423
  835. claude_mpm/services/cli/socketio_manager.py +0 -537
  836. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +0 -286
  837. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
  838. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
  839. claude_mpm/services/project/analyzer_refactored.py +0 -450
  840. claude_mpm/tools/code_tree_analyzer.py +0 -1693
  841. claude_mpm-4.1.26.dist-info/METADATA +0 -332
  842. claude_mpm-4.1.26.dist-info/RECORD +0 -606
  843. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/WHEEL +0 -0
  844. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/licenses/LICENSE +0 -0
  845. {claude_mpm-4.1.26.dist-info → claude_mpm-4.24.0.dist-info}/top_level.txt +0 -0
@@ -12,148 +12,30 @@ DESIGN DECISIONS:
12
12
  """
13
13
 
14
14
  import json
15
- import os
16
- import sys
17
15
  from pathlib import Path
18
16
  from typing import Dict, List, Optional
19
17
 
20
- from rich.box import ROUNDED
21
- from rich.columns import Columns
22
18
  from rich.console import Console
23
- from rich.panel import Panel
24
19
  from rich.prompt import Confirm, Prompt
25
- from rich.syntax import Syntax
26
- from rich.table import Table
27
20
  from rich.text import Text
28
21
 
22
+ from ...core.config import Config
29
23
  from ...services.version_service import VersionService
30
24
  from ...utils.console import console as default_console
31
25
  from ..shared import BaseCommand, CommandResult
32
-
33
-
34
- class AgentConfig:
35
- """Simple agent configuration model."""
36
-
37
- def __init__(
38
- self, name: str, description: str = "", dependencies: Optional[List[str]] = None
39
- ):
40
- self.name = name
41
- self.description = description
42
- self.dependencies = dependencies or []
43
-
44
-
45
- class SimpleAgentManager:
46
- """Simple agent state management that discovers real agents from templates."""
47
-
48
- def __init__(self, config_dir: Path):
49
- self.config_dir = config_dir
50
- self.config_file = config_dir / "agent_states.json"
51
- self.config_dir.mkdir(parents=True, exist_ok=True)
52
- self._load_states()
53
- # Path to agent templates directory
54
- self.templates_dir = (
55
- Path(__file__).parent.parent.parent / "agents" / "templates"
56
- )
57
-
58
- def _load_states(self):
59
- """Load agent states from file."""
60
- if self.config_file.exists():
61
- with open(self.config_file) as f:
62
- self.states = json.load(f)
63
- else:
64
- self.states = {}
65
-
66
- def _save_states(self):
67
- """Save agent states to file."""
68
- with open(self.config_file, "w") as f:
69
- json.dump(self.states, f, indent=2)
70
-
71
- def is_agent_enabled(self, agent_name: str) -> bool:
72
- """Check if an agent is enabled."""
73
- return self.states.get(agent_name, {}).get("enabled", True)
74
-
75
- def set_agent_enabled(self, agent_name: str, enabled: bool):
76
- """Set agent enabled state."""
77
- if agent_name not in self.states:
78
- self.states[agent_name] = {}
79
- self.states[agent_name]["enabled"] = enabled
80
- self._save_states()
81
-
82
- def discover_agents(self) -> List[AgentConfig]:
83
- """Discover available agents from template JSON files."""
84
- agents = []
85
-
86
- # Scan templates directory for JSON files
87
- if not self.templates_dir.exists():
88
- # Fallback to a minimal set if templates dir doesn't exist
89
- return [
90
- AgentConfig("engineer", "Engineering agent (templates not found)", []),
91
- AgentConfig("research", "Research agent (templates not found)", []),
92
- ]
93
-
94
- try:
95
- # Read all JSON template files
96
- for template_file in sorted(self.templates_dir.glob("*.json")):
97
- # Skip backup files
98
- if "backup" in template_file.name.lower():
99
- continue
100
-
101
- try:
102
- with open(template_file) as f:
103
- template_data = json.load(f)
104
-
105
- # Extract agent information from template
106
- agent_id = template_data.get("agent_id", template_file.stem)
107
-
108
- # Get metadata for display info
109
- metadata = template_data.get("metadata", {})
110
- metadata.get("name", agent_id)
111
- description = metadata.get(
112
- "description", "No description available"
113
- )
114
-
115
- # Extract capabilities/tools as dependencies for display
116
- capabilities = template_data.get("capabilities", {})
117
- tools = capabilities.get("tools", [])
118
- # Show first few tools as "dependencies" for UI purposes
119
- display_tools = tools[:3] if len(tools) > 3 else tools
120
-
121
- # Normalize agent ID (remove -agent suffix if present, replace underscores)
122
- normalized_id = agent_id.replace("-agent", "").replace("_", "-")
123
-
124
- agents.append(
125
- AgentConfig(
126
- name=normalized_id,
127
- description=(
128
- description[:80] + "..."
129
- if len(description) > 80
130
- else description
131
- ),
132
- dependencies=display_tools,
133
- )
134
- )
135
-
136
- except (json.JSONDecodeError, KeyError):
137
- # Skip malformed templates
138
- continue
139
-
140
- except Exception as e:
141
- # If there's an error reading templates, return a minimal set
142
- return [
143
- AgentConfig("engineer", f"Error loading templates: {e!s}", []),
144
- AgentConfig("research", "Research agent", []),
145
- ]
146
-
147
- # Sort agents by name for consistent display
148
- agents.sort(key=lambda a: a.name)
149
-
150
- return (
151
- agents
152
- if agents
153
- else [
154
- AgentConfig("engineer", "No agents found in templates", []),
155
- ]
156
- )
26
+ from .agent_state_manager import SimpleAgentManager
27
+ from .configure_agent_display import AgentDisplay
28
+ from .configure_behavior_manager import BehaviorManager
29
+ from .configure_hook_manager import HookManager
30
+ from .configure_models import AgentConfig
31
+ from .configure_navigation import ConfigNavigation
32
+ from .configure_persistence import ConfigPersistence
33
+ from .configure_startup_manager import StartupManager
34
+ from .configure_template_editor import TemplateEditor
35
+ from .configure_validators import (
36
+ parse_id_selection,
37
+ validate_args as validate_configure_args,
38
+ )
157
39
 
158
40
 
159
41
  class ConfigureCommand(BaseCommand):
@@ -166,24 +48,88 @@ class ConfigureCommand(BaseCommand):
166
48
  self.current_scope = "project"
167
49
  self.project_dir = Path.cwd()
168
50
  self.agent_manager = None
51
+ self.hook_manager = HookManager(self.console)
52
+ self.behavior_manager = None # Initialized when scope is set
53
+ self._agent_display = None # Lazy-initialized
54
+ self._persistence = None # Lazy-initialized
55
+ self._navigation = None # Lazy-initialized
56
+ self._template_editor = None # Lazy-initialized
57
+ self._startup_manager = None # Lazy-initialized
169
58
 
170
59
  def validate_args(self, args) -> Optional[str]:
171
60
  """Validate command arguments."""
172
- # Check for conflicting direct navigation options
173
- nav_options = [
174
- getattr(args, "agents", False),
175
- getattr(args, "templates", False),
176
- getattr(args, "behaviors", False),
177
- getattr(args, "version_info", False),
178
- ]
179
- if sum(nav_options) > 1:
180
- return "Only one direct navigation option can be specified at a time"
181
-
182
- # Check for conflicting non-interactive options
183
- if getattr(args, "enable_agent", None) and getattr(args, "disable_agent", None):
184
- return "Cannot enable and disable agents at the same time"
185
-
186
- return None
61
+ return validate_configure_args(args)
62
+
63
+ @property
64
+ def agent_display(self) -> AgentDisplay:
65
+ """Lazy-initialize agent display handler."""
66
+ if self._agent_display is None:
67
+ if self.agent_manager is None:
68
+ raise RuntimeError(
69
+ "agent_manager must be initialized before agent_display"
70
+ )
71
+ self._agent_display = AgentDisplay(
72
+ self.console,
73
+ self.agent_manager,
74
+ self._get_agent_template_path,
75
+ self._display_header,
76
+ )
77
+ return self._agent_display
78
+
79
+ @property
80
+ def persistence(self) -> ConfigPersistence:
81
+ """Lazy-initialize persistence handler."""
82
+ if self._persistence is None:
83
+ # Note: agent_manager might be None for version_info calls
84
+ self._persistence = ConfigPersistence(
85
+ self.console,
86
+ self.version_service,
87
+ self.agent_manager, # Can be None for version operations
88
+ self._get_agent_template_path,
89
+ self._display_header,
90
+ self.current_scope,
91
+ self.project_dir,
92
+ )
93
+ return self._persistence
94
+
95
+ @property
96
+ def navigation(self) -> ConfigNavigation:
97
+ """Lazy-initialize navigation handler."""
98
+ if self._navigation is None:
99
+ self._navigation = ConfigNavigation(self.console, self.project_dir)
100
+ # Sync scope from main command
101
+ self._navigation.current_scope = self.current_scope
102
+ return self._navigation
103
+
104
+ @property
105
+ def template_editor(self) -> TemplateEditor:
106
+ """Lazy-initialize template editor."""
107
+ if self._template_editor is None:
108
+ if self.agent_manager is None:
109
+ raise RuntimeError(
110
+ "agent_manager must be initialized before template_editor"
111
+ )
112
+ self._template_editor = TemplateEditor(
113
+ self.console, self.agent_manager, self.current_scope, self.project_dir
114
+ )
115
+ return self._template_editor
116
+
117
+ @property
118
+ def startup_manager(self) -> StartupManager:
119
+ """Lazy-initialize startup manager."""
120
+ if self._startup_manager is None:
121
+ if self.agent_manager is None:
122
+ raise RuntimeError(
123
+ "agent_manager must be initialized before startup_manager"
124
+ )
125
+ self._startup_manager = StartupManager(
126
+ self.agent_manager,
127
+ self.console,
128
+ self.current_scope,
129
+ self.project_dir,
130
+ self._display_header,
131
+ )
132
+ return self._startup_manager
187
133
 
188
134
  def run(self, args) -> CommandResult:
189
135
  """Execute the configure command."""
@@ -192,12 +138,15 @@ class ConfigureCommand(BaseCommand):
192
138
  if getattr(args, "project_dir", None):
193
139
  self.project_dir = Path(args.project_dir)
194
140
 
195
- # Initialize agent manager with appropriate config directory
141
+ # Initialize agent manager and behavior manager with appropriate config directory
196
142
  if self.current_scope == "project":
197
143
  config_dir = self.project_dir / ".claude-mpm"
198
144
  else:
199
145
  config_dir = Path.home() / ".claude-mpm"
200
146
  self.agent_manager = SimpleAgentManager(config_dir)
147
+ self.behavior_manager = BehaviorManager(
148
+ config_dir, self.current_scope, self.console
149
+ )
201
150
 
202
151
  # Disable colors if requested
203
152
  if getattr(args, "no_colors", False):
@@ -242,39 +191,15 @@ class ConfigureCommand(BaseCommand):
242
191
  if getattr(args, "behaviors", False):
243
192
  return self._run_behavior_management()
244
193
 
194
+ if getattr(args, "startup", False):
195
+ return self._run_startup_configuration()
196
+
245
197
  # Launch interactive TUI
246
198
  return self._run_interactive_tui(args)
247
199
 
248
200
  def _run_interactive_tui(self, args) -> CommandResult:
249
- """Run the main interactive TUI."""
250
- # Check if we can use the modern Textual TUI
251
- use_textual = getattr(args, "use_textual", True)
252
- force_rich = getattr(args, "force_rich", False)
253
-
254
- if use_textual and not force_rich:
255
- try:
256
- # Try to import and use Textual TUI
257
- from .configure_tui import can_use_tui, launch_tui
258
-
259
- if can_use_tui():
260
- self.console.print(
261
- "[cyan]Launching full-screen configuration interface...[/cyan]"
262
- )
263
- return launch_tui(self.current_scope, self.project_dir)
264
- # Fall back to Rich TUI if terminal doesn't support full-screen
265
- self.console.print(
266
- "[yellow]Terminal doesn't support full-screen mode. Using menu interface.[/yellow]"
267
- )
268
- except ImportError:
269
- # Textual not available, fall back to Rich
270
- self.console.print(
271
- "[yellow]Textual not installed. Using menu interface.[/yellow]"
272
- )
273
- self.console.print(
274
- "[dim]Install textual for a better experience: pip install textual[/dim]"
275
- )
276
-
277
- # Original Rich-based TUI
201
+ """Run the main interactive menu interface."""
202
+ # Rich-based menu interface
278
203
  try:
279
204
  self.console.clear()
280
205
 
@@ -286,13 +211,49 @@ class ConfigureCommand(BaseCommand):
286
211
  if choice == "1":
287
212
  self._manage_agents()
288
213
  elif choice == "2":
289
- self._edit_templates()
214
+ self._manage_skills()
290
215
  elif choice == "3":
291
- self._manage_behaviors()
216
+ self._edit_templates()
292
217
  elif choice == "4":
293
- self._switch_scope()
218
+ self._manage_behaviors()
294
219
  elif choice == "5":
220
+ # If user saves and wants to proceed to startup, exit the configurator
221
+ if self._manage_startup_configuration():
222
+ self.console.print(
223
+ "\n[green]Configuration saved. Exiting configurator...[/green]"
224
+ )
225
+ break
226
+ elif choice == "6":
227
+ self._switch_scope()
228
+ elif choice == "7":
295
229
  self._show_version_info_interactive()
230
+ elif choice == "l":
231
+ # Check for pending agent changes
232
+ if self.agent_manager and self.agent_manager.has_pending_changes():
233
+ should_save = Confirm.ask(
234
+ "[yellow]You have unsaved agent changes. Save them before launching?[/yellow]",
235
+ default=True,
236
+ )
237
+ if should_save:
238
+ self.agent_manager.commit_deferred_changes()
239
+ self.console.print("[green]✓ Agent changes saved[/green]")
240
+ else:
241
+ self.agent_manager.discard_deferred_changes()
242
+ self.console.print(
243
+ "[yellow]⚠ Agent changes discarded[/yellow]"
244
+ )
245
+
246
+ # Save all configuration
247
+ self.console.print("\n[cyan]Saving configuration...[/cyan]")
248
+ if self._save_all_configuration():
249
+ # Launch Claude MPM (this will replace the process if successful)
250
+ self._launch_claude_mpm()
251
+ # If execvp fails, we'll return here and break
252
+ break
253
+ self.console.print(
254
+ "[red]✗ Failed to save configuration. Not launching.[/red]"
255
+ )
256
+ Prompt.ask("\nPress Enter to continue")
296
257
  elif choice == "q":
297
258
  self.console.print(
298
259
  "\n[green]Configuration complete. Goodbye![/green]"
@@ -312,57 +273,15 @@ class ConfigureCommand(BaseCommand):
312
273
 
313
274
  def _display_header(self) -> None:
314
275
  """Display the TUI header."""
315
- self.console.clear()
316
-
317
- # Create header panel
318
- header_text = Text()
319
- header_text.append("Claude MPM ", style="bold cyan")
320
- header_text.append("Configuration Interface", style="bold white")
321
-
322
- scope_text = Text(f"Scope: {self.current_scope.upper()}", style="yellow")
323
- dir_text = Text(f"Directory: {self.project_dir}", style="dim")
324
-
325
- header_content = Columns([header_text], align="center")
326
- subtitle_content = f"{scope_text} | {dir_text}"
327
-
328
- header_panel = Panel(
329
- header_content,
330
- subtitle=subtitle_content,
331
- box=ROUNDED,
332
- style="blue",
333
- padding=(1, 2),
334
- )
335
-
336
- self.console.print(header_panel)
337
- self.console.print()
276
+ # Sync scope to navigation before display
277
+ self.navigation.current_scope = self.current_scope
278
+ self.navigation.display_header()
338
279
 
339
280
  def _show_main_menu(self) -> str:
340
281
  """Show the main menu and get user choice."""
341
- menu_items = [
342
- ("1", "Agent Management", "Enable/disable agents and customize settings"),
343
- ("2", "Template Editing", "Edit agent JSON templates"),
344
- ("3", "Behavior Files", "Manage identity and workflow configurations"),
345
- ("4", "Switch Scope", f"Current: {self.current_scope}"),
346
- ("5", "Version Info", "Display MPM and Claude versions"),
347
- ("q", "Quit", "Exit configuration interface"),
348
- ]
349
-
350
- table = Table(show_header=False, box=None, padding=(0, 2))
351
- table.add_column("Key", style="cyan", width=3)
352
- table.add_column("Option", style="bold white", width=20)
353
- table.add_column("Description", style="dim")
354
-
355
- for key, option, desc in menu_items:
356
- table.add_row(f"[{key}]", option, desc)
357
-
358
- menu_panel = Panel(
359
- table, title="[bold]Main Menu[/bold]", box=ROUNDED, style="green"
360
- )
361
-
362
- self.console.print(menu_panel)
363
- self.console.print()
364
-
365
- return Prompt.ask("[bold cyan]Select an option[/bold cyan]", default="q")
282
+ # Sync scope to navigation before display
283
+ self.navigation.current_scope = self.current_scope
284
+ return self.navigation.show_main_menu()
366
285
 
367
286
  def _manage_agents(self) -> None:
368
287
  """Agent management interface."""
@@ -376,22 +295,41 @@ class ConfigureCommand(BaseCommand):
376
295
 
377
296
  # Show agent menu
378
297
  self.console.print("\n[bold]Agent Management Options:[/bold]")
379
- self.console.print(" [cyan][e][/cyan] Enable an agent")
380
- self.console.print(" [cyan][d][/cyan] Disable an agent")
381
- self.console.print(" [cyan][c][/cyan] Customize agent template")
382
- self.console.print(" [cyan][v][/cyan] View agent details")
383
- self.console.print(" [cyan][r][/cyan] Reset agent to defaults")
384
- self.console.print(" [cyan][b][/cyan] Back to main menu")
298
+
299
+ # Use Text objects to properly display shortcuts with styling
300
+ text_t = Text(" ")
301
+ text_t.append("[t]", style="bold blue")
302
+ text_t.append(" Toggle agents (enable/disable multiple)")
303
+ self.console.print(text_t)
304
+
305
+ text_c = Text(" ")
306
+ text_c.append("[c]", style="bold blue")
307
+ text_c.append(" Customize agent template")
308
+ self.console.print(text_c)
309
+
310
+ text_v = Text(" ")
311
+ text_v.append("[v]", style="bold blue")
312
+ text_v.append(" View agent details")
313
+ self.console.print(text_v)
314
+
315
+ text_r = Text(" ")
316
+ text_r.append("[r]", style="bold blue")
317
+ text_r.append(" Reset agent to defaults")
318
+ self.console.print(text_r)
319
+
320
+ text_b = Text(" ")
321
+ text_b.append("[b]", style="bold blue")
322
+ text_b.append(" Back to main menu")
323
+ self.console.print(text_b)
324
+
385
325
  self.console.print()
386
326
 
387
- choice = Prompt.ask("[bold cyan]Select an option[/bold cyan]", default="b")
327
+ choice = Prompt.ask("[bold blue]Select an option[/bold blue]", default="b")
388
328
 
389
329
  if choice == "b":
390
330
  break
391
- if choice == "e":
392
- self._enable_agent_interactive(agents)
393
- elif choice == "d":
394
- self._disable_agent_interactive(agents)
331
+ if choice == "t":
332
+ self._toggle_agents_interactive(agents)
395
333
  elif choice == "c":
396
334
  self._customize_agent_template(agents)
397
335
  elif choice == "v":
@@ -404,679 +342,366 @@ class ConfigureCommand(BaseCommand):
404
342
 
405
343
  def _display_agents_table(self, agents: List[AgentConfig]) -> None:
406
344
  """Display a table of available agents."""
407
- table = Table(
408
- title=f"Available Agents ({len(agents)} total)",
409
- box=ROUNDED,
410
- show_lines=True,
411
- )
345
+ self.agent_display.display_agents_table(agents)
412
346
 
413
- table.add_column("ID", style="dim", width=3)
414
- table.add_column("Name", style="cyan", width=22)
415
- table.add_column("Status", width=12)
416
- table.add_column("Description", style="white", width=45)
417
- table.add_column("Model/Tools", style="dim", width=20)
418
-
419
- for idx, agent in enumerate(agents, 1):
420
- # Check if agent is enabled
421
- is_enabled = self.agent_manager.is_agent_enabled(agent.name)
422
- status = (
423
- "[green]✓ Enabled[/green]" if is_enabled else "[red]✗ Disabled[/red]"
424
- )
425
-
426
- # Format tools/dependencies - show first 2 tools
427
- tools_display = ""
428
- if agent.dependencies:
429
- if len(agent.dependencies) > 2:
430
- tools_display = f"{', '.join(agent.dependencies[:2])}..."
431
- else:
432
- tools_display = ", ".join(agent.dependencies)
433
- else:
434
- # Try to get model from template
435
- try:
436
- template_path = self._get_agent_template_path(agent.name)
437
- if template_path.exists():
438
- with open(template_path) as f:
439
- template = json.load(f)
440
- model = template.get("capabilities", {}).get("model", "default")
441
- tools_display = f"Model: {model}"
442
- else:
443
- tools_display = "Default"
444
- except:
445
- tools_display = "Default"
446
-
447
- # Truncate description for table display
448
- desc_display = (
449
- agent.description[:42] + "..."
450
- if len(agent.description) > 42
451
- else agent.description
452
- )
347
+ def _display_agents_with_pending_states(self, agents: List[AgentConfig]) -> None:
348
+ """Display agents table with pending state indicators."""
349
+ self.agent_display.display_agents_with_pending_states(agents)
453
350
 
454
- table.add_row(str(idx), agent.name, status, desc_display, tools_display)
351
+ def _toggle_agents_interactive(self, agents: List[AgentConfig]) -> None:
352
+ """Interactive multi-agent enable/disable with batch save."""
455
353
 
456
- self.console.print(table)
354
+ # Initialize pending states from current states
355
+ for agent in agents:
356
+ current_state = self.agent_manager.is_agent_enabled(agent.name)
357
+ self.agent_manager.set_agent_enabled_deferred(agent.name, current_state)
457
358
 
458
- def _enable_agent_interactive(self, agents: List[AgentConfig]) -> None:
459
- """Interactive agent enabling."""
460
- agent_id = Prompt.ask("Enter agent ID to enable (or 'all' for all agents)")
359
+ while True:
360
+ # Display table with pending states
361
+ self._display_agents_with_pending_states(agents)
362
+
363
+ # Show menu
364
+ self.console.print("\n[bold]Toggle Agent Status:[/bold]")
365
+ text_toggle = Text(" ")
366
+ text_toggle.append("[t]", style="bold blue")
367
+ text_toggle.append(" Enter agent IDs to toggle (e.g., '1,3,5' or '1-4')")
368
+ self.console.print(text_toggle)
369
+
370
+ text_all = Text(" ")
371
+ text_all.append("[a]", style="bold blue")
372
+ text_all.append(" Enable all agents")
373
+ self.console.print(text_all)
374
+
375
+ text_none = Text(" ")
376
+ text_none.append("[n]", style="bold blue")
377
+ text_none.append(" Disable all agents")
378
+ self.console.print(text_none)
379
+
380
+ text_save = Text(" ")
381
+ text_save.append("[s]", style="bold green")
382
+ text_save.append(" Save changes and return")
383
+ self.console.print(text_save)
384
+
385
+ text_cancel = Text(" ")
386
+ text_cancel.append("[c]", style="bold magenta")
387
+ text_cancel.append(" Cancel (discard changes)")
388
+ self.console.print(text_cancel)
389
+
390
+ choice = (
391
+ Prompt.ask("[bold blue]Select an option[/bold blue]", default="s")
392
+ .strip()
393
+ .lower()
394
+ )
461
395
 
462
- if agent_id.lower() == "all":
463
- if Confirm.ask("[yellow]Enable ALL agents?[/yellow]"):
464
- for agent in agents:
465
- self.agent_manager.set_agent_enabled(agent.name, True)
466
- self.console.print("[green]All agents enabled successfully![/green]")
467
- else:
468
- try:
469
- idx = int(agent_id) - 1
470
- if 0 <= idx < len(agents):
471
- agent = agents[idx]
472
- self.agent_manager.set_agent_enabled(agent.name, True)
473
- self.console.print(
474
- f"[green]Agent '{agent.name}' enabled successfully![/green]"
475
- )
396
+ if choice == "s":
397
+ if self.agent_manager.has_pending_changes():
398
+ self.agent_manager.commit_deferred_changes()
399
+ self.console.print("[green]✓ Changes saved successfully![/green]")
476
400
  else:
477
- self.console.print("[red]Invalid agent ID.[/red]")
478
- except ValueError:
479
- self.console.print("[red]Invalid input. Please enter a number.[/red]")
480
-
481
- Prompt.ask("Press Enter to continue")
482
-
483
- def _disable_agent_interactive(self, agents: List[AgentConfig]) -> None:
484
- """Interactive agent disabling."""
485
- agent_id = Prompt.ask("Enter agent ID to disable (or 'all' for all agents)")
486
-
487
- if agent_id.lower() == "all":
488
- if Confirm.ask("[yellow]Disable ALL agents?[/yellow]"):
401
+ self.console.print("[yellow]No changes to save.[/yellow]")
402
+ Prompt.ask("Press Enter to continue")
403
+ break
404
+ if choice == "c":
405
+ self.agent_manager.discard_deferred_changes()
406
+ self.console.print("[yellow]Changes discarded.[/yellow]")
407
+ Prompt.ask("Press Enter to continue")
408
+ break
409
+ if choice == "a":
489
410
  for agent in agents:
490
- self.agent_manager.set_agent_enabled(agent.name, False)
491
- self.console.print("[green]All agents disabled successfully![/green]")
492
- else:
493
- try:
494
- idx = int(agent_id) - 1
495
- if 0 <= idx < len(agents):
496
- agent = agents[idx]
497
- self.agent_manager.set_agent_enabled(agent.name, False)
498
- self.console.print(
499
- f"[green]Agent '{agent.name}' disabled successfully![/green]"
500
- )
501
- else:
502
- self.console.print("[red]Invalid agent ID.[/red]")
503
- except ValueError:
504
- self.console.print("[red]Invalid input. Please enter a number.[/red]")
505
-
506
- Prompt.ask("Press Enter to continue")
411
+ self.agent_manager.set_agent_enabled_deferred(agent.name, True)
412
+ elif choice == "n":
413
+ for agent in agents:
414
+ self.agent_manager.set_agent_enabled_deferred(agent.name, False)
415
+ elif choice == "t" or choice.replace(",", "").replace("-", "").isdigit():
416
+ selected_ids = self._parse_id_selection(
417
+ choice if choice != "t" else Prompt.ask("Enter IDs"), len(agents)
418
+ )
419
+ for idx in selected_ids:
420
+ if 1 <= idx <= len(agents):
421
+ agent = agents[idx - 1]
422
+ current = self.agent_manager.get_pending_state(agent.name)
423
+ self.agent_manager.set_agent_enabled_deferred(
424
+ agent.name, not current
425
+ )
507
426
 
508
427
  def _customize_agent_template(self, agents: List[AgentConfig]) -> None:
509
428
  """Customize agent JSON template."""
510
- agent_id = Prompt.ask("Enter agent ID to customize")
511
-
512
- try:
513
- idx = int(agent_id) - 1
514
- if 0 <= idx < len(agents):
515
- agent = agents[idx]
516
- self._edit_agent_template(agent)
517
- else:
518
- self.console.print("[red]Invalid agent ID.[/red]")
519
- Prompt.ask("Press Enter to continue")
520
- except ValueError:
521
- self.console.print("[red]Invalid input. Please enter a number.[/red]")
522
- Prompt.ask("Press Enter to continue")
429
+ self.template_editor.customize_agent_template(agents)
523
430
 
524
431
  def _edit_agent_template(self, agent: AgentConfig) -> None:
525
432
  """Edit an agent's JSON template."""
526
- self.console.clear()
527
- self.console.print(f"[bold]Editing template for: {agent.name}[/bold]\n")
528
-
529
- # Get current template
530
- template_path = self._get_agent_template_path(agent.name)
531
-
532
- if template_path.exists():
533
- with open(template_path) as f:
534
- template = json.load(f)
535
- is_system = str(template_path).startswith(
536
- str(self.agent_manager.templates_dir)
537
- )
538
- else:
539
- # Create a minimal template structure based on system templates
540
- template = {
541
- "schema_version": "1.2.0",
542
- "agent_id": agent.name,
543
- "agent_version": "1.0.0",
544
- "agent_type": agent.name.replace("-", "_"),
545
- "metadata": {
546
- "name": agent.name.replace("-", " ").title() + " Agent",
547
- "description": agent.description,
548
- "tags": [agent.name],
549
- "author": "Custom",
550
- "created_at": "",
551
- "updated_at": "",
552
- },
553
- "capabilities": {
554
- "model": "opus",
555
- "tools": (
556
- agent.dependencies
557
- if agent.dependencies
558
- else ["Read", "Write", "Edit", "Bash"]
559
- ),
560
- },
561
- "instructions": {
562
- "base_template": "BASE_AGENT_TEMPLATE.md",
563
- "custom_instructions": "",
564
- },
565
- }
566
- is_system = False
567
-
568
- # Display current template
569
- if is_system:
570
- self.console.print(
571
- "[yellow]Viewing SYSTEM template (read-only). Customization will create a local copy.[/yellow]\n"
572
- )
573
-
574
- self.console.print("[bold]Current Template:[/bold]")
575
- # Truncate for display if too large
576
- display_template = template.copy()
577
- if (
578
- "instructions" in display_template
579
- and isinstance(display_template["instructions"], dict)
580
- and (
581
- "custom_instructions" in display_template["instructions"]
582
- and len(str(display_template["instructions"]["custom_instructions"]))
583
- > 200
584
- )
585
- ):
586
- display_template["instructions"]["custom_instructions"] = (
587
- display_template["instructions"]["custom_instructions"][:200] + "..."
588
- )
589
-
590
- json_str = json.dumps(display_template, indent=2)
591
- # Limit display to first 50 lines for readability
592
- lines = json_str.split("\n")
593
- if len(lines) > 50:
594
- json_str = "\n".join(lines[:50]) + "\n... (truncated for display)"
595
-
596
- syntax = Syntax(json_str, "json", theme="monokai", line_numbers=True)
597
- self.console.print(syntax)
598
- self.console.print()
599
-
600
- # Editing options
601
- self.console.print("[bold]Editing Options:[/bold]")
602
- if not is_system:
603
- self.console.print(" [cyan][1][/cyan] Edit in external editor")
604
- self.console.print(" [cyan][2][/cyan] Add/modify a field")
605
- self.console.print(" [cyan][3][/cyan] Remove a field")
606
- self.console.print(" [cyan][4][/cyan] Reset to defaults")
607
- else:
608
- self.console.print(" [cyan][1][/cyan] Create customized copy")
609
- self.console.print(" [cyan][2][/cyan] View full template")
610
- self.console.print(" [cyan][b][/cyan] Back")
611
- self.console.print()
612
-
613
- choice = Prompt.ask("[bold cyan]Select an option[/bold cyan]", default="b")
614
-
615
- if is_system:
616
- if choice == "1":
617
- # Create a customized copy
618
- self._create_custom_template_copy(agent, template)
619
- elif choice == "2":
620
- # View full template
621
- self._view_full_template(template)
622
- elif choice == "1":
623
- self._edit_in_external_editor(template_path, template)
624
- elif choice == "2":
625
- self._modify_template_field(template, template_path)
626
- elif choice == "3":
627
- self._remove_template_field(template, template_path)
628
- elif choice == "4":
629
- self._reset_template(agent, template_path)
630
-
631
- if choice != "b":
632
- Prompt.ask("Press Enter to continue")
433
+ self.template_editor.edit_agent_template(agent)
633
434
 
634
435
  def _get_agent_template_path(self, agent_name: str) -> Path:
635
436
  """Get the path to an agent's template file."""
636
- # First check for custom template in project/user config
637
- if self.current_scope == "project":
638
- config_dir = self.project_dir / ".claude-mpm" / "agents"
639
- else:
640
- config_dir = Path.home() / ".claude-mpm" / "agents"
641
-
642
- config_dir.mkdir(parents=True, exist_ok=True)
643
- custom_template = config_dir / f"{agent_name}.json"
644
-
645
- # If custom template exists, return it
646
- if custom_template.exists():
647
- return custom_template
648
-
649
- # Otherwise, look for the system template
650
- # Handle various naming conventions
651
- possible_names = [
652
- f"{agent_name}.json",
653
- f"{agent_name.replace('-', '_')}.json",
654
- f"{agent_name}-agent.json",
655
- f"{agent_name.replace('-', '_')}_agent.json",
656
- ]
657
-
658
- for name in possible_names:
659
- system_template = self.agent_manager.templates_dir / name
660
- if system_template.exists():
661
- return system_template
662
-
663
- # Return the custom template path for new templates
664
- return custom_template
437
+ return self.template_editor.get_agent_template_path(agent_name)
665
438
 
666
439
  def _edit_in_external_editor(self, template_path: Path, template: Dict) -> None:
667
440
  """Open template in external editor."""
668
- import subprocess
669
- import tempfile
670
-
671
- # Write current template to temp file
672
- with tempfile.NamedTemporaryFile(mode="w", suffix=".json", delete=False) as f:
673
- json.dump(template, f, indent=2)
674
- temp_path = f.name
675
-
676
- # Get editor from environment
677
- editor = os.environ.get("EDITOR", "nano")
678
-
679
- try:
680
- # Open in editor
681
- subprocess.call([editor, temp_path])
682
-
683
- # Read back the edited content
684
- with open(temp_path) as f:
685
- new_template = json.load(f)
686
-
687
- # Save to actual template path
688
- with open(template_path, "w") as f:
689
- json.dump(new_template, f, indent=2)
690
-
691
- self.console.print("[green]Template updated successfully![/green]")
692
-
693
- except Exception as e:
694
- self.console.print(f"[red]Error editing template: {e}[/red]")
695
- finally:
696
- # Clean up temp file
697
- Path(temp_path).unlink(missing_ok=True)
441
+ self.template_editor.edit_in_external_editor(template_path, template)
698
442
 
699
443
  def _modify_template_field(self, template: Dict, template_path: Path) -> None:
700
444
  """Add or modify a field in the template."""
701
- field_name = Prompt.ask(
702
- "Enter field name (use dot notation for nested, e.g., 'config.timeout')"
703
- )
704
- field_value = Prompt.ask("Enter field value (JSON format)")
705
-
706
- try:
707
- # Parse the value as JSON
708
- value = json.loads(field_value)
709
-
710
- # Navigate to the field location
711
- parts = field_name.split(".")
712
- current = template
713
-
714
- for part in parts[:-1]:
715
- if part not in current:
716
- current[part] = {}
717
- current = current[part]
718
-
719
- # Set the value
720
- current[parts[-1]] = value
721
-
722
- # Save the template
723
- with open(template_path, "w") as f:
724
- json.dump(template, f, indent=2)
725
-
726
- self.console.print(
727
- f"[green]Field '{field_name}' updated successfully![/green]"
728
- )
729
-
730
- except json.JSONDecodeError:
731
- self.console.print("[red]Invalid JSON value. Please try again.[/red]")
732
- except Exception as e:
733
- self.console.print(f"[red]Error updating field: {e}[/red]")
445
+ self.template_editor.modify_template_field(template, template_path)
734
446
 
735
447
  def _remove_template_field(self, template: Dict, template_path: Path) -> None:
736
448
  """Remove a field from the template."""
737
- field_name = Prompt.ask(
738
- "Enter field name to remove (use dot notation for nested)"
739
- )
740
-
741
- try:
742
- # Navigate to the field location
743
- parts = field_name.split(".")
744
- current = template
745
-
746
- for part in parts[:-1]:
747
- if part not in current:
748
- raise KeyError(f"Field '{field_name}' not found")
749
- current = current[part]
750
-
751
- # Remove the field
752
- if parts[-1] in current:
753
- del current[parts[-1]]
754
-
755
- # Save the template
756
- with open(template_path, "w") as f:
757
- json.dump(template, f, indent=2)
758
-
759
- self.console.print(
760
- f"[green]Field '{field_name}' removed successfully![/green]"
761
- )
762
- else:
763
- self.console.print(f"[red]Field '{field_name}' not found.[/red]")
764
-
765
- except Exception as e:
766
- self.console.print(f"[red]Error removing field: {e}[/red]")
449
+ self.template_editor.remove_template_field(template, template_path)
767
450
 
768
451
  def _reset_template(self, agent: AgentConfig, template_path: Path) -> None:
769
452
  """Reset template to defaults."""
770
- if Confirm.ask(f"[yellow]Reset '{agent.name}' template to defaults?[/yellow]"):
771
- # Remove custom template file
772
- template_path.unlink(missing_ok=True)
773
- self.console.print(
774
- f"[green]Template for '{agent.name}' reset to defaults![/green]"
775
- )
453
+ self.template_editor.reset_template(agent, template_path)
776
454
 
777
455
  def _create_custom_template_copy(self, agent: AgentConfig, template: Dict) -> None:
778
456
  """Create a customized copy of a system template."""
779
- if self.current_scope == "project":
780
- config_dir = self.project_dir / ".claude-mpm" / "agents"
781
- else:
782
- config_dir = Path.home() / ".claude-mpm" / "agents"
457
+ self.template_editor.create_custom_template_copy(agent, template)
783
458
 
784
- config_dir.mkdir(parents=True, exist_ok=True)
785
- custom_path = config_dir / f"{agent.name}.json"
459
+ def _view_full_template(self, template: Dict) -> None:
460
+ """View the full template without truncation."""
461
+ self.template_editor.view_full_template(template)
786
462
 
787
- if custom_path.exists() and not Confirm.ask(
788
- "[yellow]Custom template already exists. Overwrite?[/yellow]"
789
- ):
790
- return
463
+ def _reset_agent_defaults(self, agents: List[AgentConfig]) -> None:
464
+ """Reset an agent to default enabled state and remove custom template."""
465
+ self.template_editor.reset_agent_defaults(agents)
791
466
 
792
- # Save the template copy
793
- with open(custom_path, "w") as f:
794
- json.dump(template, f, indent=2)
467
+ def _edit_templates(self) -> None:
468
+ """Template editing interface."""
469
+ self.template_editor.edit_templates_interface()
795
470
 
796
- self.console.print(f"[green]Created custom template at: {custom_path}[/green]")
797
- self.console.print("[green]You can now edit this template.[/green]")
471
+ def _manage_behaviors(self) -> None:
472
+ """Behavior file management interface."""
473
+ # Note: BehaviorManager handles its own loop and clears screen
474
+ # but doesn't display our header. We'll need to update BehaviorManager
475
+ # to accept a header callback in the future. For now, just delegate.
476
+ self.behavior_manager.manage_behaviors()
798
477
 
799
- def _view_full_template(self, template: Dict) -> None:
800
- """View the full template without truncation."""
801
- self.console.clear()
802
- self.console.print("[bold]Full Template View:[/bold]\n")
478
+ def _manage_skills(self) -> None:
479
+ """Skills management interface."""
480
+ from ...cli.interactive.skills_wizard import SkillsWizard
481
+ from ...skills.skill_manager import get_manager
803
482
 
804
- json_str = json.dumps(template, indent=2)
805
- syntax = Syntax(json_str, "json", theme="monokai", line_numbers=True)
483
+ wizard = SkillsWizard()
484
+ manager = get_manager()
806
485
 
807
- # Use pager for long content
486
+ while True:
487
+ self.console.clear()
488
+ self._display_header()
808
489
 
809
- with self.console.pager():
810
- self.console.print(syntax)
490
+ self.console.print("\n[bold]Skills Management Options:[/bold]\n")
491
+ self.console.print(" [1] View Available Skills")
492
+ self.console.print(" [2] Configure Skills for Agents")
493
+ self.console.print(" [3] View Current Skill Mappings")
494
+ self.console.print(" [4] Auto-Link Skills to Agents")
495
+ self.console.print(" [b] Back to Main Menu")
496
+ self.console.print()
811
497
 
812
- def _view_agent_details(self, agents: List[AgentConfig]) -> None:
813
- """View detailed information about an agent."""
814
- agent_id = Prompt.ask("Enter agent ID to view")
498
+ choice = Prompt.ask("[bold blue]Select an option[/bold blue]", default="b")
815
499
 
816
- try:
817
- idx = int(agent_id) - 1
818
- if 0 <= idx < len(agents):
819
- agent = agents[idx]
500
+ if choice == "1":
501
+ # View available skills
502
+ self.console.clear()
503
+ self._display_header()
504
+ wizard.list_available_skills()
505
+ Prompt.ask("\nPress Enter to continue")
820
506
 
507
+ elif choice == "2":
508
+ # Configure skills interactively
821
509
  self.console.clear()
822
510
  self._display_header()
823
511
 
824
- # Try to load full template for more details
825
- template_path = self._get_agent_template_path(agent.name)
826
- extra_info = ""
512
+ # Get list of enabled agents
513
+ agents = self.agent_manager.discover_agents()
514
+ enabled_agents = [
515
+ a.name
516
+ for a in agents
517
+ if self.agent_manager.get_pending_state(a.name)
518
+ ]
827
519
 
828
- if template_path.exists():
829
- try:
830
- with open(template_path) as f:
831
- template = json.load(f)
520
+ if not enabled_agents:
521
+ self.console.print(
522
+ "[yellow]No agents are currently enabled.[/yellow]"
523
+ )
524
+ self.console.print(
525
+ "Please enable agents first in Agent Management."
526
+ )
527
+ Prompt.ask("\nPress Enter to continue")
528
+ continue
832
529
 
833
- # Extract additional information
834
- metadata = template.get("metadata", {})
835
- capabilities = template.get("capabilities", {})
530
+ # Run skills wizard
531
+ success, mapping = wizard.run_interactive_selection(enabled_agents)
836
532
 
837
- # Get full description if available
838
- full_desc = metadata.get("description", agent.description)
533
+ if success:
534
+ # Save the configuration
535
+ manager.save_mappings_to_config()
536
+ self.console.print("\n[green]✓ Skills configuration saved![/green]")
537
+ else:
538
+ self.console.print(
539
+ "\n[yellow]Skills configuration cancelled.[/yellow]"
540
+ )
839
541
 
840
- # Get model and tools
841
- model = capabilities.get("model", "default")
842
- tools = capabilities.get("tools", [])
542
+ Prompt.ask("\nPress Enter to continue")
843
543
 
844
- # Get tags
845
- tags = metadata.get("tags", [])
544
+ elif choice == "3":
545
+ # View current mappings
546
+ self.console.clear()
547
+ self._display_header()
846
548
 
847
- # Get version info
848
- agent_version = template.get("agent_version", "N/A")
849
- schema_version = template.get("schema_version", "N/A")
549
+ self.console.print("\n[bold]Current Skill Mappings:[/bold]\n")
850
550
 
851
- extra_info = f"""
852
- [bold]Full Description:[/bold]
853
- {full_desc}
551
+ mappings = manager.list_agent_skill_mappings()
552
+ if not mappings:
553
+ self.console.print("[dim]No skill mappings configured yet.[/dim]")
554
+ else:
555
+ from rich.table import Table
854
556
 
855
- [bold]Model:[/bold] {model}
856
- [bold]Agent Version:[/bold] {agent_version}
857
- [bold]Schema Version:[/bold] {schema_version}
858
- [bold]Tags:[/bold] {', '.join(tags) if tags else 'None'}
859
- [bold]Tools:[/bold] {', '.join(tools[:5]) if tools else 'None'}{'...' if len(tools) > 5 else ''}
860
- """
861
- except:
862
- pass
863
-
864
- # Create detail panel
865
- detail_text = f"""
866
- [bold]Name:[/bold] {agent.name}
867
- [bold]Status:[/bold] {'[green]Enabled[/green]' if self.agent_manager.is_agent_enabled(agent.name) else '[red]Disabled[/red]'}
868
- [bold]Template Path:[/bold] {template_path}
869
- [bold]Is System Template:[/bold] {'Yes' if str(template_path).startswith(str(self.agent_manager.templates_dir)) else 'No (Custom)'}
870
- {extra_info}
871
- """
872
-
873
- panel = Panel(
874
- detail_text.strip(),
875
- title=f"[bold]{agent.name} Details[/bold]",
876
- box=ROUNDED,
877
- style="cyan",
878
- )
557
+ table = Table(show_header=True, header_style="bold cyan")
558
+ table.add_column("Agent", style="yellow")
559
+ table.add_column("Skills", style="green")
879
560
 
880
- self.console.print(panel)
561
+ for agent_id, skills in mappings.items():
562
+ skills_str = (
563
+ ", ".join(skills) if skills else "[dim](none)[/dim]"
564
+ )
565
+ table.add_row(agent_id, skills_str)
881
566
 
882
- else:
883
- self.console.print("[red]Invalid agent ID.[/red]")
567
+ self.console.print(table)
884
568
 
885
- except ValueError:
886
- self.console.print("[red]Invalid input. Please enter a number.[/red]")
569
+ Prompt.ask("\nPress Enter to continue")
887
570
 
888
- Prompt.ask("\nPress Enter to continue")
571
+ elif choice == "4":
572
+ # Auto-link skills
573
+ self.console.clear()
574
+ self._display_header()
889
575
 
890
- def _edit_templates(self) -> None:
891
- """Template editing interface."""
892
- self.console.print("[yellow]Template editing interface - Coming soon![/yellow]")
893
- Prompt.ask("Press Enter to continue")
576
+ self.console.print("\n[bold]Auto-Linking Skills to Agents...[/bold]\n")
894
577
 
895
- def _manage_behaviors(self) -> None:
896
- """Behavior file management interface."""
897
- while True:
898
- self.console.clear()
899
- self._display_header()
578
+ # Get enabled agents
579
+ agents = self.agent_manager.discover_agents()
580
+ enabled_agents = [
581
+ a.name
582
+ for a in agents
583
+ if self.agent_manager.get_pending_state(a.name)
584
+ ]
900
585
 
901
- self.console.print("[bold]Behavior File Management[/bold]\n")
586
+ if not enabled_agents:
587
+ self.console.print(
588
+ "[yellow]No agents are currently enabled.[/yellow]"
589
+ )
590
+ self.console.print(
591
+ "Please enable agents first in Agent Management."
592
+ )
593
+ Prompt.ask("\nPress Enter to continue")
594
+ continue
902
595
 
903
- # Display current behavior files
904
- self._display_behavior_files()
596
+ # Auto-link
597
+ mapping = wizard._auto_link_skills(enabled_agents)
905
598
 
906
- # Show behavior menu
907
- self.console.print("\n[bold]Options:[/bold]")
908
- self.console.print(" [cyan][1][/cyan] Edit identity configuration")
909
- self.console.print(" [cyan][2][/cyan] Edit workflow configuration")
910
- self.console.print(" [cyan][3][/cyan] Import behavior file")
911
- self.console.print(" [cyan][4][/cyan] Export behavior file")
912
- self.console.print(" [cyan][b][/cyan] Back to main menu")
913
- self.console.print()
599
+ # Display preview
600
+ self.console.print("Auto-linked skills:\n")
601
+ for agent_id, skills in mapping.items():
602
+ self.console.print(f" [yellow]{agent_id}[/yellow]:")
603
+ for skill in skills:
604
+ self.console.print(f" - {skill}")
914
605
 
915
- choice = Prompt.ask("[bold cyan]Select an option[/bold cyan]", default="b")
606
+ # Confirm
607
+ confirm = Confirm.ask("\nApply this configuration?", default=True)
916
608
 
917
- if choice == "b":
609
+ if confirm:
610
+ wizard._apply_skills_configuration(mapping)
611
+ manager.save_mappings_to_config()
612
+ self.console.print("\n[green]✓ Auto-linking complete![/green]")
613
+ else:
614
+ self.console.print("\n[yellow]Auto-linking cancelled.[/yellow]")
615
+
616
+ Prompt.ask("\nPress Enter to continue")
617
+
618
+ elif choice == "b":
918
619
  break
919
- if choice == "1":
920
- self._edit_identity_config()
921
- elif choice == "2":
922
- self._edit_workflow_config()
923
- elif choice == "3":
924
- self._import_behavior_file()
925
- elif choice == "4":
926
- self._export_behavior_file()
927
620
  else:
928
- self.console.print("[red]Invalid choice.[/red]")
929
- Prompt.ask("Press Enter to continue")
621
+ self.console.print("[red]Invalid choice. Please try again.[/red]")
622
+ Prompt.ask("\nPress Enter to continue")
930
623
 
931
624
  def _display_behavior_files(self) -> None:
932
625
  """Display current behavior files."""
933
- if self.current_scope == "project":
934
- config_dir = self.project_dir / ".claude-mpm" / "behaviors"
935
- else:
936
- config_dir = Path.home() / ".claude-mpm" / "behaviors"
937
-
938
- config_dir.mkdir(parents=True, exist_ok=True)
939
-
940
- table = Table(title="Behavior Files", box=ROUNDED)
941
- table.add_column("File", style="cyan", width=30)
942
- table.add_column("Size", style="dim", width=10)
943
- table.add_column("Modified", style="white", width=20)
944
-
945
- identity_file = config_dir / "identity.yaml"
946
- workflow_file = config_dir / "workflow.yaml"
947
-
948
- for file_path in [identity_file, workflow_file]:
949
- if file_path.exists():
950
- stat = file_path.stat()
951
- size = f"{stat.st_size} bytes"
952
- modified = f"{stat.st_mtime:.0f}" # Simplified timestamp
953
- table.add_row(file_path.name, size, modified)
954
- else:
955
- table.add_row(file_path.name, "[dim]Not found[/dim]", "-")
956
-
957
- self.console.print(table)
626
+ self.behavior_manager.display_behavior_files()
958
627
 
959
628
  def _edit_identity_config(self) -> None:
960
629
  """Edit identity configuration."""
961
- self.console.print(
962
- "[yellow]Identity configuration editor - Coming soon![/yellow]"
963
- )
964
- Prompt.ask("Press Enter to continue")
630
+ self.behavior_manager.edit_identity_config()
965
631
 
966
632
  def _edit_workflow_config(self) -> None:
967
633
  """Edit workflow configuration."""
968
- self.console.print(
969
- "[yellow]Workflow configuration editor - Coming soon![/yellow]"
970
- )
971
- Prompt.ask("Press Enter to continue")
634
+ self.behavior_manager.edit_workflow_config()
972
635
 
973
636
  def _import_behavior_file(self) -> None:
974
637
  """Import a behavior file."""
975
- file_path = Prompt.ask("Enter path to behavior file to import")
638
+ self.behavior_manager.import_behavior_file()
976
639
 
977
- try:
978
- source = Path(file_path)
979
- if not source.exists():
980
- self.console.print(f"[red]File not found: {file_path}[/red]")
981
- return
982
-
983
- # Determine target directory
984
- if self.current_scope == "project":
985
- config_dir = self.project_dir / ".claude-mpm" / "behaviors"
986
- else:
987
- config_dir = Path.home() / ".claude-mpm" / "behaviors"
640
+ def _export_behavior_file(self) -> None:
641
+ """Export a behavior file."""
642
+ self.behavior_manager.export_behavior_file()
988
643
 
989
- config_dir.mkdir(parents=True, exist_ok=True)
644
+ def _manage_startup_configuration(self) -> bool:
645
+ """Manage startup configuration for MCP services and agents."""
646
+ return self.startup_manager.manage_startup_configuration()
990
647
 
991
- # Copy file
992
- import shutil
648
+ def _load_startup_configuration(self, config: Config) -> Dict:
649
+ """Load current startup configuration from config."""
650
+ return self.startup_manager.load_startup_configuration(config)
993
651
 
994
- target = config_dir / source.name
995
- shutil.copy2(source, target)
652
+ def _display_startup_configuration(self, startup_config: Dict) -> None:
653
+ """Display current startup configuration in a table."""
654
+ self.startup_manager.display_startup_configuration(startup_config)
996
655
 
997
- self.console.print(f"[green]Successfully imported {source.name}![/green]")
656
+ def _configure_mcp_services(self, startup_config: Dict, config: Config) -> None:
657
+ """Configure which MCP services to enable at startup."""
658
+ self.startup_manager.configure_mcp_services(startup_config, config)
998
659
 
999
- except Exception as e:
1000
- self.console.print(f"[red]Error importing file: {e}[/red]")
660
+ def _configure_hook_services(self, startup_config: Dict, config: Config) -> None:
661
+ """Configure which hook services to enable at startup."""
662
+ self.startup_manager.configure_hook_services(startup_config, config)
1001
663
 
1002
- Prompt.ask("Press Enter to continue")
664
+ def _configure_system_agents(self, startup_config: Dict, config: Config) -> None:
665
+ """Configure which system agents to deploy at startup."""
666
+ self.startup_manager.configure_system_agents(startup_config, config)
1003
667
 
1004
- def _export_behavior_file(self) -> None:
1005
- """Export a behavior file."""
1006
- self.console.print("[yellow]Behavior file export - Coming soon![/yellow]")
1007
- Prompt.ask("Press Enter to continue")
668
+ def _parse_id_selection(self, selection: str, max_id: int) -> List[int]:
669
+ """Parse ID selection string (e.g., '1,3,5' or '1-4')."""
670
+ return parse_id_selection(selection, max_id)
671
+
672
+ def _enable_all_services(self, startup_config: Dict, config: Config) -> None:
673
+ """Enable all services and agents."""
674
+ self.startup_manager.enable_all_services(startup_config, config)
675
+
676
+ def _disable_all_services(self, startup_config: Dict, config: Config) -> None:
677
+ """Disable all services and agents."""
678
+ self.startup_manager.disable_all_services(startup_config, config)
679
+
680
+ def _reset_to_defaults(self, startup_config: Dict, config: Config) -> None:
681
+ """Reset startup configuration to defaults."""
682
+ self.startup_manager.reset_to_defaults(startup_config, config)
683
+
684
+ def _save_startup_configuration(self, startup_config: Dict, config: Config) -> bool:
685
+ """Save startup configuration to config file and return whether to proceed to startup."""
686
+ return self.startup_manager.save_startup_configuration(startup_config, config)
687
+
688
+ def _save_all_configuration(self) -> bool:
689
+ """Save all configuration changes across all contexts."""
690
+ return self.startup_manager.save_all_configuration()
691
+
692
+ def _launch_claude_mpm(self) -> None:
693
+ """Launch Claude MPM run command, replacing current process."""
694
+ self.navigation.launch_claude_mpm()
1008
695
 
1009
696
  def _switch_scope(self) -> None:
1010
697
  """Switch between project and user scope."""
1011
- self.current_scope = "user" if self.current_scope == "project" else "project"
1012
- self.console.print(f"[green]Switched to {self.current_scope} scope[/green]")
1013
- Prompt.ask("Press Enter to continue")
698
+ self.navigation.switch_scope()
699
+ # Sync scope back from navigation
700
+ self.current_scope = self.navigation.current_scope
1014
701
 
1015
702
  def _show_version_info_interactive(self) -> None:
1016
703
  """Show version information in interactive mode."""
1017
- self.console.clear()
1018
- self._display_header()
1019
-
1020
- # Get version information
1021
- mpm_version = self.version_service.get_version()
1022
- build_number = self.version_service.get_build_number()
1023
-
1024
- # Try to get Claude Code version using the installer's method
1025
- claude_version = "Unknown"
1026
- try:
1027
- from ...hooks.claude_hooks.installer import HookInstaller
1028
-
1029
- installer = HookInstaller()
1030
- detected_version = installer.get_claude_version()
1031
- if detected_version:
1032
- is_compatible, _ = installer.is_version_compatible()
1033
- claude_version = f"{detected_version} (Claude Code)"
1034
- if not is_compatible:
1035
- claude_version += (
1036
- f" - Monitoring requires {installer.MIN_CLAUDE_VERSION}+"
1037
- )
1038
- else:
1039
- # Fallback to direct subprocess call
1040
- import subprocess
1041
-
1042
- result = subprocess.run(
1043
- ["claude", "--version"],
1044
- capture_output=True,
1045
- text=True,
1046
- timeout=5,
1047
- check=False,
1048
- )
1049
- if result.returncode == 0:
1050
- claude_version = result.stdout.strip()
1051
- except:
1052
- pass
1053
-
1054
- # Create version panel
1055
- version_text = f"""
1056
- [bold cyan]Claude MPM[/bold cyan]
1057
- Version: {mpm_version}
1058
- Build: {build_number}
1059
-
1060
- [bold cyan]Claude Code[/bold cyan]
1061
- Version: {claude_version}
1062
-
1063
- [bold cyan]Python[/bold cyan]
1064
- Version: {sys.version.split()[0]}
1065
-
1066
- [bold cyan]Configuration[/bold cyan]
1067
- Scope: {self.current_scope}
1068
- Directory: {self.project_dir}
1069
- """
1070
-
1071
- panel = Panel(
1072
- version_text.strip(),
1073
- title="[bold]Version Information[/bold]",
1074
- box=ROUNDED,
1075
- style="green",
1076
- )
1077
-
1078
- self.console.print(panel)
1079
- Prompt.ask("\nPress Enter to continue")
704
+ self.persistence.show_version_info_interactive()
1080
705
 
1081
706
  # Non-interactive command methods
1082
707
 
@@ -1118,261 +743,33 @@ Directory: {self.project_dir}
1118
743
 
1119
744
  def _export_config(self, file_path: str) -> CommandResult:
1120
745
  """Export configuration to a file."""
1121
- try:
1122
- # Gather all configuration
1123
- config_data = {"scope": self.current_scope, "agents": {}, "behaviors": {}}
1124
-
1125
- # Get agent states
1126
- agents = self.agent_manager.discover_agents()
1127
- for agent in agents:
1128
- config_data["agents"][agent.name] = {
1129
- "enabled": self.agent_manager.is_agent_enabled(agent.name),
1130
- "template_path": str(self._get_agent_template_path(agent.name)),
1131
- }
1132
-
1133
- # Write to file
1134
- output_path = Path(file_path)
1135
- with open(output_path, "w") as f:
1136
- json.dump(config_data, f, indent=2)
1137
-
1138
- return CommandResult.success_result(
1139
- f"Configuration exported to {output_path}"
1140
- )
1141
-
1142
- except Exception as e:
1143
- return CommandResult.error_result(f"Failed to export configuration: {e}")
746
+ return self.persistence.export_config(file_path)
1144
747
 
1145
748
  def _import_config(self, file_path: str) -> CommandResult:
1146
749
  """Import configuration from a file."""
1147
- try:
1148
- input_path = Path(file_path)
1149
- if not input_path.exists():
1150
- return CommandResult.error_result(f"File not found: {file_path}")
1151
-
1152
- with open(input_path) as f:
1153
- config_data = json.load(f)
1154
-
1155
- # Apply agent states
1156
- if "agents" in config_data:
1157
- for agent_name, agent_config in config_data["agents"].items():
1158
- if "enabled" in agent_config:
1159
- self.agent_manager.set_agent_enabled(
1160
- agent_name, agent_config["enabled"]
1161
- )
1162
-
1163
- return CommandResult.success_result(
1164
- f"Configuration imported from {input_path}"
1165
- )
1166
-
1167
- except Exception as e:
1168
- return CommandResult.error_result(f"Failed to import configuration: {e}")
750
+ return self.persistence.import_config(file_path)
1169
751
 
1170
752
  def _show_version_info(self) -> CommandResult:
1171
753
  """Show version information in non-interactive mode."""
1172
- mpm_version = self.version_service.get_version()
1173
- build_number = self.version_service.get_build_number()
1174
-
1175
- data = {
1176
- "mpm_version": mpm_version,
1177
- "build_number": build_number,
1178
- "python_version": sys.version.split()[0],
1179
- }
1180
-
1181
- # Try to get Claude version
1182
- try:
1183
- import subprocess
1184
-
1185
- result = subprocess.run(
1186
- ["claude", "--version"],
1187
- capture_output=True,
1188
- text=True,
1189
- timeout=5,
1190
- check=False,
1191
- )
1192
- if result.returncode == 0:
1193
- data["claude_version"] = result.stdout.strip()
1194
- except:
1195
- data["claude_version"] = "Unknown"
1196
-
1197
- # Print formatted output
1198
- self.console.print(
1199
- f"[bold]Claude MPM:[/bold] {mpm_version} (build {build_number})"
1200
- )
1201
- self.console.print(
1202
- f"[bold]Claude Code:[/bold] {data.get('claude_version', 'Unknown')}"
1203
- )
1204
- self.console.print(f"[bold]Python:[/bold] {data['python_version']}")
1205
-
1206
- return CommandResult.success_result("Version information displayed", data=data)
754
+ return self.persistence.show_version_info()
1207
755
 
1208
756
  def _install_hooks(self, force: bool = False) -> CommandResult:
1209
757
  """Install Claude MPM hooks for Claude Code integration."""
1210
- try:
1211
- from ...hooks.claude_hooks.installer import HookInstaller
1212
-
1213
- installer = HookInstaller()
1214
-
1215
- # Check Claude Code version compatibility first
1216
- is_compatible, version_message = installer.is_version_compatible()
1217
- self.console.print("[cyan]Checking Claude Code version...[/cyan]")
1218
- self.console.print(version_message)
1219
-
1220
- if not is_compatible:
1221
- self.console.print(
1222
- "\n[yellow]⚠ Hook monitoring is not available for your Claude Code version.[/yellow]"
1223
- )
1224
- self.console.print(
1225
- "The dashboard and other features will work without real-time monitoring."
1226
- )
1227
- self.console.print(
1228
- f"\n[dim]To enable monitoring, upgrade Claude Code to version {installer.MIN_CLAUDE_VERSION} or higher.[/dim]"
1229
- )
1230
- return CommandResult.success_result(
1231
- "Version incompatible with hook monitoring",
1232
- data={"compatible": False, "message": version_message},
1233
- )
1234
-
1235
- # Check current status
1236
- status = installer.get_status()
1237
- if status["installed"] and not force:
1238
- self.console.print("[yellow]Hooks are already installed.[/yellow]")
1239
- self.console.print("Use --force to reinstall.")
1240
-
1241
- if not status["valid"]:
1242
- self.console.print("\n[red]However, there are issues:[/red]")
1243
- for issue in status["issues"]:
1244
- self.console.print(f" - {issue}")
1245
-
1246
- return CommandResult.success_result(
1247
- "Hooks already installed", data=status
1248
- )
1249
-
1250
- # Install hooks
1251
- self.console.print("[cyan]Installing Claude MPM hooks...[/cyan]")
1252
- success = installer.install_hooks(force=force)
1253
-
1254
- if success:
1255
- self.console.print("[green]✓ Hooks installed successfully![/green]")
1256
- self.console.print("\nYou can now use /mpm commands in Claude Code:")
1257
- self.console.print(" /mpm - Show help")
1258
- self.console.print(" /mpm status - Show claude-mpm status")
1259
-
1260
- # Verify installation
1261
- is_valid, issues = installer.verify_hooks()
1262
- if not is_valid:
1263
- self.console.print(
1264
- "\n[yellow]Warning: Installation completed but verification found issues:[/yellow]"
1265
- )
1266
- for issue in issues:
1267
- self.console.print(f" - {issue}")
1268
-
1269
- return CommandResult.success_result("Hooks installed successfully")
1270
- self.console.print("[red]✗ Hook installation failed[/red]")
1271
- return CommandResult.error_result("Hook installation failed")
1272
-
1273
- except ImportError:
1274
- self.console.print("[red]Error: HookInstaller module not found[/red]")
1275
- self.console.print("Please ensure claude-mpm is properly installed.")
1276
- return CommandResult.error_result("HookInstaller module not found")
1277
- except Exception as e:
1278
- self.logger.error(f"Hook installation error: {e}", exc_info=True)
1279
- return CommandResult.error_result(f"Hook installation failed: {e}")
758
+ # Share logger with hook manager for consistent error logging
759
+ self.hook_manager.logger = self.logger
760
+ return self.hook_manager.install_hooks(force=force)
1280
761
 
1281
762
  def _verify_hooks(self) -> CommandResult:
1282
763
  """Verify that Claude MPM hooks are properly installed."""
1283
- try:
1284
- from ...hooks.claude_hooks.installer import HookInstaller
1285
-
1286
- installer = HookInstaller()
1287
- status = installer.get_status()
1288
-
1289
- self.console.print("[bold]Hook Installation Status[/bold]\n")
1290
-
1291
- # Show Claude Code version and compatibility
1292
- if status.get("claude_version"):
1293
- self.console.print(f"Claude Code Version: {status['claude_version']}")
1294
- if status.get("version_compatible"):
1295
- self.console.print(
1296
- "[green]✓[/green] Version compatible with hook monitoring"
1297
- )
1298
- else:
1299
- self.console.print(
1300
- f"[yellow]⚠[/yellow] {status.get('version_message', 'Version incompatible')}"
1301
- )
1302
- self.console.print()
1303
- else:
1304
- self.console.print(
1305
- "[yellow]Claude Code version could not be detected[/yellow]"
1306
- )
1307
- self.console.print()
1308
-
1309
- if status["installed"]:
1310
- self.console.print(
1311
- f"[green]✓[/green] Hooks installed at: {status['hook_script']}"
1312
- )
1313
- else:
1314
- self.console.print("[red]✗[/red] Hooks not installed")
1315
-
1316
- if status["settings_file"]:
1317
- self.console.print(
1318
- f"[green]✓[/green] Settings file: {status['settings_file']}"
1319
- )
1320
- else:
1321
- self.console.print("[red]✗[/red] Settings file not found")
1322
-
1323
- if status.get("configured_events"):
1324
- self.console.print(
1325
- f"[green]✓[/green] Configured events: {', '.join(status['configured_events'])}"
1326
- )
1327
- else:
1328
- self.console.print("[red]✗[/red] No events configured")
1329
-
1330
- if status["valid"]:
1331
- self.console.print("\n[green]All checks passed![/green]")
1332
- else:
1333
- self.console.print("\n[red]Issues found:[/red]")
1334
- for issue in status["issues"]:
1335
- self.console.print(f" - {issue}")
1336
-
1337
- return CommandResult.success_result(
1338
- "Hook verification complete", data=status
1339
- )
1340
-
1341
- except ImportError:
1342
- self.console.print("[red]Error: HookInstaller module not found[/red]")
1343
- return CommandResult.error_result("HookInstaller module not found")
1344
- except Exception as e:
1345
- self.logger.error(f"Hook verification error: {e}", exc_info=True)
1346
- return CommandResult.error_result(f"Hook verification failed: {e}")
764
+ # Share logger with hook manager for consistent error logging
765
+ self.hook_manager.logger = self.logger
766
+ return self.hook_manager.verify_hooks()
1347
767
 
1348
768
  def _uninstall_hooks(self) -> CommandResult:
1349
769
  """Uninstall Claude MPM hooks."""
1350
- try:
1351
- from ...hooks.claude_hooks.installer import HookInstaller
1352
-
1353
- installer = HookInstaller()
1354
-
1355
- # Confirm uninstallation
1356
- if not Confirm.ask(
1357
- "[yellow]Are you sure you want to uninstall Claude MPM hooks?[/yellow]"
1358
- ):
1359
- return CommandResult.success_result("Uninstallation cancelled")
1360
-
1361
- self.console.print("[cyan]Uninstalling Claude MPM hooks...[/cyan]")
1362
- success = installer.uninstall_hooks()
1363
-
1364
- if success:
1365
- self.console.print("[green]✓ Hooks uninstalled successfully![/green]")
1366
- return CommandResult.success_result("Hooks uninstalled successfully")
1367
- self.console.print("[red]✗ Hook uninstallation failed[/red]")
1368
- return CommandResult.error_result("Hook uninstallation failed")
1369
-
1370
- except ImportError:
1371
- self.console.print("[red]Error: HookInstaller module not found[/red]")
1372
- return CommandResult.error_result("HookInstaller module not found")
1373
- except Exception as e:
1374
- self.logger.error(f"Hook uninstallation error: {e}", exc_info=True)
1375
- return CommandResult.error_result(f"Hook uninstallation failed: {e}")
770
+ # Share logger with hook manager for consistent error logging
771
+ self.hook_manager.logger = self.logger
772
+ return self.hook_manager.uninstall_hooks()
1376
773
 
1377
774
  def _run_agent_management(self) -> CommandResult:
1378
775
  """Jump directly to agent management."""
@@ -1396,13 +793,21 @@ Directory: {self.project_dir}
1396
793
 
1397
794
  def _run_behavior_management(self) -> CommandResult:
1398
795
  """Jump directly to behavior management."""
796
+ return self.behavior_manager.run_behavior_management()
797
+
798
+ def _run_startup_configuration(self) -> CommandResult:
799
+ """Jump directly to startup configuration."""
1399
800
  try:
1400
- self._manage_behaviors()
1401
- return CommandResult.success_result("Behavior management completed")
801
+ proceed = self._manage_startup_configuration()
802
+ if proceed:
803
+ return CommandResult.success_result(
804
+ "Startup configuration saved, proceeding to startup"
805
+ )
806
+ return CommandResult.success_result("Startup configuration completed")
1402
807
  except KeyboardInterrupt:
1403
- return CommandResult.success_result("Behavior management cancelled")
808
+ return CommandResult.success_result("Startup configuration cancelled")
1404
809
  except Exception as e:
1405
- return CommandResult.error_result(f"Behavior management failed: {e}")
810
+ return CommandResult.error_result(f"Startup configuration failed: {e}")
1406
811
 
1407
812
 
1408
813
  def manage_configure(args) -> int: