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

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (792) 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 +432 -158
  9. claude_mpm/agents/BASE_PROMPT_ENGINEER.md +787 -0
  10. claude_mpm/agents/BASE_QA.md +167 -0
  11. claude_mpm/agents/BASE_RESEARCH.md +53 -0
  12. claude_mpm/agents/OUTPUT_STYLE.md +254 -29
  13. claude_mpm/agents/PM_INSTRUCTIONS.md +969 -0
  14. claude_mpm/agents/PM_INSTRUCTIONS_TEACH.md +1322 -0
  15. claude_mpm/agents/WORKFLOW.md +355 -191
  16. claude_mpm/agents/__init__.py +6 -0
  17. claude_mpm/agents/agent_loader.py +41 -14
  18. claude_mpm/agents/agent_loader_integration.py +3 -2
  19. claude_mpm/agents/async_agent_loader.py +3 -3
  20. claude_mpm/agents/base_agent.json +6 -3
  21. claude_mpm/agents/base_agent_loader.py +21 -44
  22. claude_mpm/agents/frontmatter_validator.py +292 -252
  23. claude_mpm/agents/system_agent_config.py +3 -2
  24. claude_mpm/agents/templates/README.md +465 -0
  25. claude_mpm/agents/templates/circuit-breakers.md +1005 -0
  26. claude_mpm/agents/templates/context-management-examples.md +544 -0
  27. claude_mpm/agents/templates/git-file-tracking.md +584 -0
  28. claude_mpm/agents/templates/pm-examples.md +474 -0
  29. claude_mpm/agents/templates/pm-red-flags.md +310 -0
  30. claude_mpm/agents/templates/pr-workflow-examples.md +427 -0
  31. claude_mpm/agents/templates/research-gate-examples.md +669 -0
  32. claude_mpm/agents/templates/response-format.md +583 -0
  33. claude_mpm/agents/templates/structured-questions-examples.md +615 -0
  34. claude_mpm/agents/templates/ticket-completeness-examples.md +139 -0
  35. claude_mpm/agents/templates/ticketing-examples.md +277 -0
  36. claude_mpm/agents/templates/validation-templates.md +312 -0
  37. claude_mpm/cli/__init__.py +72 -376
  38. claude_mpm/cli/commands/__init__.py +4 -0
  39. claude_mpm/cli/commands/agent_manager.py +675 -20
  40. claude_mpm/cli/commands/agent_source.py +774 -0
  41. claude_mpm/cli/commands/agent_state_manager.py +344 -0
  42. claude_mpm/cli/commands/agents.py +1673 -178
  43. claude_mpm/cli/commands/agents_cleanup.py +210 -0
  44. claude_mpm/cli/commands/agents_detect.py +380 -0
  45. claude_mpm/cli/commands/agents_discover.py +338 -0
  46. claude_mpm/cli/commands/agents_recommend.py +309 -0
  47. claude_mpm/cli/commands/aggregate.py +11 -7
  48. claude_mpm/cli/commands/analyze.py +18 -13
  49. claude_mpm/cli/commands/analyze_code.py +8 -4
  50. claude_mpm/cli/commands/auto_configure.py +566 -0
  51. claude_mpm/cli/commands/cleanup.py +12 -12
  52. claude_mpm/cli/commands/config.py +54 -17
  53. claude_mpm/cli/commands/configure.py +1184 -1055
  54. claude_mpm/cli/commands/configure_agent_display.py +261 -0
  55. claude_mpm/cli/commands/configure_behavior_manager.py +204 -0
  56. claude_mpm/cli/commands/configure_hook_manager.py +225 -0
  57. claude_mpm/cli/commands/configure_models.py +18 -0
  58. claude_mpm/cli/commands/configure_navigation.py +184 -0
  59. claude_mpm/cli/commands/configure_paths.py +104 -0
  60. claude_mpm/cli/commands/configure_persistence.py +254 -0
  61. claude_mpm/cli/commands/configure_startup_manager.py +646 -0
  62. claude_mpm/cli/commands/configure_template_editor.py +497 -0
  63. claude_mpm/cli/commands/configure_validators.py +73 -0
  64. claude_mpm/cli/commands/dashboard.py +50 -52
  65. claude_mpm/cli/commands/debug.py +19 -19
  66. claude_mpm/cli/commands/doctor.py +51 -7
  67. claude_mpm/cli/commands/hook_errors.py +277 -0
  68. claude_mpm/cli/commands/info.py +3 -4
  69. claude_mpm/cli/commands/local_deploy.py +534 -0
  70. claude_mpm/cli/commands/mcp.py +17 -10
  71. claude_mpm/cli/commands/mcp_command_router.py +11 -0
  72. claude_mpm/cli/commands/mcp_config.py +154 -0
  73. claude_mpm/cli/commands/mcp_external_commands.py +249 -0
  74. claude_mpm/cli/commands/mcp_install_commands.py +101 -32
  75. claude_mpm/cli/commands/mcp_pipx_config.py +2 -2
  76. claude_mpm/cli/commands/mcp_setup_external.py +868 -0
  77. claude_mpm/cli/commands/memory.py +55 -21
  78. claude_mpm/cli/commands/monitor.py +160 -70
  79. claude_mpm/cli/commands/mpm_init/__init__.py +73 -0
  80. claude_mpm/cli/commands/mpm_init/core.py +573 -0
  81. claude_mpm/cli/commands/mpm_init/display.py +341 -0
  82. claude_mpm/cli/commands/mpm_init/git_activity.py +427 -0
  83. claude_mpm/cli/commands/mpm_init/modes.py +397 -0
  84. claude_mpm/cli/commands/mpm_init/prompts.py +442 -0
  85. claude_mpm/cli/commands/mpm_init_cli.py +396 -0
  86. claude_mpm/cli/commands/mpm_init_handler.py +114 -4
  87. claude_mpm/cli/commands/postmortem.py +401 -0
  88. claude_mpm/cli/commands/run.py +252 -167
  89. claude_mpm/cli/commands/search.py +458 -0
  90. claude_mpm/cli/commands/skill_source.py +694 -0
  91. claude_mpm/cli/commands/skills.py +1225 -0
  92. claude_mpm/cli/commands/uninstall.py +176 -0
  93. claude_mpm/cli/commands/upgrade.py +152 -0
  94. claude_mpm/cli/commands/verify.py +119 -0
  95. claude_mpm/cli/executor.py +279 -0
  96. claude_mpm/cli/helpers.py +105 -0
  97. claude_mpm/cli/interactive/__init__.py +21 -0
  98. claude_mpm/cli/interactive/agent_wizard.py +1872 -0
  99. claude_mpm/cli/interactive/skills_wizard.py +491 -0
  100. claude_mpm/cli/parser.py +79 -2
  101. claude_mpm/cli/parsers/__init__.py +7 -1
  102. claude_mpm/cli/parsers/agent_manager_parser.py +161 -1
  103. claude_mpm/cli/parsers/agent_source_parser.py +171 -0
  104. claude_mpm/cli/parsers/agents_parser.py +369 -1
  105. claude_mpm/cli/parsers/auto_configure_parser.py +245 -0
  106. claude_mpm/cli/parsers/base_parser.py +196 -3
  107. claude_mpm/cli/parsers/config_parser.py +96 -43
  108. claude_mpm/cli/parsers/configure_parser.py +11 -15
  109. claude_mpm/cli/parsers/local_deploy_parser.py +227 -0
  110. claude_mpm/cli/parsers/mcp_parser.py +15 -0
  111. claude_mpm/cli/parsers/monitor_parser.py +12 -2
  112. claude_mpm/cli/parsers/mpm_init_parser.py +179 -9
  113. claude_mpm/cli/parsers/run_parser.py +5 -0
  114. claude_mpm/cli/parsers/search_parser.py +245 -0
  115. claude_mpm/cli/parsers/skill_source_parser.py +169 -0
  116. claude_mpm/cli/parsers/skills_parser.py +282 -0
  117. claude_mpm/cli/parsers/source_parser.py +138 -0
  118. claude_mpm/cli/shared/argument_patterns.py +20 -13
  119. claude_mpm/cli/shared/base_command.py +2 -2
  120. claude_mpm/cli/shared/output_formatters.py +28 -19
  121. claude_mpm/cli/startup.py +994 -0
  122. claude_mpm/cli/startup_display.py +480 -0
  123. claude_mpm/cli/startup_logging.py +179 -13
  124. claude_mpm/cli/utils.py +54 -3
  125. claude_mpm/cli_module/commands.py +1 -1
  126. claude_mpm/commands/mpm-agents-auto-configure.md +278 -0
  127. claude_mpm/commands/mpm-agents-detect.md +177 -0
  128. claude_mpm/commands/mpm-agents-list.md +131 -0
  129. claude_mpm/commands/mpm-agents-recommend.md +223 -0
  130. claude_mpm/commands/mpm-config-view.md +150 -0
  131. claude_mpm/commands/mpm-doctor.md +9 -0
  132. claude_mpm/commands/mpm-help.md +297 -5
  133. claude_mpm/commands/mpm-init.md +401 -17
  134. claude_mpm/commands/mpm-monitor.md +418 -0
  135. claude_mpm/commands/mpm-postmortem.md +123 -0
  136. claude_mpm/commands/mpm-session-resume.md +381 -0
  137. claude_mpm/commands/mpm-status.md +79 -8
  138. claude_mpm/commands/mpm-ticket-organize.md +304 -0
  139. claude_mpm/commands/mpm-ticket-view.md +552 -0
  140. claude_mpm/commands/mpm-version.md +122 -0
  141. claude_mpm/commands/mpm.md +12 -0
  142. claude_mpm/config/agent_config.py +4 -4
  143. claude_mpm/config/agent_presets.py +488 -0
  144. claude_mpm/config/agent_sources.py +325 -0
  145. claude_mpm/config/experimental_features.py +7 -7
  146. claude_mpm/config/model_config.py +428 -0
  147. claude_mpm/config/paths.py +3 -2
  148. claude_mpm/config/skill_presets.py +392 -0
  149. claude_mpm/config/skill_sources.py +590 -0
  150. claude_mpm/config/socketio_config.py +3 -3
  151. claude_mpm/constants.py +28 -1
  152. claude_mpm/core/__init__.py +53 -17
  153. claude_mpm/core/agent_name_normalizer.py +3 -2
  154. claude_mpm/core/agent_registry.py +2 -2
  155. claude_mpm/core/agent_session_manager.py +10 -10
  156. claude_mpm/core/api_validator.py +330 -0
  157. claude_mpm/core/base_service.py +33 -23
  158. claude_mpm/core/cache.py +9 -9
  159. claude_mpm/core/claude_runner.py +24 -42
  160. claude_mpm/core/config.py +101 -8
  161. claude_mpm/core/config_aliases.py +7 -6
  162. claude_mpm/core/constants.py +66 -1
  163. claude_mpm/core/container.py +11 -5
  164. claude_mpm/core/enums.py +452 -0
  165. claude_mpm/core/error_handler.py +623 -0
  166. claude_mpm/core/factories.py +1 -1
  167. claude_mpm/core/file_utils.py +764 -0
  168. claude_mpm/core/framework/__init__.py +25 -0
  169. claude_mpm/core/framework/formatters/__init__.py +11 -0
  170. claude_mpm/core/framework/formatters/capability_generator.py +367 -0
  171. claude_mpm/core/framework/formatters/content_formatter.py +288 -0
  172. claude_mpm/core/framework/formatters/context_generator.py +185 -0
  173. claude_mpm/core/framework/loaders/__init__.py +13 -0
  174. claude_mpm/core/framework/loaders/agent_loader.py +210 -0
  175. claude_mpm/core/framework/loaders/file_loader.py +176 -0
  176. claude_mpm/core/framework/loaders/instruction_loader.py +181 -0
  177. claude_mpm/core/framework/loaders/packaged_loader.py +232 -0
  178. claude_mpm/core/framework/processors/__init__.py +11 -0
  179. claude_mpm/core/framework/processors/memory_processor.py +230 -0
  180. claude_mpm/core/framework/processors/metadata_processor.py +146 -0
  181. claude_mpm/core/framework/processors/template_processor.py +244 -0
  182. claude_mpm/core/framework_loader.py +321 -1631
  183. claude_mpm/core/hook_error_memory.py +381 -0
  184. claude_mpm/core/hook_manager.py +49 -8
  185. claude_mpm/core/injectable_service.py +11 -8
  186. claude_mpm/core/instruction_reinforcement_hook.py +4 -3
  187. claude_mpm/core/interactive_session.py +146 -18
  188. claude_mpm/core/interfaces.py +56 -1
  189. claude_mpm/core/lazy.py +3 -3
  190. claude_mpm/core/log_manager.py +92 -23
  191. claude_mpm/core/logger.py +22 -15
  192. claude_mpm/core/logging_config.py +6 -2
  193. claude_mpm/core/logging_utils.py +520 -0
  194. claude_mpm/core/oneshot_session.py +122 -15
  195. claude_mpm/core/optimized_agent_loader.py +9 -9
  196. claude_mpm/core/optimized_startup.py +1 -1
  197. claude_mpm/core/output_style_manager.py +12 -192
  198. claude_mpm/core/pm_hook_interceptor.py +18 -12
  199. claude_mpm/core/protocols/__init__.py +23 -0
  200. claude_mpm/core/protocols/runner_protocol.py +103 -0
  201. claude_mpm/core/protocols/session_protocol.py +131 -0
  202. claude_mpm/core/service_registry.py +7 -3
  203. claude_mpm/core/session_manager.py +14 -12
  204. claude_mpm/core/shared/config_loader.py +1 -1
  205. claude_mpm/core/shared/singleton_manager.py +11 -4
  206. claude_mpm/core/socketio_pool.py +15 -15
  207. claude_mpm/core/system_context.py +38 -0
  208. claude_mpm/core/tool_access_control.py +3 -2
  209. claude_mpm/core/types.py +4 -11
  210. claude_mpm/core/typing_utils.py +7 -6
  211. claude_mpm/core/unified_agent_registry.py +115 -11
  212. claude_mpm/core/unified_config.py +6 -6
  213. claude_mpm/core/unified_paths.py +23 -20
  214. claude_mpm/dashboard/analysis_runner.py +4 -4
  215. claude_mpm/dashboard/api/simple_directory.py +261 -0
  216. claude_mpm/dashboard/static/css/activity.css +69 -69
  217. claude_mpm/dashboard/static/css/connection-status.css +10 -10
  218. claude_mpm/dashboard/static/css/dashboard.css +600 -18
  219. claude_mpm/dashboard/static/js/components/activity-tree.js +181 -195
  220. claude_mpm/dashboard/static/js/components/agent-hierarchy.js +105 -102
  221. claude_mpm/dashboard/static/js/components/agent-inference.js +34 -31
  222. claude_mpm/dashboard/static/js/components/build-tracker.js +67 -59
  223. claude_mpm/dashboard/static/js/components/code-simple.js +857 -0
  224. claude_mpm/dashboard/static/js/components/connection-debug.js +101 -101
  225. claude_mpm/dashboard/static/js/components/diff-viewer.js +891 -0
  226. claude_mpm/dashboard/static/js/components/event-processor.js +3 -0
  227. claude_mpm/dashboard/static/js/components/event-viewer.js +50 -13
  228. claude_mpm/dashboard/static/js/components/export-manager.js +3 -0
  229. claude_mpm/dashboard/static/js/components/file-change-tracker.js +443 -0
  230. claude_mpm/dashboard/static/js/components/file-change-viewer.js +690 -0
  231. claude_mpm/dashboard/static/js/components/file-tool-tracker.js +36 -16
  232. claude_mpm/dashboard/static/js/components/file-viewer.js +580 -0
  233. claude_mpm/dashboard/static/js/components/module-viewer.js +49 -23
  234. claude_mpm/dashboard/static/js/components/session-manager.js +19 -19
  235. claude_mpm/dashboard/static/js/components/socket-manager.js +5 -1
  236. claude_mpm/dashboard/static/js/components/ui-state-manager.js +356 -41
  237. claude_mpm/dashboard/static/js/components/unified-data-viewer.js +520 -88
  238. claude_mpm/dashboard/static/js/components/working-directory.js +46 -11
  239. claude_mpm/dashboard/static/js/connection-manager.js +76 -76
  240. claude_mpm/dashboard/static/js/dashboard.js +309 -178
  241. claude_mpm/dashboard/static/js/extension-error-handler.js +22 -22
  242. claude_mpm/dashboard/static/js/socket-client.js +183 -139
  243. claude_mpm/dashboard/static/js/tab-isolation-fix.js +185 -0
  244. claude_mpm/dashboard/static/socket.io.min.js +7 -0
  245. claude_mpm/dashboard/static/socket.io.v4.8.1.backup.js +7 -0
  246. claude_mpm/dashboard/templates/code_simple.html +153 -0
  247. claude_mpm/dashboard/templates/index.html +125 -122
  248. claude_mpm/experimental/cli_enhancements.py +5 -7
  249. claude_mpm/generators/agent_profile_generator.py +5 -3
  250. claude_mpm/hooks/__init__.py +37 -1
  251. claude_mpm/hooks/base_hook.py +5 -4
  252. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-313.pyc +0 -0
  253. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-313.pyc +0 -0
  254. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-313.pyc +0 -0
  255. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-313.pyc +0 -0
  256. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-313.pyc +0 -0
  257. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-313.pyc +0 -0
  258. claude_mpm/hooks/claude_hooks/connection_pool.py +4 -4
  259. claude_mpm/hooks/claude_hooks/event_handlers.py +24 -19
  260. claude_mpm/hooks/claude_hooks/hook_handler.py +29 -22
  261. claude_mpm/hooks/claude_hooks/installer.py +67 -22
  262. claude_mpm/hooks/claude_hooks/memory_integration.py +3 -3
  263. claude_mpm/hooks/claude_hooks/response_tracking.py +57 -17
  264. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-313.pyc +0 -0
  265. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-313.pyc +0 -0
  266. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-313.pyc +0 -0
  267. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-313.pyc +0 -0
  268. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-313.pyc +0 -0
  269. claude_mpm/hooks/claude_hooks/services/connection_manager.py +62 -64
  270. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +140 -76
  271. claude_mpm/hooks/claude_hooks/services/state_manager.py +11 -9
  272. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +3 -3
  273. claude_mpm/hooks/failure_learning/__init__.py +54 -0
  274. claude_mpm/hooks/failure_learning/failure_detection_hook.py +230 -0
  275. claude_mpm/hooks/failure_learning/fix_detection_hook.py +212 -0
  276. claude_mpm/hooks/failure_learning/learning_extraction_hook.py +281 -0
  277. claude_mpm/hooks/instruction_reinforcement.py +301 -0
  278. claude_mpm/hooks/kuzu_enrichment_hook.py +263 -0
  279. claude_mpm/hooks/kuzu_memory_hook.py +386 -0
  280. claude_mpm/hooks/kuzu_response_hook.py +179 -0
  281. claude_mpm/hooks/memory_integration_hook.py +1 -1
  282. claude_mpm/hooks/session_resume_hook.py +121 -0
  283. claude_mpm/hooks/templates/pre_tool_use_simple.py +78 -0
  284. claude_mpm/hooks/templates/pre_tool_use_template.py +323 -0
  285. claude_mpm/hooks/tool_call_interceptor.py +8 -5
  286. claude_mpm/hooks/validation_hooks.py +3 -3
  287. claude_mpm/init.py +23 -4
  288. claude_mpm/models/agent_session.py +8 -6
  289. claude_mpm/models/git_repository.py +198 -0
  290. claude_mpm/models/resume_log.py +340 -0
  291. claude_mpm/scripts/claude-hook-handler.sh +35 -9
  292. claude_mpm/scripts/launch_monitor.py +85 -0
  293. claude_mpm/scripts/mcp_server.py +3 -5
  294. claude_mpm/scripts/mpm_doctor.py +3 -2
  295. claude_mpm/scripts/socketio_daemon.py +159 -512
  296. claude_mpm/scripts/start_activity_logging.py +3 -1
  297. claude_mpm/services/__init__.py +144 -160
  298. claude_mpm/services/agents/__init__.py +18 -5
  299. claude_mpm/services/agents/agent_builder.py +56 -18
  300. claude_mpm/services/agents/agent_preset_service.py +238 -0
  301. claude_mpm/services/agents/agent_selection_service.py +484 -0
  302. claude_mpm/services/agents/auto_config_manager.py +796 -0
  303. claude_mpm/services/agents/auto_deploy_index_parser.py +569 -0
  304. claude_mpm/services/agents/cache_git_manager.py +621 -0
  305. claude_mpm/services/agents/deployment/agent_configuration_manager.py +1 -1
  306. claude_mpm/services/agents/deployment/agent_deployment.py +164 -17
  307. claude_mpm/services/agents/deployment/agent_discovery_service.py +191 -41
  308. claude_mpm/services/agents/deployment/agent_filesystem_manager.py +5 -5
  309. claude_mpm/services/agents/deployment/agent_format_converter.py +56 -12
  310. claude_mpm/services/agents/deployment/agent_lifecycle_manager.py +5 -7
  311. claude_mpm/services/agents/deployment/agent_metrics_collector.py +3 -3
  312. claude_mpm/services/agents/deployment/agent_operation_service.py +2 -2
  313. claude_mpm/services/agents/deployment/agent_record_service.py +4 -4
  314. claude_mpm/services/agents/deployment/agent_restore_handler.py +1 -4
  315. claude_mpm/services/agents/deployment/agent_state_service.py +2 -2
  316. claude_mpm/services/agents/deployment/agent_template_builder.py +939 -50
  317. claude_mpm/services/agents/deployment/agent_validator.py +31 -7
  318. claude_mpm/services/agents/deployment/agent_version_manager.py +8 -5
  319. claude_mpm/services/agents/deployment/agent_versioning.py +1 -1
  320. claude_mpm/services/agents/deployment/agents_directory_resolver.py +101 -15
  321. claude_mpm/services/agents/deployment/async_agent_deployment.py +3 -2
  322. claude_mpm/services/agents/deployment/deployment_config_loader.py +131 -7
  323. claude_mpm/services/agents/deployment/deployment_type_detector.py +10 -14
  324. claude_mpm/services/agents/deployment/deployment_wrapper.py +58 -0
  325. claude_mpm/services/agents/deployment/facade/deployment_facade.py +3 -3
  326. claude_mpm/services/agents/deployment/interface_adapter.py +3 -2
  327. claude_mpm/services/agents/deployment/local_template_deployment.py +360 -0
  328. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +249 -53
  329. claude_mpm/services/agents/deployment/pipeline/pipeline_executor.py +2 -2
  330. claude_mpm/services/agents/deployment/pipeline/steps/agent_processing_step.py +8 -7
  331. claude_mpm/services/agents/deployment/pipeline/steps/base_step.py +7 -16
  332. claude_mpm/services/agents/deployment/pipeline/steps/configuration_step.py +4 -3
  333. claude_mpm/services/agents/deployment/pipeline/steps/target_directory_step.py +7 -5
  334. claude_mpm/services/agents/deployment/pipeline/steps/validation_step.py +6 -5
  335. claude_mpm/services/agents/deployment/refactored_agent_deployment_service.py +10 -10
  336. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +363 -0
  337. claude_mpm/services/agents/deployment/single_agent_deployer.py +2 -2
  338. claude_mpm/services/agents/deployment/system_instructions_deployer.py +168 -43
  339. claude_mpm/services/agents/deployment/validation/__init__.py +3 -1
  340. claude_mpm/services/agents/deployment/validation/deployment_validator.py +2 -2
  341. claude_mpm/services/agents/deployment/validation/template_validator.py +64 -44
  342. claude_mpm/services/agents/deployment/validation/validation_result.py +1 -9
  343. claude_mpm/services/agents/git_source_manager.py +629 -0
  344. claude_mpm/services/agents/loading/agent_profile_loader.py +10 -9
  345. claude_mpm/services/agents/loading/base_agent_manager.py +16 -6
  346. claude_mpm/services/agents/loading/framework_agent_loader.py +11 -14
  347. claude_mpm/services/agents/local_template_manager.py +784 -0
  348. claude_mpm/services/agents/management/agent_capabilities_generator.py +3 -2
  349. claude_mpm/services/agents/management/agent_management_service.py +5 -5
  350. claude_mpm/services/agents/memory/agent_memory_manager.py +32 -29
  351. claude_mpm/services/agents/memory/content_manager.py +17 -9
  352. claude_mpm/services/agents/memory/memory_categorization_service.py +4 -2
  353. claude_mpm/services/agents/memory/memory_file_service.py +32 -6
  354. claude_mpm/services/agents/memory/memory_format_service.py +6 -4
  355. claude_mpm/services/agents/memory/memory_limits_service.py +4 -2
  356. claude_mpm/services/agents/memory/template_generator.py +3 -3
  357. claude_mpm/services/agents/observers.py +547 -0
  358. claude_mpm/services/agents/recommender.py +615 -0
  359. claude_mpm/services/agents/registry/deployed_agent_discovery.py +3 -3
  360. claude_mpm/services/agents/registry/modification_tracker.py +30 -19
  361. claude_mpm/services/agents/single_tier_deployment_service.py +696 -0
  362. claude_mpm/services/agents/sources/__init__.py +13 -0
  363. claude_mpm/services/agents/sources/agent_sync_state.py +516 -0
  364. claude_mpm/services/agents/sources/git_source_sync_service.py +1087 -0
  365. claude_mpm/services/agents/startup_sync.py +239 -0
  366. claude_mpm/services/agents/toolchain_detector.py +474 -0
  367. claude_mpm/services/analysis/__init__.py +25 -0
  368. claude_mpm/services/analysis/postmortem_reporter.py +474 -0
  369. claude_mpm/services/analysis/postmortem_service.py +765 -0
  370. claude_mpm/services/async_session_logger.py +141 -98
  371. claude_mpm/services/claude_session_logger.py +82 -74
  372. claude_mpm/services/cli/agent_cleanup_service.py +5 -0
  373. claude_mpm/services/cli/agent_listing_service.py +5 -5
  374. claude_mpm/services/cli/agent_validation_service.py +3 -1
  375. claude_mpm/services/cli/memory_crud_service.py +12 -7
  376. claude_mpm/services/cli/memory_output_formatter.py +2 -2
  377. claude_mpm/services/cli/resume_service.py +617 -0
  378. claude_mpm/services/cli/session_manager.py +104 -13
  379. claude_mpm/services/cli/session_pause_manager.py +504 -0
  380. claude_mpm/services/cli/session_resume_helper.py +372 -0
  381. claude_mpm/services/cli/startup_checker.py +13 -10
  382. claude_mpm/services/cli/unified_dashboard_manager.py +439 -0
  383. claude_mpm/services/command_deployment_service.py +209 -13
  384. claude_mpm/services/command_handler_service.py +11 -5
  385. claude_mpm/services/core/__init__.py +33 -1
  386. claude_mpm/services/core/base.py +31 -11
  387. claude_mpm/services/core/interfaces/__init__.py +88 -3
  388. claude_mpm/services/core/interfaces/agent.py +184 -0
  389. claude_mpm/services/core/interfaces/health.py +169 -0
  390. claude_mpm/services/core/interfaces/model.py +281 -0
  391. claude_mpm/services/core/interfaces/process.py +372 -0
  392. claude_mpm/services/core/interfaces/project.py +121 -0
  393. claude_mpm/services/core/interfaces/restart.py +307 -0
  394. claude_mpm/services/core/interfaces/stability.py +260 -0
  395. claude_mpm/services/core/interfaces.py +56 -1
  396. claude_mpm/services/core/memory_manager.py +92 -47
  397. claude_mpm/services/core/models/__init__.py +70 -0
  398. claude_mpm/services/core/models/agent_config.py +384 -0
  399. claude_mpm/services/core/models/health.py +162 -0
  400. claude_mpm/services/core/models/process.py +239 -0
  401. claude_mpm/services/core/models/restart.py +302 -0
  402. claude_mpm/services/core/models/stability.py +264 -0
  403. claude_mpm/services/core/models/toolchain.py +306 -0
  404. claude_mpm/services/core/path_resolver.py +36 -14
  405. claude_mpm/services/diagnostics/__init__.py +2 -2
  406. claude_mpm/services/diagnostics/checks/__init__.py +8 -2
  407. claude_mpm/services/diagnostics/checks/agent_check.py +30 -34
  408. claude_mpm/services/diagnostics/checks/agent_sources_check.py +577 -0
  409. claude_mpm/services/diagnostics/checks/claude_code_check.py +270 -0
  410. claude_mpm/services/diagnostics/checks/common_issues_check.py +28 -27
  411. claude_mpm/services/diagnostics/checks/configuration_check.py +26 -25
  412. claude_mpm/services/diagnostics/checks/filesystem_check.py +18 -17
  413. claude_mpm/services/diagnostics/checks/installation_check.py +165 -60
  414. claude_mpm/services/diagnostics/checks/instructions_check.py +21 -21
  415. claude_mpm/services/diagnostics/checks/mcp_check.py +57 -44
  416. claude_mpm/services/diagnostics/checks/mcp_services_check.py +1058 -0
  417. claude_mpm/services/diagnostics/checks/monitor_check.py +24 -24
  418. claude_mpm/services/diagnostics/checks/skill_sources_check.py +587 -0
  419. claude_mpm/services/diagnostics/checks/startup_log_check.py +14 -11
  420. claude_mpm/services/diagnostics/diagnostic_runner.py +31 -13
  421. claude_mpm/services/diagnostics/doctor_reporter.py +305 -47
  422. claude_mpm/services/diagnostics/models.py +37 -21
  423. claude_mpm/services/event_aggregator.py +5 -3
  424. claude_mpm/services/event_bus/direct_relay.py +11 -7
  425. claude_mpm/services/event_bus/event_bus.py +51 -9
  426. claude_mpm/services/event_bus/relay.py +33 -14
  427. claude_mpm/services/events/consumers/dead_letter.py +7 -5
  428. claude_mpm/services/events/consumers/logging.py +1 -2
  429. claude_mpm/services/events/core.py +5 -6
  430. claude_mpm/services/events/producers/hook.py +6 -6
  431. claude_mpm/services/events/producers/system.py +8 -8
  432. claude_mpm/services/exceptions.py +5 -5
  433. claude_mpm/services/framework_claude_md_generator/__init__.py +1 -1
  434. claude_mpm/services/framework_claude_md_generator/content_assembler.py +5 -5
  435. claude_mpm/services/framework_claude_md_generator/content_validator.py +2 -2
  436. claude_mpm/services/framework_claude_md_generator/deployment_manager.py +3 -3
  437. claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +2 -2
  438. claude_mpm/services/framework_claude_md_generator/version_manager.py +1 -1
  439. claude_mpm/services/git/__init__.py +21 -0
  440. claude_mpm/services/git/git_operations_service.py +494 -0
  441. claude_mpm/services/github/__init__.py +21 -0
  442. claude_mpm/services/github/github_cli_service.py +397 -0
  443. claude_mpm/services/hook_installer_service.py +506 -0
  444. claude_mpm/services/hook_service.py +5 -6
  445. claude_mpm/services/infrastructure/context_preservation.py +13 -11
  446. claude_mpm/services/infrastructure/daemon_manager.py +9 -9
  447. claude_mpm/services/infrastructure/logging.py +2 -2
  448. claude_mpm/services/infrastructure/monitoring/__init__.py +2 -6
  449. claude_mpm/services/infrastructure/monitoring/aggregator.py +13 -18
  450. claude_mpm/services/infrastructure/monitoring/base.py +5 -13
  451. claude_mpm/services/infrastructure/monitoring/network.py +7 -6
  452. claude_mpm/services/infrastructure/monitoring/process.py +13 -12
  453. claude_mpm/services/infrastructure/monitoring/resources.py +8 -7
  454. claude_mpm/services/infrastructure/monitoring/service.py +16 -15
  455. claude_mpm/services/infrastructure/resume_log_generator.py +439 -0
  456. claude_mpm/services/instructions/__init__.py +9 -0
  457. claude_mpm/services/instructions/instruction_cache_service.py +374 -0
  458. claude_mpm/services/local_ops/__init__.py +155 -0
  459. claude_mpm/services/local_ops/crash_detector.py +257 -0
  460. claude_mpm/services/local_ops/health_checks/__init__.py +26 -0
  461. claude_mpm/services/local_ops/health_checks/http_check.py +224 -0
  462. claude_mpm/services/local_ops/health_checks/process_check.py +236 -0
  463. claude_mpm/services/local_ops/health_checks/resource_check.py +255 -0
  464. claude_mpm/services/local_ops/health_manager.py +427 -0
  465. claude_mpm/services/local_ops/log_monitor.py +396 -0
  466. claude_mpm/services/local_ops/memory_leak_detector.py +294 -0
  467. claude_mpm/services/local_ops/process_manager.py +595 -0
  468. claude_mpm/services/local_ops/resource_monitor.py +331 -0
  469. claude_mpm/services/local_ops/restart_manager.py +401 -0
  470. claude_mpm/services/local_ops/restart_policy.py +387 -0
  471. claude_mpm/services/local_ops/state_manager.py +372 -0
  472. claude_mpm/services/local_ops/unified_manager.py +600 -0
  473. claude_mpm/services/mcp_config_manager.py +1542 -0
  474. claude_mpm/services/mcp_gateway/__init__.py +97 -93
  475. claude_mpm/services/mcp_gateway/auto_configure.py +43 -38
  476. claude_mpm/services/mcp_gateway/config/config_loader.py +3 -3
  477. claude_mpm/services/mcp_gateway/config/configuration.py +24 -5
  478. claude_mpm/services/mcp_gateway/core/__init__.py +1 -2
  479. claude_mpm/services/mcp_gateway/core/base.py +20 -33
  480. claude_mpm/services/mcp_gateway/core/process_pool.py +591 -31
  481. claude_mpm/services/mcp_gateway/core/singleton_manager.py +2 -2
  482. claude_mpm/services/mcp_gateway/core/startup_verification.py +3 -3
  483. claude_mpm/services/mcp_gateway/main.py +90 -15
  484. claude_mpm/services/mcp_gateway/registry/service_registry.py +4 -2
  485. claude_mpm/services/mcp_gateway/registry/tool_registry.py +12 -9
  486. claude_mpm/services/mcp_gateway/server/mcp_gateway.py +5 -10
  487. claude_mpm/services/mcp_gateway/server/stdio_server.py +9 -17
  488. claude_mpm/services/mcp_gateway/tools/__init__.py +14 -2
  489. claude_mpm/services/mcp_gateway/tools/base_adapter.py +15 -15
  490. claude_mpm/services/mcp_gateway/tools/document_summarizer.py +10 -9
  491. claude_mpm/services/mcp_gateway/tools/external_mcp_services.py +654 -0
  492. claude_mpm/services/mcp_gateway/tools/health_check_tool.py +36 -34
  493. claude_mpm/services/mcp_gateway/tools/hello_world.py +8 -8
  494. claude_mpm/services/mcp_gateway/tools/kuzu_memory_service.py +555 -0
  495. claude_mpm/services/mcp_gateway/utils/__init__.py +14 -0
  496. claude_mpm/services/mcp_gateway/utils/package_version_checker.py +160 -0
  497. claude_mpm/services/mcp_gateway/utils/update_preferences.py +170 -0
  498. claude_mpm/services/mcp_service_verifier.py +732 -0
  499. claude_mpm/services/memory/builder.py +9 -8
  500. claude_mpm/services/memory/cache/shared_prompt_cache.py +2 -1
  501. claude_mpm/services/memory/cache/simple_cache.py +2 -2
  502. claude_mpm/services/memory/failure_tracker.py +578 -0
  503. claude_mpm/services/memory/indexed_memory.py +8 -8
  504. claude_mpm/services/memory/optimizer.py +8 -9
  505. claude_mpm/services/memory/router.py +3 -3
  506. claude_mpm/services/memory_hook_service.py +165 -4
  507. claude_mpm/services/model/__init__.py +147 -0
  508. claude_mpm/services/model/base_provider.py +365 -0
  509. claude_mpm/services/model/claude_provider.py +412 -0
  510. claude_mpm/services/model/model_router.py +452 -0
  511. claude_mpm/services/model/ollama_provider.py +415 -0
  512. claude_mpm/services/monitor/__init__.py +20 -0
  513. claude_mpm/services/monitor/daemon.py +691 -0
  514. claude_mpm/services/monitor/daemon_manager.py +1040 -0
  515. claude_mpm/services/monitor/event_emitter.py +350 -0
  516. claude_mpm/services/monitor/handlers/__init__.py +21 -0
  517. claude_mpm/services/monitor/handlers/code_analysis.py +332 -0
  518. claude_mpm/services/monitor/handlers/dashboard.py +299 -0
  519. claude_mpm/services/monitor/handlers/file.py +264 -0
  520. claude_mpm/services/monitor/handlers/hooks.py +512 -0
  521. claude_mpm/services/monitor/management/__init__.py +18 -0
  522. claude_mpm/services/monitor/management/health.py +124 -0
  523. claude_mpm/services/monitor/management/lifecycle.py +724 -0
  524. claude_mpm/services/monitor/server.py +817 -0
  525. claude_mpm/services/monitor_build_service.py +2 -2
  526. claude_mpm/services/native_agent_converter.py +356 -0
  527. claude_mpm/services/orphan_detection.py +786 -0
  528. claude_mpm/services/port_manager.py +3 -3
  529. claude_mpm/services/pr/__init__.py +14 -0
  530. claude_mpm/services/pr/pr_template_service.py +329 -0
  531. claude_mpm/services/project/__init__.py +23 -0
  532. claude_mpm/services/project/analyzer.py +3 -3
  533. claude_mpm/services/project/architecture_analyzer.py +5 -5
  534. claude_mpm/services/project/archive_manager.py +1045 -0
  535. claude_mpm/services/project/dependency_analyzer.py +4 -4
  536. claude_mpm/services/project/detection_strategies.py +719 -0
  537. claude_mpm/services/project/documentation_manager.py +554 -0
  538. claude_mpm/services/project/enhanced_analyzer.py +572 -0
  539. claude_mpm/services/project/metrics_collector.py +4 -4
  540. claude_mpm/services/project/project_organizer.py +1005 -0
  541. claude_mpm/services/project/registry.py +13 -7
  542. claude_mpm/services/project/toolchain_analyzer.py +583 -0
  543. claude_mpm/services/project_port_allocator.py +596 -0
  544. claude_mpm/services/response_tracker.py +21 -10
  545. claude_mpm/services/runner_configuration_service.py +17 -3
  546. claude_mpm/services/self_upgrade_service.py +500 -0
  547. claude_mpm/services/session_management_service.py +23 -9
  548. claude_mpm/services/session_manager.py +380 -0
  549. claude_mpm/services/shared/__init__.py +2 -1
  550. claude_mpm/services/shared/async_service_base.py +16 -27
  551. claude_mpm/services/shared/config_service_base.py +17 -14
  552. claude_mpm/services/shared/lifecycle_service_base.py +1 -14
  553. claude_mpm/services/shared/service_factory.py +8 -5
  554. claude_mpm/services/skills/__init__.py +18 -0
  555. claude_mpm/services/skills/git_skill_source_manager.py +1169 -0
  556. claude_mpm/services/skills/skill_discovery_service.py +568 -0
  557. claude_mpm/services/skills_config.py +547 -0
  558. claude_mpm/services/skills_deployer.py +955 -0
  559. claude_mpm/services/socketio/client_proxy.py +60 -5
  560. claude_mpm/services/socketio/dashboard_server.py +361 -0
  561. claude_mpm/services/socketio/event_normalizer.py +10 -6
  562. claude_mpm/services/socketio/handlers/__init__.py +5 -2
  563. claude_mpm/services/socketio/handlers/base.py +2 -2
  564. claude_mpm/services/socketio/handlers/code_analysis.py +90 -27
  565. claude_mpm/services/socketio/handlers/connection.py +22 -41
  566. claude_mpm/services/socketio/handlers/connection_handler.py +13 -10
  567. claude_mpm/services/socketio/handlers/file.py +46 -10
  568. claude_mpm/services/socketio/handlers/git.py +9 -9
  569. claude_mpm/services/socketio/handlers/hook.py +29 -17
  570. claude_mpm/services/socketio/handlers/registry.py +4 -2
  571. claude_mpm/services/socketio/monitor_client.py +364 -0
  572. claude_mpm/services/socketio/server/broadcaster.py +9 -7
  573. claude_mpm/services/socketio/server/connection_manager.py +2 -2
  574. claude_mpm/services/socketio/server/core.py +142 -8
  575. claude_mpm/services/socketio/server/eventbus_integration.py +20 -14
  576. claude_mpm/services/socketio/server/main.py +24 -24
  577. claude_mpm/services/socketio_client_manager.py +4 -4
  578. claude_mpm/services/subprocess_launcher_service.py +19 -15
  579. claude_mpm/services/system_instructions_service.py +3 -5
  580. claude_mpm/services/ticket_services/formatter_service.py +1 -1
  581. claude_mpm/services/ticket_services/validation_service.py +5 -5
  582. claude_mpm/services/unified/__init__.py +65 -0
  583. claude_mpm/services/unified/analyzer_strategies/__init__.py +44 -0
  584. claude_mpm/services/unified/analyzer_strategies/code_analyzer.py +518 -0
  585. claude_mpm/services/unified/analyzer_strategies/dependency_analyzer.py +680 -0
  586. claude_mpm/services/unified/analyzer_strategies/performance_analyzer.py +900 -0
  587. claude_mpm/services/unified/analyzer_strategies/security_analyzer.py +745 -0
  588. claude_mpm/services/unified/analyzer_strategies/structure_analyzer.py +733 -0
  589. claude_mpm/services/unified/config_strategies/__init__.py +175 -0
  590. claude_mpm/services/unified/config_strategies/config_schema.py +731 -0
  591. claude_mpm/services/unified/config_strategies/context_strategy.py +747 -0
  592. claude_mpm/services/unified/config_strategies/error_handling_strategy.py +1005 -0
  593. claude_mpm/services/unified/config_strategies/file_loader_strategy.py +881 -0
  594. claude_mpm/services/unified/config_strategies/unified_config_service.py +823 -0
  595. claude_mpm/services/unified/config_strategies/validation_strategy.py +1148 -0
  596. claude_mpm/services/unified/deployment_strategies/__init__.py +97 -0
  597. claude_mpm/services/unified/deployment_strategies/base.py +553 -0
  598. claude_mpm/services/unified/deployment_strategies/cloud_strategies.py +573 -0
  599. claude_mpm/services/unified/deployment_strategies/local.py +607 -0
  600. claude_mpm/services/unified/deployment_strategies/utils.py +667 -0
  601. claude_mpm/services/unified/deployment_strategies/vercel.py +471 -0
  602. claude_mpm/services/unified/interfaces.py +475 -0
  603. claude_mpm/services/unified/migration.py +509 -0
  604. claude_mpm/services/unified/strategies.py +534 -0
  605. claude_mpm/services/unified/unified_analyzer.py +542 -0
  606. claude_mpm/services/unified/unified_config.py +691 -0
  607. claude_mpm/services/unified/unified_deployment.py +466 -0
  608. claude_mpm/services/utility_service.py +6 -3
  609. claude_mpm/services/version_control/branch_strategy.py +2 -2
  610. claude_mpm/services/version_control/conflict_resolution.py +14 -8
  611. claude_mpm/services/version_control/git_operations.py +26 -24
  612. claude_mpm/services/version_control/semantic_versioning.py +14 -14
  613. claude_mpm/services/version_control/version_parser.py +14 -11
  614. claude_mpm/services/version_service.py +104 -1
  615. claude_mpm/services/visualization/__init__.py +1 -5
  616. claude_mpm/services/visualization/mermaid_generator.py +2 -3
  617. claude_mpm/skills/__init__.py +42 -0
  618. claude_mpm/skills/agent_skills_injector.py +324 -0
  619. claude_mpm/skills/bundled/LICENSE_ATTRIBUTIONS.md +79 -0
  620. claude_mpm/skills/bundled/__init__.py +6 -0
  621. claude_mpm/skills/bundled/api-documentation.md +393 -0
  622. claude_mpm/skills/bundled/async-testing.md +571 -0
  623. claude_mpm/skills/bundled/code-review.md +143 -0
  624. claude_mpm/skills/bundled/database-migration.md +199 -0
  625. claude_mpm/skills/bundled/docker-containerization.md +194 -0
  626. claude_mpm/skills/bundled/express-local-dev.md +1429 -0
  627. claude_mpm/skills/bundled/fastapi-local-dev.md +1199 -0
  628. claude_mpm/skills/bundled/git-workflow.md +414 -0
  629. claude_mpm/skills/bundled/imagemagick.md +204 -0
  630. claude_mpm/skills/bundled/infrastructure/env-manager/scripts/validate_env.py +576 -0
  631. claude_mpm/skills/bundled/json-data-handling.md +223 -0
  632. claude_mpm/skills/bundled/main/mcp-builder/scripts/connections.py +157 -0
  633. claude_mpm/skills/bundled/main/mcp-builder/scripts/evaluation.py +425 -0
  634. claude_mpm/skills/bundled/main/skill-creator/scripts/init_skill.py +303 -0
  635. claude_mpm/skills/bundled/main/skill-creator/scripts/package_skill.py +113 -0
  636. claude_mpm/skills/bundled/main/skill-creator/scripts/quick_validate.py +72 -0
  637. claude_mpm/skills/bundled/nextjs-local-dev.md +807 -0
  638. claude_mpm/skills/bundled/pdf.md +141 -0
  639. claude_mpm/skills/bundled/performance-profiling.md +573 -0
  640. claude_mpm/skills/bundled/refactoring-patterns.md +180 -0
  641. claude_mpm/skills/bundled/security-scanning.md +327 -0
  642. claude_mpm/skills/bundled/systematic-debugging.md +473 -0
  643. claude_mpm/skills/bundled/test-driven-development.md +378 -0
  644. claude_mpm/skills/bundled/testing/webapp-testing/examples/console_logging.py +35 -0
  645. claude_mpm/skills/bundled/testing/webapp-testing/examples/element_discovery.py +44 -0
  646. claude_mpm/skills/bundled/testing/webapp-testing/examples/static_html_automation.py +34 -0
  647. claude_mpm/skills/bundled/testing/webapp-testing/scripts/with_server.py +129 -0
  648. claude_mpm/skills/bundled/vite-local-dev.md +1061 -0
  649. claude_mpm/skills/bundled/web-performance-optimization.md +2305 -0
  650. claude_mpm/skills/bundled/xlsx.md +157 -0
  651. claude_mpm/skills/registry.py +286 -0
  652. claude_mpm/skills/skill_manager.py +310 -0
  653. claude_mpm/skills/skills_registry.py +347 -0
  654. claude_mpm/skills/skills_service.py +739 -0
  655. claude_mpm/storage/state_storage.py +31 -31
  656. claude_mpm/templates/questions/__init__.py +38 -0
  657. claude_mpm/templates/questions/base.py +193 -0
  658. claude_mpm/templates/questions/pr_strategy.py +311 -0
  659. claude_mpm/templates/questions/project_init.py +385 -0
  660. claude_mpm/templates/questions/ticket_mgmt.py +394 -0
  661. claude_mpm/tools/__main__.py +9 -9
  662. claude_mpm/tools/code_tree_analyzer/__init__.py +45 -0
  663. claude_mpm/tools/code_tree_analyzer/analysis.py +299 -0
  664. claude_mpm/tools/code_tree_analyzer/cache.py +131 -0
  665. claude_mpm/tools/code_tree_analyzer/core.py +380 -0
  666. claude_mpm/tools/code_tree_analyzer/discovery.py +403 -0
  667. claude_mpm/tools/code_tree_analyzer/events.py +168 -0
  668. claude_mpm/tools/code_tree_analyzer/gitignore.py +308 -0
  669. claude_mpm/tools/code_tree_analyzer/models.py +39 -0
  670. claude_mpm/tools/code_tree_analyzer/multilang_analyzer.py +224 -0
  671. claude_mpm/tools/code_tree_analyzer/python_analyzer.py +284 -0
  672. claude_mpm/tools/code_tree_builder.py +6 -6
  673. claude_mpm/tools/code_tree_events.py +14 -10
  674. claude_mpm/tools/socketio_debug.py +11 -11
  675. claude_mpm/utils/agent_dependency_loader.py +184 -36
  676. claude_mpm/utils/agent_filters.py +288 -0
  677. claude_mpm/utils/common.py +544 -0
  678. claude_mpm/utils/config_manager.py +12 -6
  679. claude_mpm/utils/database_connector.py +298 -0
  680. claude_mpm/utils/dependency_cache.py +5 -3
  681. claude_mpm/utils/dependency_strategies.py +15 -10
  682. claude_mpm/utils/display_helper.py +260 -0
  683. claude_mpm/utils/environment_context.py +4 -3
  684. claude_mpm/utils/error_handler.py +5 -3
  685. claude_mpm/utils/file_utils.py +13 -14
  686. claude_mpm/utils/git_analyzer.py +407 -0
  687. claude_mpm/utils/gitignore.py +241 -0
  688. claude_mpm/utils/log_cleanup.py +627 -0
  689. claude_mpm/utils/migration.py +372 -0
  690. claude_mpm/utils/path_operations.py +7 -4
  691. claude_mpm/utils/progress.py +387 -0
  692. claude_mpm/utils/robust_installer.py +131 -24
  693. claude_mpm/utils/session_logging.py +2 -2
  694. claude_mpm/utils/structured_questions.py +619 -0
  695. claude_mpm/utils/subprocess_utils.py +9 -8
  696. claude_mpm/validation/agent_validator.py +6 -6
  697. claude_mpm/validation/frontmatter_validator.py +6 -6
  698. claude_mpm-5.0.9.dist-info/METADATA +1028 -0
  699. claude_mpm-5.0.9.dist-info/RECORD +864 -0
  700. {claude_mpm-4.1.26.dist-info → claude_mpm-5.0.9.dist-info}/entry_points.txt +1 -0
  701. claude_mpm/agents/INSTRUCTIONS.md +0 -261
  702. claude_mpm/agents/templates/.claude-mpm/memories/README.md +0 -17
  703. claude_mpm/agents/templates/.claude-mpm/memories/engineer_memories.md +0 -3
  704. claude_mpm/agents/templates/agent-manager.json +0 -270
  705. claude_mpm/agents/templates/agent-manager.md +0 -619
  706. claude_mpm/agents/templates/agentic_coder_optimizer.json +0 -222
  707. claude_mpm/agents/templates/api_qa.json +0 -171
  708. claude_mpm/agents/templates/code_analyzer.json +0 -95
  709. claude_mpm/agents/templates/data_engineer.json +0 -152
  710. claude_mpm/agents/templates/documentation.json +0 -175
  711. claude_mpm/agents/templates/engineer.json +0 -176
  712. claude_mpm/agents/templates/imagemagick.json +0 -261
  713. claude_mpm/agents/templates/logs/prompts/agent_engineer_20250826_014258_728.md +0 -39
  714. claude_mpm/agents/templates/memory_manager.json +0 -155
  715. claude_mpm/agents/templates/ops.json +0 -175
  716. claude_mpm/agents/templates/project_organizer.json +0 -130
  717. claude_mpm/agents/templates/qa.json +0 -223
  718. claude_mpm/agents/templates/refactoring_engineer.json +0 -266
  719. claude_mpm/agents/templates/research.json +0 -163
  720. claude_mpm/agents/templates/security.json +0 -153
  721. claude_mpm/agents/templates/ticketing.json +0 -169
  722. claude_mpm/agents/templates/vercel_ops_agent.json +0 -281
  723. claude_mpm/agents/templates/version_control.json +0 -147
  724. claude_mpm/agents/templates/web_qa.json +0 -254
  725. claude_mpm/agents/templates/web_ui.json +0 -176
  726. claude_mpm/cli/commands/configure_tui.py +0 -1927
  727. claude_mpm/cli/commands/mpm_init.py +0 -594
  728. claude_mpm/cli/commands/socketio_monitor.py +0 -233
  729. claude_mpm/commands/mpm-agents.md +0 -12
  730. claude_mpm/commands/mpm-config.md +0 -18
  731. claude_mpm/commands/mpm-tickets.md +0 -102
  732. claude_mpm/dashboard/.claude-mpm/socketio-instances.json +0 -1
  733. claude_mpm/dashboard/static/built/components/activity-tree.js +0 -2
  734. claude_mpm/dashboard/static/built/components/agent-inference.js +0 -2
  735. claude_mpm/dashboard/static/built/components/code-tree.js +0 -2
  736. claude_mpm/dashboard/static/built/components/code-viewer.js +0 -2
  737. claude_mpm/dashboard/static/built/components/event-processor.js +0 -2
  738. claude_mpm/dashboard/static/built/components/event-viewer.js +0 -2
  739. claude_mpm/dashboard/static/built/components/export-manager.js +0 -2
  740. claude_mpm/dashboard/static/built/components/file-tool-tracker.js +0 -2
  741. claude_mpm/dashboard/static/built/components/hud-library-loader.js +0 -2
  742. claude_mpm/dashboard/static/built/components/hud-manager.js +0 -2
  743. claude_mpm/dashboard/static/built/components/hud-visualizer.js +0 -2
  744. claude_mpm/dashboard/static/built/components/module-viewer.js +0 -2
  745. claude_mpm/dashboard/static/built/components/session-manager.js +0 -2
  746. claude_mpm/dashboard/static/built/components/socket-manager.js +0 -2
  747. claude_mpm/dashboard/static/built/components/ui-state-manager.js +0 -2
  748. claude_mpm/dashboard/static/built/components/unified-data-viewer.js +0 -2
  749. claude_mpm/dashboard/static/built/components/working-directory.js +0 -2
  750. claude_mpm/dashboard/static/built/dashboard.js +0 -2
  751. claude_mpm/dashboard/static/built/socket-client.js +0 -2
  752. claude_mpm/dashboard/static/css/code-tree.css +0 -1408
  753. claude_mpm/dashboard/static/dist/components/activity-tree.js +0 -2
  754. claude_mpm/dashboard/static/dist/components/agent-inference.js +0 -2
  755. claude_mpm/dashboard/static/dist/components/code-tree.js +0 -2
  756. claude_mpm/dashboard/static/dist/components/code-viewer.js +0 -2
  757. claude_mpm/dashboard/static/dist/components/event-processor.js +0 -2
  758. claude_mpm/dashboard/static/dist/components/event-viewer.js +0 -2
  759. claude_mpm/dashboard/static/dist/components/export-manager.js +0 -2
  760. claude_mpm/dashboard/static/dist/components/file-tool-tracker.js +0 -2
  761. claude_mpm/dashboard/static/dist/components/hud-library-loader.js +0 -2
  762. claude_mpm/dashboard/static/dist/components/hud-manager.js +0 -2
  763. claude_mpm/dashboard/static/dist/components/hud-visualizer.js +0 -2
  764. claude_mpm/dashboard/static/dist/components/module-viewer.js +0 -2
  765. claude_mpm/dashboard/static/dist/components/session-manager.js +0 -2
  766. claude_mpm/dashboard/static/dist/components/socket-manager.js +0 -2
  767. claude_mpm/dashboard/static/dist/components/ui-state-manager.js +0 -2
  768. claude_mpm/dashboard/static/dist/components/unified-data-viewer.js +0 -2
  769. claude_mpm/dashboard/static/dist/components/working-directory.js +0 -2
  770. claude_mpm/dashboard/static/dist/dashboard.js +0 -2
  771. claude_mpm/dashboard/static/dist/socket-client.js +0 -2
  772. claude_mpm/dashboard/static/js/components/code-tree.js +0 -3220
  773. claude_mpm/dashboard/static/js/components/code-viewer.js +0 -480
  774. claude_mpm/hooks/claude_hooks/hook_handler_eventbus.py +0 -425
  775. claude_mpm/hooks/claude_hooks/hook_handler_original.py +0 -1040
  776. claude_mpm/hooks/claude_hooks/hook_handler_refactored.py +0 -347
  777. claude_mpm/scripts/socketio_daemon_hardened.py +0 -937
  778. claude_mpm/scripts/socketio_daemon_wrapper.py +0 -78
  779. claude_mpm/scripts/socketio_server_manager.py +0 -349
  780. claude_mpm/services/agents/deployment/agent_lifecycle_manager_refactored.py +0 -575
  781. claude_mpm/services/cli/dashboard_launcher.py +0 -423
  782. claude_mpm/services/cli/socketio_manager.py +0 -537
  783. claude_mpm/services/diagnostics/checks/claude_desktop_check.py +0 -286
  784. claude_mpm/services/mcp_gateway/tools/ticket_tools.py +0 -645
  785. claude_mpm/services/mcp_gateway/tools/unified_ticket_tool.py +0 -602
  786. claude_mpm/services/project/analyzer_refactored.py +0 -450
  787. claude_mpm/tools/code_tree_analyzer.py +0 -1693
  788. claude_mpm-4.1.26.dist-info/METADATA +0 -332
  789. claude_mpm-4.1.26.dist-info/RECORD +0 -606
  790. {claude_mpm-4.1.26.dist-info → claude_mpm-5.0.9.dist-info}/WHEEL +0 -0
  791. {claude_mpm-4.1.26.dist-info → claude_mpm-5.0.9.dist-info}/licenses/LICENSE +0 -0
  792. {claude_mpm-4.1.26.dist-info → claude_mpm-5.0.9.dist-info}/top_level.txt +0 -0
