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