@@ -8,9 +8,12 @@ maintainability and testability.
8
8
  """
9
9
 
10
10
  import json
11
+ import re
11
12
  from pathlib import Path
12
13
  from typing import Any, Dict, List
13
14
 
15
+ import yaml
16
+
14
17
  from claude_mpm.core.logging_config import get_logger
15
18
 
16
19
 
@@ -29,6 +32,301 @@ class AgentTemplateBuilder:
29
32
  """Initialize the template builder."""
30
33
  self.logger = get_logger(__name__)
31
34
 
35
+ def normalize_tools_input(self, tools):
36
+ """Normalize various tool input formats to a consistent list.
37
+
38
+ Handles multiple input formats:
39
+ - None/empty: Returns default tools
40
+ - String: Splits by comma and strips whitespace
41
+ - List: Ensures all items are strings and strips whitespace
42
+ - Dict: Takes enabled tools (where value is True)
43
+
44
+ Args:
45
+ tools: Tools input in various formats (str, list, dict, or None)
46
+
47
+ Returns:
48
+ List of tool names, normalized and cleaned
49
+ """
50
+ default_tools = ["Read", "Write", "Edit", "Grep", "Glob", "Bash"]
51
+
52
+ # Handle None or empty
53
+ if not tools:
54
+ self.logger.debug("No tools provided, using defaults")
55
+ return default_tools
56
+
57
+ # Convert to list format
58
+ if isinstance(tools, str):
59
+ # Split by comma, strip whitespace
60
+ tool_list = [t.strip() for t in tools.split(",") if t.strip()]
61
+ self.logger.debug(f"Converted string tools '{tools}' to list: {tool_list}")
62
+ elif isinstance(tools, list):
63
+ # Ensure all items are strings and strip whitespace
64
+ tool_list = [str(t).strip() for t in tools if t and str(t).strip()]
65
+ self.logger.debug(f"Normalized list tools: {tool_list}")
66
+ elif isinstance(tools, dict):
67
+ # Handle dict format - take enabled tools
68
+ tool_list = [k for k, v in tools.items() if v]
69
+ self.logger.info(f"Converting dict tools format: {tools} -> {tool_list}")
70
+ else:
71
+ self.logger.warning(f"Unknown tools format: {type(tools)}, using defaults")
72
+ return default_tools
73
+
74
+ # Return processed list or defaults if empty
75
+ if not tool_list:
76
+ self.logger.debug("Tools list empty after processing, using defaults")
77
+ return default_tools
78
+
79
+ return tool_list
80
+
81
+ def _discover_base_agent_templates(self, agent_file: Path) -> List[Path]:
82
+ """Discover BASE-AGENT.md files in hierarchy from agent file to repository root.
83
+
84
+ This method implements hierarchical BASE template discovery by walking up the
85
+ directory tree from the agent file location and collecting all BASE-AGENT.md
86
+ files found along the way.
87
+
88
+ Composition Order (closest to farthest):
89
+ 1. Local BASE-AGENT.md (same directory as agent)
90
+ 2. Parent BASE-AGENT.md (parent directory)
91
+ 3. Grandparent BASE-AGENT.md (grandparent directory)
92
+ ... continuing to repository root
93
+
94
+ Args:
95
+ agent_file: Path to the agent template file
96
+
97
+ Returns:
98
+ List of BASE-AGENT.md paths ordered from closest to farthest
99
+ (same directory to root)
100
+
101
+ Example:
102
+ Given structure:
103
+ repo/
104
+ BASE-AGENT.md # Root (index 2)
105
+ engineering/
106
+ BASE-AGENT.md # Parent (index 1)
107
+ python/
108
+ BASE-AGENT.md # Local (index 0)
109
+ fastapi-engineer.md # Agent file
110
+
111
+ Returns: [
112
+ repo/engineering/python/BASE-AGENT.md,
113
+ repo/engineering/BASE-AGENT.md,
114
+ repo/BASE-AGENT.md
115
+ ]
116
+ """
117
+ base_templates = []
118
+ current_dir = agent_file.parent
119
+
120
+ # Walk up directory tree until we reach root or a reasonable limit
121
+ # Stop at repository root or after 10 levels (safety limit)
122
+ max_depth = 10
123
+ depth = 0
124
+
125
+ while current_dir and depth < max_depth:
126
+ # Check for BASE-AGENT.md in current directory
127
+ base_agent_file = current_dir / "BASE-AGENT.md"
128
+ if base_agent_file.exists() and base_agent_file.is_file():
129
+ base_templates.append(base_agent_file)
130
+ self.logger.debug(f"Found BASE-AGENT.md at: {base_agent_file}")
131
+
132
+ # Stop at git repository root if detected
133
+ if (current_dir / ".git").exists():
134
+ self.logger.debug(f"Reached git repository root at: {current_dir}")
135
+ break
136
+
137
+ # Stop at common repository root indicators
138
+ if current_dir.name in [".claude-mpm", "remote-agents", "cache"]:
139
+ self.logger.debug(
140
+ f"Reached repository root indicator at: {current_dir}"
141
+ )
142
+ break
143
+
144
+ # Move to parent directory
145
+ parent = current_dir.parent
146
+ if parent == current_dir: # Reached filesystem root
147
+ break
148
+
149
+ current_dir = parent
150
+ depth += 1
151
+
152
+ if base_templates:
153
+ self.logger.info(
154
+ f"Discovered {len(base_templates)} BASE-AGENT.md file(s) for {agent_file.name}"
155
+ )
156
+
157
+ return base_templates
158
+
159
+ def _parse_markdown_template(self, template_path: Path) -> dict:
160
+ """Parse Markdown template with YAML frontmatter.
161
+
162
+ Extracts metadata from YAML frontmatter and content from Markdown body.
163
+ Supports the new agent template format with YAML frontmatter between --- delimiters.
164
+
165
+ Args:
166
+ template_path: Path to the Markdown template file
167
+
168
+ Returns:
169
+ Dictionary containing metadata and instructions
170
+
171
+ Raises:
172
+ ValueError: If frontmatter is missing or malformed
173
+ yaml.YAMLError: If YAML parsing fails
174
+ """
175
+ content = template_path.read_text(encoding="utf-8")
176
+
177
+ # Split frontmatter and body
178
+ # Format: ---\n<yaml>\n---\n<markdown>
179
+ if not content.startswith("---"):
180
+ raise ValueError(
181
+ f"Markdown template missing YAML frontmatter: {template_path}"
182
+ )
183
+
184
+ # Split by --- delimiters
185
+ parts = content.split("---", 2)
186
+ if len(parts) < 3:
187
+ raise ValueError(f"Malformed YAML frontmatter in template: {template_path}")
188
+
189
+ # parts[0] is empty (before first ---)
190
+ # parts[1] is YAML frontmatter
191
+ # parts[2] is Markdown content
192
+ yaml_content = parts[1].strip()
193
+ markdown_content = parts[2].strip()
194
+
195
+ # Parse YAML frontmatter
196
+ try:
197
+ metadata = yaml.safe_load(yaml_content)
198
+ if not isinstance(metadata, dict):
199
+ raise ValueError(
200
+ f"YAML frontmatter must be a dictionary: {template_path}"
201
+ )
202
+ except yaml.YAMLError as e:
203
+ self.logger.error(
204
+ f"Failed to parse YAML frontmatter in {template_path}: {e}"
205
+ )
206
+ raise
207
+
208
+ # Validate required fields
209
+ required_fields = ["name", "description", "version"]
210
+ missing_fields = [field for field in required_fields if field not in metadata]
211
+ if missing_fields:
212
+ raise ValueError(
213
+ f"Missing required fields in template {template_path}: {missing_fields}"
214
+ )
215
+
216
+ # Add the markdown content as instructions field
217
+ metadata["instructions"] = markdown_content
218
+
219
+ # Normalize metadata structure to match JSON template format
220
+ # JSON templates have these fields at top level, Markdown may have them nested
221
+ self._normalize_metadata_structure(metadata)
222
+
223
+ return metadata
224
+
225
+ def _normalize_metadata_structure(self, metadata: dict) -> None:
226
+ """Normalize metadata structure to match expected JSON template format.
227
+
228
+ This ensures both Markdown and JSON templates produce the same metadata structure
229
+ for downstream processing.
230
+
231
+ Args:
232
+ metadata: Metadata dictionary to normalize (modified in-place)
233
+ """
234
+ # Map Markdown frontmatter fields to JSON template structure
235
+ # Handle tags: YAML list vs JSON comma-separated string
236
+ if "tags" in metadata and isinstance(metadata["tags"], list):
237
+ # Keep as list for now, normalize_tools_input will handle both formats
238
+ pass
239
+
240
+ # Map agent_id to name if name is missing
241
+ if "agent_id" in metadata and "name" not in metadata:
242
+ metadata["name"] = metadata["agent_id"]
243
+
244
+ # Ensure capabilities dict exists
245
+ if "capabilities" not in metadata:
246
+ metadata["capabilities"] = {}
247
+
248
+ # Merge top-level capability fields into capabilities dict
249
+ capability_fields = ["memory_limit", "cpu_limit", "network_access"]
250
+ for field in capability_fields:
251
+ if field in metadata:
252
+ metadata["capabilities"][field] = metadata.pop(field)
253
+
254
+ # Add model to capabilities if present at top level
255
+ if "model" in metadata and "model" not in metadata["capabilities"]:
256
+ metadata["capabilities"]["model"] = metadata["model"]
257
+
258
+ def _load_base_agent_instructions(self, agent_type: str) -> str:
259
+ """Load BASE instructions for a specific agent type.
260
+
261
+ DEPRECATED: This method loads BASE_{TYPE}.md files (old pattern).
262
+ New pattern uses hierarchical BASE-AGENT.md files discovered via
263
+ _discover_base_agent_templates() and composed in build_agent_markdown().
264
+
265
+ Args:
266
+ agent_type: The type of agent (engineer, qa, ops, research, documentation)
267
+
268
+ Returns:
269
+ The BASE instructions content or empty string if not found
270
+ """
271
+ if not agent_type:
272
+ return ""
273
+
274
+ try:
275
+ # Construct BASE file name
276
+ base_file = f"BASE_{agent_type.upper()}.md"
277
+
278
+ # Try to find BASE file in agents directory
279
+ # First try current working directory structure
280
+ agents_dir = Path(__file__).parent.parent.parent.parent / "agents"
281
+ base_path = agents_dir / base_file
282
+
283
+ if not base_path.exists():
284
+ # Try packaged resources if available
285
+ try:
286
+ from importlib.resources import files
287
+
288
+ agents_package = files("claude_mpm.agents")
289
+ base_resource = agents_package / base_file
290
+ if base_resource.is_file():
291
+ content = base_resource.read_text(encoding="utf-8")
292
+ self.logger.debug(
293
+ f"Loaded BASE instructions from package: {base_file}"
294
+ )
295
+ return content
296
+ except (ImportError, Exception) as e:
297
+ self.logger.debug(
298
+ f"Could not load BASE instructions from package: {e}"
299
+ )
300
+
301
+ # Final fallback - try multiple possible locations
302
+ possible_paths = [
303
+ Path.cwd() / "src" / "claude_mpm" / "agents" / base_file,
304
+ Path(__file__).parent.parent.parent.parent / "agents" / base_file,
305
+ Path.home() / ".claude-mpm" / "agents" / base_file,
306
+ ]
307
+
308
+ for path in possible_paths:
309
+ if path.exists():
310
+ base_path = path
311
+ break
312
+ else:
313
+ self.logger.debug(
314
+ f"No BASE instructions found for type: {agent_type}"
315
+ )
316
+ return ""
317
+
318
+ if base_path.exists():
319
+ self.logger.debug(f"Loading BASE instructions from {base_path}")
320
+ return base_path.read_text(encoding="utf-8")
321
+ self.logger.debug(f"No BASE instructions found for type: {agent_type}")
322
+ return ""
323
+
324
+ except Exception as e:
325
+ self.logger.warning(
326
+ f"Error loading BASE instructions for {agent_type}: {e}"
327
+ )
328
+ return ""
329
+
32
330
  def build_agent_markdown(
33
331
  self,
34
332
  agent_name: str,
@@ -41,7 +339,7 @@ class AgentTemplateBuilder:
41
339
 
42
340
  Args:
43
341
  agent_name: Name of the agent
44
- template_path: Path to the agent template JSON file
342
+ template_path: Path to the agent template (JSON or Markdown file)
45
343
  base_agent_data: Base agent configuration data
46
344
  source_info: Source of the agent (system/project/user)
47
345
 
@@ -51,16 +349,34 @@ class AgentTemplateBuilder:
51
349
  Raises:
52
350
  FileNotFoundError: If template file doesn't exist
53
351
  json.JSONDecodeError: If template JSON is invalid
352
+ yaml.YAMLError: If template YAML is invalid
353
+ ValueError: If template format is unsupported or malformed
54
354
  """
55
355
  if not template_path.exists():
56
356
  raise FileNotFoundError(f"Template file not found: {template_path}")
57
357
 
358
+ # Format detection: route to appropriate parser
58
359
  try:
59
- template_content = template_path.read_text()
60
- template_data = json.loads(template_content)
360
+ if template_path.suffix == ".md":
361
+ # Parse Markdown template with YAML frontmatter
362
+ self.logger.debug(f"Parsing Markdown template: {template_path}")
363
+ template_data = self._parse_markdown_template(template_path)
364
+ elif template_path.suffix == ".json":
365
+ # Parse JSON template (legacy format)
366
+ self.logger.debug(f"Parsing JSON template: {template_path}")
367
+ template_content = template_path.read_text()
368
+ template_data = json.loads(template_content)
369
+ else:
370
+ raise ValueError(
371
+ f"Unsupported template format: {template_path.suffix}. "
372
+ f"Expected .md or .json"
373
+ )
61
374
  except json.JSONDecodeError as e:
62
375
  self.logger.error(f"Invalid JSON in template {template_path}: {e}")
63
376
  raise
377
+ except (yaml.YAMLError, ValueError) as e:
378
+ self.logger.error(f"Invalid template {template_path}: {e}")
379
+ raise
64
380
 
65
381
  # Extract tools from template with fallback
66
382
  # Handle both dict and list formats for capabilities (backward compatibility)
@@ -69,13 +385,39 @@ class AgentTemplateBuilder:
69
385
  capabilities.get("tools") if isinstance(capabilities, dict) else None
70
386
  )
71
387
 
72
- tools = (
388
+ # Get raw tools from various possible locations
389
+ raw_tools = (
73
390
  template_data.get("tools")
74
391
  or capabilities_tools
75
392
  or template_data.get("configuration_fields", {}).get("tools")
76
- or ["Read", "Write", "Edit", "Grep", "Glob", "LS"] # Default fallback
77
393
  )
78
394
 
395
+ # Normalize tools to a consistent list format
396
+ tools = self.normalize_tools_input(raw_tools)
397
+
398
+ # Log if we see non-standard tool names (info level, not warning)
399
+ standard_tools = {
400
+ "Read",
401
+ "Write",
402
+ "Edit",
403
+ "MultiEdit", # File operations
404
+ "Grep",
405
+ "Glob",
406
+ "LS", # Search and navigation
407
+ "Bash",
408
+ "BashOutput",
409
+ "KillShell", # Command execution
410
+ "TodoWrite",
411
+ "ExitPlanMode", # Task management
412
+ "WebSearch",
413
+ "WebFetch", # Web operations
414
+ "NotebookRead",
415
+ "NotebookEdit", # Jupyter notebook support
416
+ }
417
+ non_standard = [t for t in tools if t not in standard_tools]
418
+ if non_standard:
419
+ self.logger.info(f"Using non-standard tools: {non_standard}")
420
+
79
421
  # Extract model from template with fallback
80
422
  capabilities_model = (
81
423
  capabilities.get("model") if isinstance(capabilities, dict) else None
@@ -88,19 +430,14 @@ class AgentTemplateBuilder:
88
430
  or "sonnet" # Default fallback
89
431
  )
90
432
 
91
- # Convert tools list to comma-separated string (no spaces!)
92
- tools_str = ",".join(tools) if isinstance(tools, list) else str(tools)
93
-
94
- # Validate tools format - CRITICAL: No spaces allowed!
95
- if ", " in tools_str:
96
- self.logger.error(f"Tools contain spaces: '{tools_str}'")
97
- raise ValueError(
98
- f"Tools must be comma-separated WITHOUT spaces: {tools_str}"
99
- )
433
+ # Convert tools list to comma-separated string (without spaces for compatibility)
434
+ ",".join(tools)
100
435
 
101
- # Map model names to Claude Code format
436
+ # Map model names to Claude Code format (as required)
102
437
  model_map = {
103
438
  "claude-3-5-sonnet-20241022": "sonnet",
439
+ "claude-3-5-haiku-20241022": "haiku",
440
+ "claude-3-opus-20240229": "opus",
104
441
  "claude-3-5-sonnet": "sonnet",
105
442
  "claude-3-sonnet": "sonnet",
106
443
  "claude-3-haiku": "haiku",
@@ -112,6 +449,9 @@ class AgentTemplateBuilder:
112
449
 
113
450
  if model in model_map:
114
451
  model = model_map[model]
452
+ else:
453
+ # Default to sonnet if model not found in map
454
+ model = "sonnet"
115
455
 
116
456
  # Get response format from template or use base agent default
117
457
  template_data.get("response", {}).get("format", "structured")
@@ -122,8 +462,6 @@ class AgentTemplateBuilder:
122
462
  # CRITICAL: NO underscores allowed - they cause silent failures!
123
463
 
124
464
  # Validate the name before proceeding
125
- import re
126
-
127
465
  if not re.match(r"^[a-z0-9]+(-[a-z0-9]+)*$", claude_code_name):
128
466
  self.logger.error(
129
467
  f"Invalid agent name '{claude_code_name}' - must match ^[a-z0-9]+(-[a-z0-9]+)*$"
@@ -133,12 +471,17 @@ class AgentTemplateBuilder:
133
471
  )
134
472
 
135
473
  # Extract description from template with fallback
136
- description = (
474
+ raw_description = (
137
475
  template_data.get("description")
138
476
  or template_data.get("metadata", {}).get("description")
139
477
  or f"{agent_name.title()} agent for specialized tasks"
140
478
  )
141
479
 
480
+ # Convert to multiline format with examples for Claude Code compatibility
481
+ description = self._create_multiline_description(
482
+ raw_description, agent_name, template_data
483
+ )
484
+
142
485
  # Extract custom metadata fields
143
486
  metadata = template_data.get("metadata", {})
144
487
  agent_version = (
@@ -163,7 +506,7 @@ class AgentTemplateBuilder:
163
506
 
164
507
  if template_color:
165
508
  # Use the color specified in the template
166
- color = template_color
509
+ pass
167
510
  else:
168
511
  # Fallback to default color map based on agent type
169
512
  color_map = {
@@ -174,7 +517,7 @@ class AgentTemplateBuilder:
174
517
  "documentation": "cyan", # Changed default to match template preference
175
518
  "ops": "gray",
176
519
  }
177
- color = color_map.get(agent_type, "blue")
520
+ color_map.get(agent_type, "blue")
178
521
 
179
522
  # Check if we should include tools field (only if significantly restricting)
180
523
  # Claude Code approach: omit tools field unless specifically restricting
@@ -188,41 +531,58 @@ class AgentTemplateBuilder:
188
531
  has_core_tools = len(agent_tools.intersection(core_tools)) >= 5
189
532
 
190
533
  # Include tools field only if agent is clearly restricted (missing core tools or very few tools)
191
- include_tools_field = not has_core_tools or len(agent_tools) < 6
534
+ not has_core_tools or len(agent_tools) < 6
192
535
 
193
- # Build YAML frontmatter using Claude Code's minimal format
194
- # ONLY include fields that Claude Code recognizes
536
+ # Build YAML frontmatter with all relevant metadata from JSON template
537
+ # Include all fields that are useful for agent management and functionality
195
538
  #
196
- # CLAUDE CODE COMPATIBLE FORMAT:
539
+ # COMPREHENSIVE AGENT FRONTMATTER FORMAT:
197
540
  # - name: kebab-case agent name (required)
198
- # - description: when/why to use this agent (required)
199
- # - version: agent version for update tracking (recommended)
200
- # - tools: comma-separated tool list (optional, only if restricting)
201
- # - color, author, tags: metadata fields (optional)
541
+ # - description: when/why to use this agent with examples (required, multiline)
542
+ # - model: mapped model name (required)
543
+ # - type: agent type for categorization and functionality (optional but important)
544
+ # - category: organizational category (optional)
545
+ # - color: visual identifier (optional)
546
+ # - version: agent version for update tracking (optional)
547
+ # - author: creator information (optional)
548
+ # - created_at: creation timestamp (optional)
549
+ # - updated_at: last update timestamp (optional)
550
+ # - tags: list of tags for search and categorization (optional)
202
551
  frontmatter_lines = [
203
552
  "---",
204
553
  f"name: {claude_code_name}",
205
- f"description: {description}",
206
- f'version: "{agent_version}"',
207
554
  ]
208
555
 
209
- # Add optional metadata if available
556
+ # Add description as single-line YAML string with \n escapes
557
+ frontmatter_lines.append(
558
+ f"description: {self._format_description_for_yaml(description)}"
559
+ )
560
+
561
+ # Add model field (required for Claude Code)
562
+ frontmatter_lines.append(f"model: {model}")
563
+
564
+ # Add type field (important for agent categorization)
565
+ if agent_type and agent_type != "general":
566
+ frontmatter_lines.append(f"type: {agent_type}")
567
+
568
+ # Add optional metadata fields
210
569
  if metadata.get("color"):
211
570
  frontmatter_lines.append(f"color: {metadata['color']}")
212
- if metadata.get("author"):
213
- frontmatter_lines.append(f"author: {metadata['author']}")
214
- if metadata.get("tags"):
215
- frontmatter_lines.append("tags:")
216
- for tag in metadata["tags"][:10]: # Limit to 10 tags
217
- frontmatter_lines.append(f" - {tag}")
218
- if metadata.get("priority"):
219
- frontmatter_lines.append(f"priority: {metadata['priority']}")
220
571
  if metadata.get("category"):
221
572
  frontmatter_lines.append(f"category: {metadata['category']}")
222
-
223
- # Only include tools if restricting to subset
224
- if include_tools_field:
225
- frontmatter_lines.append(f"tools: {tools_str}")
573
+ # Always include version field to prevent deployment comparison issues
574
+ if agent_version:
575
+ frontmatter_lines.append(f'version: "{agent_version}"')
576
+ if metadata.get("author"):
577
+ frontmatter_lines.append(f'author: "{metadata["author"]}"')
578
+ if metadata.get("created_at"):
579
+ frontmatter_lines.append(f"created_at: {metadata['created_at']}")
580
+ if metadata.get("updated_at"):
581
+ frontmatter_lines.append(f"updated_at: {metadata['updated_at']}")
582
+ # Add tags as comma-separated string if they exist (consistent with tools format)
583
+ if metadata.get("tags") and isinstance(metadata["tags"], list):
584
+ tags_str = ",".join(metadata["tags"])
585
+ frontmatter_lines.append(f"tags: {tags_str}")
226
586
 
227
587
  frontmatter_lines.extend(
228
588
  [
@@ -234,12 +594,53 @@ class AgentTemplateBuilder:
234
594
  frontmatter = "\n".join(frontmatter_lines)
235
595
 
236
596
  # Get agent instructions from template data (primary) or base agent data (fallback)
237
- content = (
238
- template_data.get("instructions")
239
- or base_agent_data.get("content")
240
- or base_agent_data.get("instructions")
241
- or "# Agent Instructions\n\nThis agent provides specialized assistance."
242
- )
597
+ raw_instructions = template_data.get("instructions")
598
+
599
+ # Handle dictionary instructions format
600
+ if isinstance(raw_instructions, dict):
601
+ agent_specific_instructions = self._convert_instructions_dict_to_markdown(
602
+ raw_instructions
603
+ )
604
+ else:
605
+ agent_specific_instructions = (
606
+ raw_instructions
607
+ or base_agent_data.get("content")
608
+ or base_agent_data.get("instructions")
609
+ or "# Agent Instructions\n\nThis agent provides specialized assistance."
610
+ )
611
+
612
+ # Compose hierarchical BASE-AGENT.md templates
613
+ # Order: agent-specific + local BASE + parent BASE + ... + root BASE
614
+ content_parts = [agent_specific_instructions]
615
+
616
+ # Discover BASE-AGENT.md files in directory hierarchy
617
+ base_templates = self._discover_base_agent_templates(template_path)
618
+
619
+ # Append each BASE template (order: closest to farthest)
620
+ for base_template_path in base_templates:
621
+ try:
622
+ base_content = base_template_path.read_text(encoding="utf-8")
623
+ if base_content.strip():
624
+ content_parts.append(base_content)
625
+ self.logger.debug(
626
+ f"Composed BASE template: {base_template_path.relative_to(template_path.parent.parent) if template_path.parent.parent in base_template_path.parents else base_template_path.name}"
627
+ )
628
+ except Exception as e:
629
+ self.logger.warning(
630
+ f"Failed to read BASE template {base_template_path}: {e}"
631
+ )
632
+
633
+ # Fallback: Load legacy BASE_{TYPE}.md if no hierarchical templates found
634
+ if len(content_parts) == 1: # Only agent-specific instructions
635
+ legacy_base_instructions = self._load_base_agent_instructions(agent_type)
636
+ if legacy_base_instructions:
637
+ content_parts.append(legacy_base_instructions)
638
+ self.logger.debug(
639
+ f"Using legacy BASE_{agent_type.upper()}.md (no hierarchical BASE-AGENT.md found)"
640
+ )
641
+
642
+ # Join all parts with separator
643
+ content = "\n\n---\n\n".join(content_parts)
243
644
 
244
645
  # Add memory update instructions if not already present
245
646
  if "memory-update" not in content and "Remember" not in content:
@@ -316,7 +717,8 @@ Only include memories that are:
316
717
  )
317
718
 
318
719
  # Get tools and model with fallbacks
319
- tools = merged_config.get("tools", ["Read", "Write", "Edit"])
720
+ raw_tools = merged_config.get("tools")
721
+ tools = self.normalize_tools_input(raw_tools)
320
722
  model = merged_config.get("model", "sonnet")
321
723
 
322
724
  # Format tools as YAML list
@@ -464,3 +866,490 @@ tools:
464
866
  formatted_items.append(f"{indent_str}- {item}")
465
867
 
466
868
  return "\n".join(formatted_items)
869
+
870
+ def _create_multiline_description(
871
+ self, raw_description: str, agent_name: str, template_data: dict
872
+ ) -> str:
873
+ """
874
+ Create a comprehensive multiline description with examples for Claude Code compatibility.
875
+ Based on Claude's software-engineer.md format: detailed when/why description with examples.
876
+
877
+ Args:
878
+ raw_description: Original single-line description
879
+ agent_name: Name of the agent
880
+ template_data: Template data for extracting examples
881
+
882
+ Returns:
883
+ Formatted multiline description with examples in Claude Code format
884
+ """
885
+ raw_description = self._format_to_single_line(raw_description)
886
+
887
+ # Get agent type for creating targeted descriptions
888
+ agent_type = template_data.get("agent_type", "general")
889
+
890
+ # Create enhanced description based on agent type
891
+ enhanced_description = self._create_enhanced_description(
892
+ raw_description, agent_name, agent_type, template_data
893
+ )
894
+
895
+ # Add examples
896
+ examples = self._extract_examples_from_template(template_data, agent_name)
897
+ if not examples:
898
+ examples = self._generate_default_examples(agent_name, template_data)
899
+
900
+ # Combine enhanced description with examples
901
+ if examples:
902
+ description_parts = [enhanced_description, "", *examples]
903
+ else:
904
+ description_parts = [enhanced_description]
905
+
906
+ return "\n".join(description_parts)
907
+
908
+ def _format_to_single_line(self, description: str) -> str:
909
+ """
910
+ Format description to single line by removing line breaks and normalizing whitespace.
911
+
912
+ Args:
913
+ description: Raw description text
914
+
915
+ Returns:
916
+ Single-line formatted description
917
+ """
918
+ if not description:
919
+ return description
920
+
921
+ # Remove all line breaks and normalize whitespace
922
+ single_line = " ".join(description.strip().split())
923
+
924
+ # Remove redundant spaces around punctuation
925
+ single_line = re.sub(r"\s+([,.!?;:])", r"\1", single_line)
926
+ return re.sub(r"([,.!?;:])\s+", r"\1 ", single_line)
927
+
928
+ def _create_enhanced_description(
929
+ self,
930
+ raw_description: str,
931
+ agent_name: str,
932
+ agent_type: str,
933
+ template_data: dict,
934
+ ) -> str:
935
+ """
936
+ Create an enhanced description based on agent type that follows Claude's format.
937
+
938
+ Args:
939
+ raw_description: Original description
940
+ agent_name: Name of the agent
941
+ agent_type: Type of agent (engineer, qa, research, etc.)
942
+ template_data: Template data for additional context
943
+
944
+ Returns:
945
+ Enhanced description string
946
+ """
947
+ # Type-specific enhanced descriptions following Claude's software-engineer.md pattern
948
+ enhanced_descriptions = {
949
+ "engineer": "Use this agent when you need to implement new features, write production-quality code, refactor existing code, or solve complex programming challenges. This agent excels at translating requirements into well-architected, maintainable code solutions across various programming languages and frameworks.",
950
+ "qa": "Use this agent when you need comprehensive testing, quality assurance validation, or test automation. This agent specializes in creating robust test suites, identifying edge cases, and ensuring code quality through systematic testing approaches across different testing methodologies.",
951
+ "research": "Use this agent when you need to investigate codebases, analyze system architecture, or gather technical insights. This agent excels at code exploration, pattern identification, and providing comprehensive analysis of existing systems while maintaining strict memory efficiency.",
952
+ "ops": "Use this agent when you need infrastructure management, deployment automation, or operational excellence. This agent specializes in DevOps practices, cloud operations, monitoring setup, and maintaining reliable production systems.",
953
+ "security": "Use this agent when you need security analysis, vulnerability assessment, or secure coding practices. This agent excels at identifying security risks, implementing security best practices, and ensuring applications meet security standards.",
954
+ "documentation": "Use this agent when you need to create, update, or maintain technical documentation. This agent specializes in writing clear, comprehensive documentation including API docs, user guides, and technical specifications.",
955
+ }
956
+
957
+ # Get the enhanced description or fallback to the original with improvements
958
+ if agent_type in enhanced_descriptions:
959
+ return enhanced_descriptions[agent_type]
960
+ # Enhance the raw description if it's a custom type
961
+ if raw_description and len(raw_description) > 10:
962
+ return f"Use this agent when you need specialized assistance with {raw_description.lower()}. This agent provides targeted expertise and follows best practices for {agent_name.replace('-', ' ')} related tasks."
963
+ return f"Use this agent when you need specialized assistance from the {agent_name.replace('-', ' ')} agent. This agent provides targeted expertise and follows established best practices."
964
+
965
+ def _extract_examples_from_template(
966
+ self, template_data: dict, agent_name: str
967
+ ) -> List[str]:
968
+ """
969
+ Extract examples from template data and format with commentary.
970
+ Creates ONE example with commentary from template data.
971
+
972
+ Args:
973
+ template_data: Template data
974
+ agent_name: Name of the agent
975
+
976
+ Returns:
977
+ List of example strings (single example with commentary)
978
+ """
979
+ examples = []
980
+
981
+ # Check for examples in knowledge section
982
+ knowledge = template_data.get("knowledge", {})
983
+ template_examples = knowledge.get("examples", [])
984
+
985
+ if template_examples:
986
+ # Take only the first example and add commentary
987
+ example = template_examples[0]
988
+ scenario = example.get("scenario", "")
989
+ approach = example.get("approach", "")
990
+ commentary = example.get("commentary", "")
991
+
992
+ if scenario and approach:
993
+ examples.extend(
994
+ [
995
+ "<example>",
996
+ f"Context: {scenario}",
997
+ f'user: "I need help with {scenario.lower()}"',
998
+ f'assistant: "I\'ll use the {agent_name} agent to {approach.lower()}."',
999
+ "<commentary>",
1000
+ (
1001
+ commentary
1002
+ if commentary
1003
+ else f"This agent is well-suited for {scenario.lower()} because it specializes in {approach.lower()} with targeted expertise."
1004
+ ),
1005
+ "</commentary>",
1006
+ "</example>",
1007
+ ]
1008
+ )
1009
+
1010
+ # Check for triggers that can be converted to examples
1011
+ interactions = template_data.get("interactions", {})
1012
+ triggers = interactions.get("triggers", [])
1013
+
1014
+ if triggers and not examples:
1015
+ # Convert first trigger to example with commentary
1016
+ trigger = triggers[0]
1017
+
1018
+ # Handle both string and dict trigger formats
1019
+ if isinstance(trigger, dict):
1020
+ # New format with pattern and confidence
1021
+ trigger_text = trigger.get("pattern", "")
1022
+ else:
1023
+ # Old format with simple string
1024
+ trigger_text = str(trigger)
1025
+
1026
+ # Skip if we don't have valid trigger text
1027
+ if not trigger_text:
1028
+ return examples
1029
+
1030
+ agent_type = template_data.get("agent_type", "general")
1031
+
1032
+ examples.extend(
1033
+ [
1034
+ "<example>",
1035
+ f"Context: When user needs {trigger_text}",
1036
+ f'user: "{trigger_text}"',
1037
+ f'assistant: "I\'ll use the {agent_name} agent for {trigger_text}."',
1038
+ "<commentary>",
1039
+ f"This {agent_type} agent is appropriate because it has specialized capabilities for {trigger_text.lower()} tasks.",
1040
+ "</commentary>",
1041
+ "</example>",
1042
+ ]
1043
+ )
1044
+
1045
+ return examples
1046
+
1047
+ def _generate_default_examples(
1048
+ self, agent_name: str, template_data: dict
1049
+ ) -> List[str]:
1050
+ """
1051
+ Generate default examples when none are available in template.
1052
+ Creates ONE example with commentary for each agent type.
1053
+
1054
+ Args:
1055
+ agent_name: Name of the agent
1056
+ template_data: Template data for context
1057
+
1058
+ Returns:
1059
+ List of example strings (single example with commentary)
1060
+ """
1061
+ agent_type = template_data.get("agent_type", "general")
1062
+
1063
+ # Create type-specific examples with commentary inside
1064
+ type_examples = {
1065
+ "engineer": [
1066
+ "<example>",
1067
+ "Context: When you need to implement new features or write code.",
1068
+ 'user: "I need to add authentication to my API"',
1069
+ f'assistant: "I\'ll use the {agent_name} agent to implement a secure authentication system for your API."',
1070
+ "<commentary>",
1071
+ "The engineer agent is ideal for code implementation tasks because it specializes in writing production-quality code, following best practices, and creating well-architected solutions.",
1072
+ "</commentary>",
1073
+ "</example>",
1074
+ ],
1075
+ "ops": [
1076
+ "<example>",
1077
+ "Context: When you need to deploy or manage infrastructure.",
1078
+ 'user: "I need to deploy my application to the cloud"',
1079
+ f'assistant: "I\'ll use the {agent_name} agent to set up and deploy your application infrastructure."',
1080
+ "<commentary>",
1081
+ "The ops agent excels at infrastructure management and deployment automation, ensuring reliable and scalable production systems.",
1082
+ "</commentary>",
1083
+ "</example>",
1084
+ ],
1085
+ "qa": [
1086
+ "<example>",
1087
+ "Context: When you need to test or validate functionality.",
1088
+ 'user: "I need to write tests for my new feature"',
1089
+ f'assistant: "I\'ll use the {agent_name} agent to create comprehensive tests for your feature."',
1090
+ "<commentary>",
1091
+ "The QA agent specializes in comprehensive testing strategies, quality assurance validation, and creating robust test suites that ensure code reliability.",
1092
+ "</commentary>",
1093
+ "</example>",
1094
+ ],
1095
+ "research": [
1096
+ "<example>",
1097
+ "Context: When you need to investigate or analyze existing codebases.",
1098
+ 'user: "I need to understand how the authentication system works in this project"',
1099
+ f'assistant: "I\'ll use the {agent_name} agent to analyze the codebase and explain the authentication implementation."',
1100
+ "<commentary>",
1101
+ "The research agent is perfect for code exploration and analysis tasks, providing thorough investigation of existing systems while maintaining memory efficiency.",
1102
+ "</commentary>",
1103
+ "</example>",
1104
+ ],
1105
+ "security": [
1106
+ "<example>",
1107
+ "Context: When you need to review code for security vulnerabilities.",
1108
+ 'user: "I need a security review of my authentication implementation"',
1109
+ f'assistant: "I\'ll use the {agent_name} agent to conduct a thorough security analysis of your authentication code."',
1110
+ "<commentary>",
1111
+ "The security agent specializes in identifying security risks, vulnerability assessment, and ensuring applications meet security standards and best practices.",
1112
+ "</commentary>",
1113
+ "</example>",
1114
+ ],
1115
+ "documentation": [
1116
+ "<example>",
1117
+ "Context: When you need to create or update technical documentation.",
1118
+ 'user: "I need to document this new API endpoint"',
1119
+ f'assistant: "I\'ll use the {agent_name} agent to create comprehensive API documentation."',
1120
+ "<commentary>",
1121
+ "The documentation agent excels at creating clear, comprehensive technical documentation including API docs, user guides, and technical specifications.",
1122
+ "</commentary>",
1123
+ "</example>",
1124
+ ],
1125
+ }
1126
+
1127
+ return type_examples.get(
1128
+ agent_type,
1129
+ [
1130
+ "<example>",
1131
+ f"Context: When you need specialized assistance from the {agent_name} agent.",
1132
+ f'user: "I need help with {agent_name.replace("-", " ")} tasks"',
1133
+ f'assistant: "I\'ll use the {agent_name} agent to provide specialized assistance."',
1134
+ "<commentary>",
1135
+ f"This agent provides targeted expertise for {agent_name.replace('-', ' ')} related tasks and follows established best practices.",
1136
+ "</commentary>",
1137
+ "</example>",
1138
+ ],
1139
+ )
1140
+
1141
+ def _indent_multiline_text(self, text: str, spaces: int) -> str:
1142
+ """
1143
+ Indent multiline text with specified number of spaces.
1144
+
1145
+ Args:
1146
+ text: Text to indent
1147
+ spaces: Number of spaces for indentation
1148
+
1149
+ Returns:
1150
+ Indented text
1151
+ """
1152
+ if not text:
1153
+ return ""
1154
+
1155
+ indent = " " * spaces
1156
+ lines = text.split("\n")
1157
+ indented_lines = []
1158
+
1159
+ for line in lines:
1160
+ if line.strip(): # Non-empty lines get indented
1161
+ indented_lines.append(indent + line)
1162
+ else: # Empty lines stay empty
1163
+ indented_lines.append("")
1164
+
1165
+ return "\n".join(indented_lines)
1166
+
1167
+ def _format_description_for_yaml(self, description: str) -> str:
1168
+ """Format description as a single-line YAML string with escaped newlines.
1169
+
1170
+ Args:
1171
+ description: Multi-line description text
1172
+
1173
+ Returns:
1174
+ Single-line YAML-formatted string with \n escapes
1175
+ """
1176
+ if not description:
1177
+ return '""'
1178
+
1179
+ # The description already contains actual newlines, we need to escape them
1180
+ # Replace actual newlines with \n escape sequence
1181
+ escaped = description.replace("\n", "\\n")
1182
+
1183
+ # Escape any quotes in the description
1184
+ escaped = escaped.replace('"', '\\"')
1185
+
1186
+ # Return as quoted string
1187
+ return f'"{escaped}"'
1188
+
1189
+ def _convert_instructions_dict_to_markdown(self, instructions_dict: dict) -> str:
1190
+ """Convert complex instructions dictionary to markdown format.
1191
+
1192
+ Args:
1193
+ instructions_dict: Dictionary containing structured instructions
1194
+
1195
+ Returns:
1196
+ Formatted markdown string representing the instructions
1197
+ """
1198
+ if not instructions_dict:
1199
+ return "# Agent Instructions\n\nThis agent provides specialized assistance."
1200
+
1201
+ markdown_parts = []
1202
+
1203
+ # Add primary role
1204
+ if "primary_role" in instructions_dict:
1205
+ markdown_parts.extend(["# Role", "", instructions_dict["primary_role"], ""])
1206
+
1207
+ # Add core identity
1208
+ if "core_identity" in instructions_dict:
1209
+ markdown_parts.extend(
1210
+ ["## Core Identity", "", instructions_dict["core_identity"], ""]
1211
+ )
1212
+
1213
+ # Add responsibilities
1214
+ if "responsibilities" in instructions_dict:
1215
+ markdown_parts.extend(["## Responsibilities", ""])
1216
+
1217
+ responsibilities = instructions_dict["responsibilities"]
1218
+ if isinstance(responsibilities, list):
1219
+ for resp in responsibilities:
1220
+ if isinstance(resp, dict):
1221
+ area = resp.get("area", "Unknown Area")
1222
+ tasks = resp.get("tasks", [])
1223
+
1224
+ markdown_parts.extend([f"### {area}", ""])
1225
+
1226
+ if isinstance(tasks, list):
1227
+ for task in tasks:
1228
+ markdown_parts.append(f"- {task}")
1229
+
1230
+ markdown_parts.append("")
1231
+ else:
1232
+ markdown_parts.append(f"- {resp}")
1233
+
1234
+ markdown_parts.append("")
1235
+
1236
+ # Add analytical framework
1237
+ if "analytical_framework" in instructions_dict:
1238
+ framework = instructions_dict["analytical_framework"]
1239
+ if isinstance(framework, dict):
1240
+ markdown_parts.extend(["## Analytical Framework", ""])
1241
+
1242
+ for framework_area, framework_data in framework.items():
1243
+ markdown_parts.extend(
1244
+ [f"### {framework_area.replace('_', ' ').title()}", ""]
1245
+ )
1246
+
1247
+ if isinstance(framework_data, dict):
1248
+ for category, items in framework_data.items():
1249
+ markdown_parts.extend(
1250
+ [f"#### {category.replace('_', ' ').title()}", ""]
1251
+ )
1252
+
1253
+ if isinstance(items, list):
1254
+ for item in items:
1255
+ markdown_parts.append(f"- {item}")
1256
+ elif isinstance(items, str):
1257
+ markdown_parts.append(items)
1258
+
1259
+ markdown_parts.append("")
1260
+ elif isinstance(framework_data, list):
1261
+ for item in framework_data:
1262
+ markdown_parts.append(f"- {item}")
1263
+ markdown_parts.append("")
1264
+
1265
+ # Add methodologies
1266
+ if "methodologies" in instructions_dict:
1267
+ methodologies = instructions_dict["methodologies"]
1268
+ if isinstance(methodologies, dict):
1269
+ markdown_parts.extend(["## Methodologies", ""])
1270
+
1271
+ for method_name, method_data in methodologies.items():
1272
+ markdown_parts.extend(
1273
+ [f"### {method_name.replace('_', ' ').title()}", ""]
1274
+ )
1275
+
1276
+ if isinstance(method_data, dict):
1277
+ for key, value in method_data.items():
1278
+ if isinstance(value, list):
1279
+ markdown_parts.extend(
1280
+ [f"#### {key.replace('_', ' ').title()}", ""]
1281
+ )
1282
+ for item in value:
1283
+ markdown_parts.append(f"- {item}")
1284
+ markdown_parts.append("")
1285
+ elif isinstance(value, str):
1286
+ markdown_parts.extend(
1287
+ [
1288
+ f"**{key.replace('_', ' ').title()}**: {value}",
1289
+ "",
1290
+ ]
1291
+ )
1292
+
1293
+ # Add quality standards
1294
+ if "quality_standards" in instructions_dict:
1295
+ standards = instructions_dict["quality_standards"]
1296
+ if isinstance(standards, dict):
1297
+ markdown_parts.extend(["## Quality Standards", ""])
1298
+
1299
+ for standard_area, standard_items in standards.items():
1300
+ markdown_parts.extend(
1301
+ [f"### {standard_area.replace('_', ' ').title()}", ""]
1302
+ )
1303
+
1304
+ if isinstance(standard_items, list):
1305
+ for item in standard_items:
1306
+ markdown_parts.append(f"- {item}")
1307
+ elif isinstance(standard_items, str):
1308
+ markdown_parts.append(standard_items)
1309
+
1310
+ markdown_parts.append("")
1311
+
1312
+ # Add communication style
1313
+ if "communication_style" in instructions_dict:
1314
+ comm_style = instructions_dict["communication_style"]
1315
+ if isinstance(comm_style, dict):
1316
+ markdown_parts.extend(["## Communication Style", ""])
1317
+
1318
+ for style_area, style_items in comm_style.items():
1319
+ markdown_parts.extend(
1320
+ [f"### {style_area.replace('_', ' ').title()}", ""]
1321
+ )
1322
+
1323
+ if isinstance(style_items, list):
1324
+ for item in style_items:
1325
+ markdown_parts.append(f"- {item}")
1326
+ elif isinstance(style_items, str):
1327
+ markdown_parts.append(style_items)
1328
+
1329
+ markdown_parts.append("")
1330
+
1331
+ # If no specific sections were found, convert as generic dict
1332
+ if not markdown_parts:
1333
+ markdown_parts = ["# Agent Instructions", ""]
1334
+ for key, value in instructions_dict.items():
1335
+ key_title = key.replace("_", " ").title()
1336
+ if isinstance(value, str):
1337
+ markdown_parts.extend([f"## {key_title}", "", value, ""])
1338
+ elif isinstance(value, list):
1339
+ markdown_parts.extend([f"## {key_title}", ""])
1340
+ for item in value:
1341
+ markdown_parts.append(f"- {item}")
1342
+ markdown_parts.append("")
1343
+ elif isinstance(value, dict):
1344
+ markdown_parts.extend([f"## {key_title}", ""])
1345
+ # Simple dict formatting
1346
+ for subkey, subvalue in value.items():
1347
+ if isinstance(subvalue, str):
1348
+ markdown_parts.extend(
1349
+ [
1350
+ f"**{subkey.replace('_', ' ').title()}**: {subvalue}",
1351
+ "",
1352
+ ]
1353
+ )
1354
+
1355
+ return "\n".join(markdown_parts).strip()