claude-mpm 5.4.22__py3-none-any.whl → 5.6.34__py3-none-any.whl

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

Potentially problematic release.


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

Files changed (487) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/BASE_AGENT.md +164 -0
  3. claude_mpm/agents/BASE_ENGINEER.md +658 -0
  4. claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md +66 -241
  5. claude_mpm/agents/CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md +413 -0
  6. claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md +109 -1925
  7. claude_mpm/agents/MEMORY.md +1 -1
  8. claude_mpm/agents/PM_INSTRUCTIONS.md +374 -1257
  9. claude_mpm/agents/WORKFLOW.md +6 -253
  10. claude_mpm/agents/agent_loader.py +1 -1
  11. claude_mpm/agents/base_agent.json +31 -0
  12. claude_mpm/agents/frontmatter_validator.py +2 -2
  13. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  14. claude_mpm/cli/__init__.py +5 -1
  15. claude_mpm/cli/commands/agent_state_manager.py +10 -10
  16. claude_mpm/cli/commands/agents.py +11 -13
  17. claude_mpm/cli/commands/agents_reconcile.py +197 -0
  18. claude_mpm/cli/commands/auto_configure.py +4 -4
  19. claude_mpm/cli/commands/autotodos.py +566 -0
  20. claude_mpm/cli/commands/commander.py +216 -0
  21. claude_mpm/cli/commands/configure.py +621 -22
  22. claude_mpm/cli/commands/configure_agent_display.py +12 -0
  23. claude_mpm/cli/commands/hook_errors.py +60 -60
  24. claude_mpm/cli/commands/monitor.py +2 -2
  25. claude_mpm/cli/commands/mpm_init/core.py +72 -0
  26. claude_mpm/cli/commands/postmortem.py +1 -1
  27. claude_mpm/cli/commands/profile.py +276 -0
  28. claude_mpm/cli/commands/run.py +35 -3
  29. claude_mpm/cli/commands/skill_source.py +51 -2
  30. claude_mpm/cli/commands/skills.py +182 -32
  31. claude_mpm/cli/executor.py +130 -16
  32. claude_mpm/cli/interactive/__init__.py +10 -0
  33. claude_mpm/cli/interactive/agent_wizard.py +32 -52
  34. claude_mpm/cli/interactive/questionary_styles.py +65 -0
  35. claude_mpm/cli/interactive/skill_selector.py +481 -0
  36. claude_mpm/cli/parsers/base_parser.py +83 -1
  37. claude_mpm/cli/parsers/commander_parser.py +116 -0
  38. claude_mpm/cli/parsers/profile_parser.py +147 -0
  39. claude_mpm/cli/parsers/run_parser.py +10 -0
  40. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  41. claude_mpm/cli/parsers/skills_parser.py +2 -3
  42. claude_mpm/cli/startup.py +690 -386
  43. claude_mpm/cli/startup_display.py +74 -6
  44. claude_mpm/cli/startup_logging.py +2 -2
  45. claude_mpm/cli/utils.py +7 -3
  46. claude_mpm/commander/__init__.py +78 -0
  47. claude_mpm/commander/adapters/__init__.py +60 -0
  48. claude_mpm/commander/adapters/auggie.py +260 -0
  49. claude_mpm/commander/adapters/base.py +288 -0
  50. claude_mpm/commander/adapters/claude_code.py +392 -0
  51. claude_mpm/commander/adapters/codex.py +237 -0
  52. claude_mpm/commander/adapters/communication.py +366 -0
  53. claude_mpm/commander/adapters/example_usage.py +310 -0
  54. claude_mpm/commander/adapters/mpm.py +389 -0
  55. claude_mpm/commander/adapters/registry.py +204 -0
  56. claude_mpm/commander/api/__init__.py +16 -0
  57. claude_mpm/commander/api/app.py +121 -0
  58. claude_mpm/commander/api/errors.py +133 -0
  59. claude_mpm/commander/api/routes/__init__.py +8 -0
  60. claude_mpm/commander/api/routes/events.py +184 -0
  61. claude_mpm/commander/api/routes/inbox.py +171 -0
  62. claude_mpm/commander/api/routes/messages.py +148 -0
  63. claude_mpm/commander/api/routes/projects.py +271 -0
  64. claude_mpm/commander/api/routes/sessions.py +226 -0
  65. claude_mpm/commander/api/routes/work.py +296 -0
  66. claude_mpm/commander/api/schemas.py +186 -0
  67. claude_mpm/commander/chat/__init__.py +7 -0
  68. claude_mpm/commander/chat/cli.py +146 -0
  69. claude_mpm/commander/chat/commands.py +96 -0
  70. claude_mpm/commander/chat/repl.py +310 -0
  71. claude_mpm/commander/config.py +51 -0
  72. claude_mpm/commander/config_loader.py +115 -0
  73. claude_mpm/commander/core/__init__.py +10 -0
  74. claude_mpm/commander/core/block_manager.py +325 -0
  75. claude_mpm/commander/core/response_manager.py +323 -0
  76. claude_mpm/commander/daemon.py +603 -0
  77. claude_mpm/commander/env_loader.py +59 -0
  78. claude_mpm/commander/events/__init__.py +26 -0
  79. claude_mpm/commander/events/manager.py +332 -0
  80. claude_mpm/commander/frameworks/__init__.py +12 -0
  81. claude_mpm/commander/frameworks/base.py +146 -0
  82. claude_mpm/commander/frameworks/claude_code.py +58 -0
  83. claude_mpm/commander/frameworks/mpm.py +62 -0
  84. claude_mpm/commander/inbox/__init__.py +16 -0
  85. claude_mpm/commander/inbox/dedup.py +128 -0
  86. claude_mpm/commander/inbox/inbox.py +224 -0
  87. claude_mpm/commander/inbox/models.py +70 -0
  88. claude_mpm/commander/instance_manager.py +450 -0
  89. claude_mpm/commander/llm/__init__.py +6 -0
  90. claude_mpm/commander/llm/openrouter_client.py +167 -0
  91. claude_mpm/commander/llm/summarizer.py +70 -0
  92. claude_mpm/commander/memory/__init__.py +45 -0
  93. claude_mpm/commander/memory/compression.py +347 -0
  94. claude_mpm/commander/memory/embeddings.py +230 -0
  95. claude_mpm/commander/memory/entities.py +310 -0
  96. claude_mpm/commander/memory/example_usage.py +290 -0
  97. claude_mpm/commander/memory/integration.py +325 -0
  98. claude_mpm/commander/memory/search.py +381 -0
  99. claude_mpm/commander/memory/store.py +657 -0
  100. claude_mpm/commander/models/__init__.py +18 -0
  101. claude_mpm/commander/models/events.py +121 -0
  102. claude_mpm/commander/models/project.py +162 -0
  103. claude_mpm/commander/models/work.py +214 -0
  104. claude_mpm/commander/parsing/__init__.py +20 -0
  105. claude_mpm/commander/parsing/extractor.py +132 -0
  106. claude_mpm/commander/parsing/output_parser.py +270 -0
  107. claude_mpm/commander/parsing/patterns.py +100 -0
  108. claude_mpm/commander/persistence/__init__.py +11 -0
  109. claude_mpm/commander/persistence/event_store.py +274 -0
  110. claude_mpm/commander/persistence/state_store.py +309 -0
  111. claude_mpm/commander/persistence/work_store.py +164 -0
  112. claude_mpm/commander/polling/__init__.py +13 -0
  113. claude_mpm/commander/polling/event_detector.py +104 -0
  114. claude_mpm/commander/polling/output_buffer.py +49 -0
  115. claude_mpm/commander/polling/output_poller.py +153 -0
  116. claude_mpm/commander/project_session.py +268 -0
  117. claude_mpm/commander/proxy/__init__.py +12 -0
  118. claude_mpm/commander/proxy/formatter.py +89 -0
  119. claude_mpm/commander/proxy/output_handler.py +191 -0
  120. claude_mpm/commander/proxy/relay.py +155 -0
  121. claude_mpm/commander/registry.py +410 -0
  122. claude_mpm/commander/runtime/__init__.py +10 -0
  123. claude_mpm/commander/runtime/executor.py +191 -0
  124. claude_mpm/commander/runtime/monitor.py +346 -0
  125. claude_mpm/commander/session/__init__.py +6 -0
  126. claude_mpm/commander/session/context.py +81 -0
  127. claude_mpm/commander/session/manager.py +59 -0
  128. claude_mpm/commander/tmux_orchestrator.py +361 -0
  129. claude_mpm/commander/web/__init__.py +1 -0
  130. claude_mpm/commander/work/__init__.py +30 -0
  131. claude_mpm/commander/work/executor.py +207 -0
  132. claude_mpm/commander/work/queue.py +405 -0
  133. claude_mpm/commander/workflow/__init__.py +27 -0
  134. claude_mpm/commander/workflow/event_handler.py +241 -0
  135. claude_mpm/commander/workflow/notifier.py +146 -0
  136. claude_mpm/commands/mpm-config.md +20 -249
  137. claude_mpm/commands/mpm-doctor.md +16 -21
  138. claude_mpm/commands/mpm-help.md +12 -205
  139. claude_mpm/commands/mpm-init.md +88 -506
  140. claude_mpm/commands/mpm-monitor.md +22 -401
  141. claude_mpm/commands/mpm-organize.md +70 -442
  142. claude_mpm/commands/mpm-postmortem.md +13 -107
  143. claude_mpm/commands/mpm-session-resume.md +20 -363
  144. claude_mpm/commands/mpm-status.md +13 -69
  145. claude_mpm/commands/mpm-ticket-view.md +60 -495
  146. claude_mpm/commands/mpm-version.md +13 -107
  147. claude_mpm/commands/mpm.md +8 -0
  148. claude_mpm/config/agent_presets.py +8 -7
  149. claude_mpm/config/skill_sources.py +16 -0
  150. claude_mpm/constants.py +1 -0
  151. claude_mpm/core/claude_runner.py +154 -2
  152. claude_mpm/core/config.py +37 -26
  153. claude_mpm/core/config_constants.py +74 -9
  154. claude_mpm/core/constants.py +56 -12
  155. claude_mpm/core/framework/loaders/agent_loader.py +1 -1
  156. claude_mpm/core/framework/loaders/instruction_loader.py +52 -11
  157. claude_mpm/core/hook_manager.py +51 -3
  158. claude_mpm/core/interactive_session.py +12 -11
  159. claude_mpm/core/logger.py +26 -9
  160. claude_mpm/core/logging_utils.py +39 -13
  161. claude_mpm/core/network_config.py +148 -0
  162. claude_mpm/core/oneshot_session.py +7 -6
  163. claude_mpm/core/optimized_startup.py +61 -0
  164. claude_mpm/core/output_style_manager.py +66 -18
  165. claude_mpm/core/shared/config_loader.py +3 -1
  166. claude_mpm/core/socketio_pool.py +47 -15
  167. claude_mpm/core/unified_agent_registry.py +1 -1
  168. claude_mpm/core/unified_config.py +54 -8
  169. claude_mpm/core/unified_paths.py +95 -90
  170. claude_mpm/dashboard/static/svelte-build/_app/env.js +1 -0
  171. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.C33zOoyM.css +1 -0
  172. claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.CW1J-YuA.css +1 -0
  173. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/1WZnGYqX.js +24 -0
  174. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/67pF3qNn.js +1 -0
  175. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/6RxdMKe4.js +1 -0
  176. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/8cZrfX0h.js +60 -0
  177. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/9a6T2nm-.js +7 -0
  178. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B443AUzu.js +1 -0
  179. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B8AwtY2H.js +1 -0
  180. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BF15LAsF.js +1 -0
  181. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
  182. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BRcwIQNr.js +4 -0
  183. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BSNlmTZj.js +1 -0
  184. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BV6nKitt.js +43 -0
  185. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BViJ8lZt.js +128 -0
  186. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BcQ-Q0FE.js +1 -0
  187. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bpyvgze_.js +30 -0
  188. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BzTRqg-z.js +1 -0
  189. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C0Fr8dve.js +1 -0
  190. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C3rbW_a-.js +1 -0
  191. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C8WYN38h.js +1 -0
  192. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C9I8FlXH.js +61 -0
  193. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIQcWgO2.js +36 -0
  194. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIctN7YN.js +7 -0
  195. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CKrS_JZW.js +145 -0
  196. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CR6P9C4A.js +89 -0
  197. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRRR9MD_.js +2 -0
  198. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CRcR2DqT.js +334 -0
  199. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CSXtMOf0.js +1 -0
  200. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CT-sbxSk.js +1 -0
  201. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CWm6DJsp.js +1 -0
  202. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
  203. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CpqQ1Kzn.js +1 -0
  204. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
  205. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D2nGpDRe.js +1 -0
  206. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9iCMida.js +267 -0
  207. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9ykgMoY.js +10 -0
  208. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DL2Ldur1.js +1 -0
  209. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DPfltzjH.js +165 -0
  210. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DR8nis88.js +2 -0
  211. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUliQN2b.js +1 -0
  212. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
  213. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DXlhR01x.js +122 -0
  214. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D_lyTybS.js +1 -0
  215. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DngoTTgh.js +1 -0
  216. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DqkmHtDC.js +220 -0
  217. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DsDh8EYs.js +1 -0
  218. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DypDmXgd.js +139 -0
  219. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
  220. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/IPYC-LnN.js +162 -0
  221. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JTLiF7dt.js +24 -0
  222. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/JpevfAFt.js +68 -0
  223. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/NqQ1dWOy.js +1 -0
  224. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/R8CEIRAd.js +2 -0
  225. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Zxy7qc-l.js +64 -0
  226. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/q9Hm6zAU.js +1 -0
  227. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/qtd3IeO4.js +15 -0
  228. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ulBFON_C.js +65 -0
  229. claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/wQVh1CoA.js +10 -0
  230. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.Dr7t0z2J.js +2 -0
  231. claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.BGhZHUS3.js +1 -0
  232. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/0.RgBboRvH.js +1 -0
  233. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DG-KkbDf.js +1 -0
  234. claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.D_jnf-x6.js +1 -0
  235. claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -0
  236. claude_mpm/dashboard/static/svelte-build/favicon.svg +7 -0
  237. claude_mpm/dashboard/static/svelte-build/index.html +36 -0
  238. claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
  239. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
  240. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
  241. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
  242. claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
  243. claude_mpm/experimental/cli_enhancements.py +2 -1
  244. claude_mpm/hooks/claude_hooks/INTEGRATION_EXAMPLE.md +243 -0
  245. claude_mpm/hooks/claude_hooks/README_AUTO_PAUSE.md +403 -0
  246. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-311.pyc +0 -0
  247. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  248. claude_mpm/hooks/claude_hooks/__pycache__/correlation_manager.cpython-311.pyc +0 -0
  249. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  250. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  251. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  252. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  253. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-311.pyc +0 -0
  254. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +485 -0
  255. claude_mpm/hooks/claude_hooks/event_handlers.py +527 -136
  256. claude_mpm/hooks/claude_hooks/hook_handler.py +313 -99
  257. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  258. claude_mpm/hooks/claude_hooks/installer.py +206 -36
  259. claude_mpm/hooks/claude_hooks/memory_integration.py +52 -32
  260. claude_mpm/hooks/claude_hooks/response_tracking.py +43 -60
  261. claude_mpm/hooks/claude_hooks/services/__init__.py +21 -0
  262. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-311.pyc +0 -0
  263. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  264. claude_mpm/hooks/claude_hooks/services/__pycache__/container.cpython-311.pyc +0 -0
  265. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-311.pyc +0 -0
  266. claude_mpm/hooks/claude_hooks/services/__pycache__/protocols.cpython-311.pyc +0 -0
  267. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  268. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  269. claude_mpm/hooks/claude_hooks/services/connection_manager.py +67 -32
  270. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +38 -105
  271. claude_mpm/hooks/claude_hooks/services/container.py +310 -0
  272. claude_mpm/hooks/claude_hooks/services/protocols.py +328 -0
  273. claude_mpm/hooks/claude_hooks/services/state_manager.py +25 -38
  274. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +75 -77
  275. claude_mpm/hooks/kuzu_memory_hook.py +5 -5
  276. claude_mpm/hooks/session_resume_hook.py +89 -1
  277. claude_mpm/hooks/templates/pre_tool_use_simple.py +6 -6
  278. claude_mpm/hooks/templates/pre_tool_use_template.py +16 -8
  279. claude_mpm/init.py +276 -0
  280. claude_mpm/models/git_repository.py +3 -3
  281. claude_mpm/scripts/claude-hook-handler.sh +46 -19
  282. claude_mpm/services/agents/agent_builder.py +3 -3
  283. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  284. claude_mpm/services/agents/agent_selection_service.py +2 -2
  285. claude_mpm/services/agents/cache_git_manager.py +7 -7
  286. claude_mpm/services/agents/deployment/agent_deployment.py +29 -7
  287. claude_mpm/services/agents/deployment/agent_discovery_service.py +4 -2
  288. claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
  289. claude_mpm/services/agents/deployment/agent_template_builder.py +39 -19
  290. claude_mpm/services/agents/deployment/agents_directory_resolver.py +2 -2
  291. claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
  292. claude_mpm/services/agents/deployment/deployment_reconciler.py +577 -0
  293. claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
  294. claude_mpm/services/agents/deployment/multi_source_deployment_service.py +169 -26
  295. claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +101 -75
  296. claude_mpm/services/agents/deployment/startup_reconciliation.py +138 -0
  297. claude_mpm/services/agents/git_source_manager.py +23 -4
  298. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  299. claude_mpm/services/agents/recommender.py +5 -3
  300. claude_mpm/services/agents/single_tier_deployment_service.py +6 -6
  301. claude_mpm/services/agents/sources/git_source_sync_service.py +121 -10
  302. claude_mpm/services/agents/startup_sync.py +27 -4
  303. claude_mpm/services/cli/__init__.py +3 -0
  304. claude_mpm/services/cli/incremental_pause_manager.py +561 -0
  305. claude_mpm/services/cli/session_resume_helper.py +10 -2
  306. claude_mpm/services/command_deployment_service.py +44 -26
  307. claude_mpm/services/delegation_detector.py +175 -0
  308. claude_mpm/services/diagnostics/checks/agent_check.py +2 -2
  309. claude_mpm/services/diagnostics/checks/agent_sources_check.py +31 -1
  310. claude_mpm/services/diagnostics/checks/configuration_check.py +24 -0
  311. claude_mpm/services/diagnostics/checks/installation_check.py +22 -0
  312. claude_mpm/services/diagnostics/checks/mcp_services_check.py +23 -0
  313. claude_mpm/services/diagnostics/doctor_reporter.py +31 -1
  314. claude_mpm/services/diagnostics/models.py +14 -1
  315. claude_mpm/services/event_log.py +325 -0
  316. claude_mpm/services/git/git_operations_service.py +8 -8
  317. claude_mpm/services/hook_installer_service.py +77 -8
  318. claude_mpm/services/infrastructure/__init__.py +4 -0
  319. claude_mpm/services/infrastructure/context_usage_tracker.py +291 -0
  320. claude_mpm/services/infrastructure/resume_log_generator.py +24 -5
  321. claude_mpm/services/monitor/daemon_manager.py +15 -4
  322. claude_mpm/services/monitor/management/lifecycle.py +15 -3
  323. claude_mpm/services/monitor/server.py +571 -11
  324. claude_mpm/services/pm_skills_deployer.py +884 -0
  325. claude_mpm/services/profile_manager.py +337 -0
  326. claude_mpm/services/skills/git_skill_source_manager.py +281 -20
  327. claude_mpm/services/skills/selective_skill_deployer.py +211 -46
  328. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  329. claude_mpm/services/skills_deployer.py +192 -70
  330. claude_mpm/services/socketio/dashboard_server.py +1 -0
  331. claude_mpm/services/socketio/event_normalizer.py +37 -6
  332. claude_mpm/services/socketio/handlers/hook.py +14 -7
  333. claude_mpm/services/socketio/server/core.py +262 -123
  334. claude_mpm/services/socketio/server/main.py +12 -4
  335. claude_mpm/skills/__init__.py +2 -1
  336. claude_mpm/skills/bundled/collaboration/brainstorming/SKILL.md +79 -0
  337. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/SKILL.md +178 -0
  338. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/agent-prompts.md +577 -0
  339. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/coordination-patterns.md +467 -0
  340. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/examples.md +537 -0
  341. claude_mpm/skills/bundled/collaboration/dispatching-parallel-agents/references/troubleshooting.md +730 -0
  342. claude_mpm/skills/bundled/collaboration/git-worktrees.md +317 -0
  343. claude_mpm/skills/bundled/collaboration/requesting-code-review/SKILL.md +112 -0
  344. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/code-reviewer-template.md +146 -0
  345. claude_mpm/skills/bundled/collaboration/requesting-code-review/references/review-examples.md +412 -0
  346. claude_mpm/skills/bundled/collaboration/stacked-prs.md +251 -0
  347. claude_mpm/skills/bundled/collaboration/writing-plans/SKILL.md +81 -0
  348. claude_mpm/skills/bundled/collaboration/writing-plans/references/best-practices.md +362 -0
  349. claude_mpm/skills/bundled/collaboration/writing-plans/references/plan-structure-templates.md +312 -0
  350. claude_mpm/skills/bundled/debugging/root-cause-tracing/SKILL.md +152 -0
  351. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/advanced-techniques.md +668 -0
  352. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/examples.md +587 -0
  353. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/integration.md +438 -0
  354. claude_mpm/skills/bundled/debugging/root-cause-tracing/references/tracing-techniques.md +391 -0
  355. claude_mpm/skills/bundled/debugging/systematic-debugging/CREATION-LOG.md +119 -0
  356. claude_mpm/skills/bundled/debugging/systematic-debugging/SKILL.md +148 -0
  357. claude_mpm/skills/bundled/debugging/systematic-debugging/references/anti-patterns.md +483 -0
  358. claude_mpm/skills/bundled/debugging/systematic-debugging/references/examples.md +452 -0
  359. claude_mpm/skills/bundled/debugging/systematic-debugging/references/troubleshooting.md +449 -0
  360. claude_mpm/skills/bundled/debugging/systematic-debugging/references/workflow.md +411 -0
  361. claude_mpm/skills/bundled/debugging/systematic-debugging/test-academic.md +14 -0
  362. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-1.md +58 -0
  363. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-2.md +68 -0
  364. claude_mpm/skills/bundled/debugging/systematic-debugging/test-pressure-3.md +69 -0
  365. claude_mpm/skills/bundled/debugging/verification-before-completion/SKILL.md +131 -0
  366. claude_mpm/skills/bundled/debugging/verification-before-completion/references/gate-function.md +325 -0
  367. claude_mpm/skills/bundled/debugging/verification-before-completion/references/integration-and-workflows.md +490 -0
  368. claude_mpm/skills/bundled/debugging/verification-before-completion/references/red-flags-and-failures.md +425 -0
  369. claude_mpm/skills/bundled/debugging/verification-before-completion/references/verification-patterns.md +499 -0
  370. claude_mpm/skills/bundled/infrastructure/env-manager/INTEGRATION.md +611 -0
  371. claude_mpm/skills/bundled/infrastructure/env-manager/README.md +596 -0
  372. claude_mpm/skills/bundled/infrastructure/env-manager/SKILL.md +260 -0
  373. claude_mpm/skills/bundled/infrastructure/env-manager/examples/nextjs-env-structure.md +315 -0
  374. claude_mpm/skills/bundled/infrastructure/env-manager/references/frameworks.md +436 -0
  375. claude_mpm/skills/bundled/infrastructure/env-manager/references/security.md +433 -0
  376. claude_mpm/skills/bundled/infrastructure/env-manager/references/synchronization.md +452 -0
  377. claude_mpm/skills/bundled/infrastructure/env-manager/references/troubleshooting.md +404 -0
  378. claude_mpm/skills/bundled/infrastructure/env-manager/references/validation.md +420 -0
  379. claude_mpm/skills/bundled/main/artifacts-builder/SKILL.md +86 -0
  380. claude_mpm/skills/bundled/main/internal-comms/SKILL.md +43 -0
  381. claude_mpm/skills/bundled/main/internal-comms/examples/3p-updates.md +47 -0
  382. claude_mpm/skills/bundled/main/internal-comms/examples/company-newsletter.md +65 -0
  383. claude_mpm/skills/bundled/main/internal-comms/examples/faq-answers.md +30 -0
  384. claude_mpm/skills/bundled/main/internal-comms/examples/general-comms.md +16 -0
  385. claude_mpm/skills/bundled/main/mcp-builder/SKILL.md +160 -0
  386. claude_mpm/skills/bundled/main/mcp-builder/reference/design_principles.md +412 -0
  387. claude_mpm/skills/bundled/main/mcp-builder/reference/evaluation.md +602 -0
  388. claude_mpm/skills/bundled/main/mcp-builder/reference/mcp_best_practices.md +915 -0
  389. claude_mpm/skills/bundled/main/mcp-builder/reference/node_mcp_server.md +916 -0
  390. claude_mpm/skills/bundled/main/mcp-builder/reference/python_mcp_server.md +752 -0
  391. claude_mpm/skills/bundled/main/mcp-builder/reference/workflow.md +1237 -0
  392. claude_mpm/skills/bundled/main/skill-creator/SKILL.md +189 -0
  393. claude_mpm/skills/bundled/main/skill-creator/references/best-practices.md +500 -0
  394. claude_mpm/skills/bundled/main/skill-creator/references/creation-workflow.md +464 -0
  395. claude_mpm/skills/bundled/main/skill-creator/references/examples.md +619 -0
  396. claude_mpm/skills/bundled/main/skill-creator/references/progressive-disclosure.md +437 -0
  397. claude_mpm/skills/bundled/main/skill-creator/references/skill-structure.md +231 -0
  398. claude_mpm/skills/bundled/php/espocrm-development/SKILL.md +170 -0
  399. claude_mpm/skills/bundled/php/espocrm-development/references/architecture.md +602 -0
  400. claude_mpm/skills/bundled/php/espocrm-development/references/common-tasks.md +821 -0
  401. claude_mpm/skills/bundled/php/espocrm-development/references/development-workflow.md +742 -0
  402. claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md +726 -0
  403. claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md +764 -0
  404. claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md +831 -0
  405. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  406. claude_mpm/skills/bundled/pm/mpm-agent-update-workflow/SKILL.md +75 -0
  407. claude_mpm/skills/bundled/pm/mpm-bug-reporting/SKILL.md +248 -0
  408. claude_mpm/skills/bundled/pm/mpm-circuit-breaker-enforcement/SKILL.md +476 -0
  409. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  410. claude_mpm/skills/bundled/pm/mpm-delegation-patterns/SKILL.md +167 -0
  411. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  412. claude_mpm/skills/bundled/pm/mpm-git-file-tracking/SKILL.md +113 -0
  413. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  414. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  415. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  416. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  417. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  418. claude_mpm/skills/bundled/pm/mpm-pr-workflow/SKILL.md +124 -0
  419. claude_mpm/skills/bundled/pm/mpm-session-management/SKILL.md +312 -0
  420. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  421. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  422. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  423. claude_mpm/skills/bundled/pm/mpm-teaching-mode/SKILL.md +657 -0
  424. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  425. claude_mpm/skills/bundled/pm/mpm-ticketing-integration/SKILL.md +154 -0
  426. claude_mpm/skills/bundled/pm/mpm-tool-usage-guide/SKILL.md +386 -0
  427. claude_mpm/skills/bundled/pm/mpm-verification-protocols/SKILL.md +198 -0
  428. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  429. claude_mpm/skills/bundled/react/flexlayout-react.md +742 -0
  430. claude_mpm/skills/bundled/rust/desktop-applications/SKILL.md +226 -0
  431. claude_mpm/skills/bundled/rust/desktop-applications/references/architecture-patterns.md +901 -0
  432. claude_mpm/skills/bundled/rust/desktop-applications/references/native-gui-frameworks.md +901 -0
  433. claude_mpm/skills/bundled/rust/desktop-applications/references/platform-integration.md +775 -0
  434. claude_mpm/skills/bundled/rust/desktop-applications/references/state-management.md +937 -0
  435. claude_mpm/skills/bundled/rust/desktop-applications/references/tauri-framework.md +770 -0
  436. claude_mpm/skills/bundled/rust/desktop-applications/references/testing-deployment.md +961 -0
  437. claude_mpm/skills/bundled/security-scanning.md +112 -0
  438. claude_mpm/skills/bundled/tauri/tauri-async-patterns.md +495 -0
  439. claude_mpm/skills/bundled/tauri/tauri-build-deploy.md +599 -0
  440. claude_mpm/skills/bundled/tauri/tauri-command-patterns.md +535 -0
  441. claude_mpm/skills/bundled/tauri/tauri-error-handling.md +613 -0
  442. claude_mpm/skills/bundled/tauri/tauri-event-system.md +648 -0
  443. claude_mpm/skills/bundled/tauri/tauri-file-system.md +673 -0
  444. claude_mpm/skills/bundled/tauri/tauri-frontend-integration.md +767 -0
  445. claude_mpm/skills/bundled/tauri/tauri-performance.md +669 -0
  446. claude_mpm/skills/bundled/tauri/tauri-state-management.md +573 -0
  447. claude_mpm/skills/bundled/tauri/tauri-testing.md +384 -0
  448. claude_mpm/skills/bundled/tauri/tauri-window-management.md +628 -0
  449. claude_mpm/skills/bundled/testing/condition-based-waiting/SKILL.md +119 -0
  450. claude_mpm/skills/bundled/testing/condition-based-waiting/references/patterns-and-implementation.md +253 -0
  451. claude_mpm/skills/bundled/testing/test-driven-development/SKILL.md +145 -0
  452. claude_mpm/skills/bundled/testing/test-driven-development/references/anti-patterns.md +543 -0
  453. claude_mpm/skills/bundled/testing/test-driven-development/references/examples.md +741 -0
  454. claude_mpm/skills/bundled/testing/test-driven-development/references/integration.md +470 -0
  455. claude_mpm/skills/bundled/testing/test-driven-development/references/philosophy.md +458 -0
  456. claude_mpm/skills/bundled/testing/test-driven-development/references/workflow.md +639 -0
  457. claude_mpm/skills/bundled/testing/test-quality-inspector/SKILL.md +458 -0
  458. claude_mpm/skills/bundled/testing/test-quality-inspector/examples/example-inspection-report.md +411 -0
  459. claude_mpm/skills/bundled/testing/test-quality-inspector/references/assertion-quality.md +317 -0
  460. claude_mpm/skills/bundled/testing/test-quality-inspector/references/inspection-checklist.md +270 -0
  461. claude_mpm/skills/bundled/testing/test-quality-inspector/references/red-flags.md +436 -0
  462. claude_mpm/skills/bundled/testing/testing-anti-patterns/SKILL.md +140 -0
  463. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/completeness-anti-patterns.md +572 -0
  464. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/core-anti-patterns.md +411 -0
  465. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/detection-guide.md +569 -0
  466. claude_mpm/skills/bundled/testing/testing-anti-patterns/references/tdd-connection.md +695 -0
  467. claude_mpm/skills/bundled/testing/webapp-testing/SKILL.md +184 -0
  468. claude_mpm/skills/bundled/testing/webapp-testing/decision-tree.md +459 -0
  469. claude_mpm/skills/bundled/testing/webapp-testing/playwright-patterns.md +479 -0
  470. claude_mpm/skills/bundled/testing/webapp-testing/reconnaissance-pattern.md +687 -0
  471. claude_mpm/skills/bundled/testing/webapp-testing/server-management.md +758 -0
  472. claude_mpm/skills/bundled/testing/webapp-testing/troubleshooting.md +868 -0
  473. claude_mpm/skills/registry.py +295 -90
  474. claude_mpm/skills/skill_manager.py +98 -3
  475. claude_mpm/templates/.pre-commit-config.yaml +112 -0
  476. claude_mpm/utils/agent_dependency_loader.py +115 -4
  477. claude_mpm/utils/agent_filters.py +1 -1
  478. claude_mpm/utils/migration.py +4 -4
  479. claude_mpm/utils/robust_installer.py +86 -21
  480. claude_mpm-5.6.34.dist-info/METADATA +393 -0
  481. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/RECORD +486 -145
  482. claude_mpm-5.4.22.dist-info/METADATA +0 -996
  483. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/WHEEL +0 -0
  484. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/entry_points.txt +0 -0
  485. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE +0 -0
  486. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  487. {claude_mpm-5.4.22.dist-info → claude_mpm-5.6.34.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,146 @@
1
+ """Commander CLI entry point."""
2
+
3
+ import asyncio
4
+ import logging
5
+ from dataclasses import dataclass
6
+ from pathlib import Path
7
+ from typing import Optional
8
+
9
+ from claude_mpm.commander.env_loader import load_env
10
+ from claude_mpm.commander.instance_manager import InstanceManager
11
+ from claude_mpm.commander.llm.openrouter_client import (
12
+ OpenRouterClient,
13
+ OpenRouterConfig,
14
+ )
15
+ from claude_mpm.commander.llm.summarizer import OutputSummarizer
16
+ from claude_mpm.commander.proxy.formatter import OutputFormatter
17
+ from claude_mpm.commander.proxy.output_handler import OutputHandler
18
+ from claude_mpm.commander.proxy.relay import OutputRelay
19
+ from claude_mpm.commander.session.manager import SessionManager
20
+ from claude_mpm.commander.tmux_orchestrator import TmuxOrchestrator
21
+
22
+ from .repl import CommanderREPL
23
+
24
+ # Load environment variables at module import
25
+ load_env()
26
+
27
+ logger = logging.getLogger(__name__)
28
+
29
+
30
+ @dataclass
31
+ class CommanderCLIConfig:
32
+ """Configuration for Commander CLI mode.
33
+
34
+ Attributes:
35
+ summarize_responses: Whether to use LLM to summarize instance responses
36
+ port: Port for internal services (reserved for future use)
37
+ state_dir: Directory for state persistence (optional)
38
+
39
+ Example:
40
+ >>> config = CommanderCLIConfig(summarize_responses=False)
41
+ """
42
+
43
+ summarize_responses: bool = True
44
+ port: int = 8765
45
+ state_dir: Optional[Path] = None
46
+
47
+
48
+ async def run_commander(
49
+ port: int = 8765,
50
+ state_dir: Optional[Path] = None,
51
+ config: Optional[CommanderCLIConfig] = None,
52
+ ) -> None:
53
+ """Run Commander in interactive mode.
54
+
55
+ Args:
56
+ port: Port for internal services (unused currently).
57
+ state_dir: Directory for state persistence (optional).
58
+ config: Commander CLI configuration (optional, uses defaults if None).
59
+
60
+ Example:
61
+ >>> asyncio.run(run_commander())
62
+ # Starts interactive Commander REPL
63
+ >>> config = CommanderCLIConfig(summarize_responses=False)
64
+ >>> asyncio.run(run_commander(config=config))
65
+ # Starts Commander without response summarization
66
+ """
67
+ # Use default config if not provided
68
+ if config is None:
69
+ config = CommanderCLIConfig(port=port, state_dir=state_dir)
70
+
71
+ # Setup logging
72
+ logging.basicConfig(
73
+ level=logging.INFO,
74
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
75
+ )
76
+
77
+ # Initialize components
78
+ logger.info("Initializing Commander...")
79
+
80
+ # Create tmux orchestrator
81
+ orchestrator = TmuxOrchestrator()
82
+
83
+ # Create instance manager
84
+ instance_manager = InstanceManager(orchestrator)
85
+
86
+ # Create session manager
87
+ session_manager = SessionManager()
88
+
89
+ # Try to initialize LLM client (optional)
90
+ llm_client: Optional[OpenRouterClient] = None
91
+ try:
92
+ llm_config = OpenRouterConfig()
93
+ llm_client = OpenRouterClient(llm_config)
94
+ logger.info("LLM client initialized")
95
+ except ValueError as e:
96
+ logger.warning(f"LLM client not available: {e}")
97
+ logger.warning("Output summarization will be disabled")
98
+
99
+ # Create output relay (optional)
100
+ output_relay: Optional[OutputRelay] = None
101
+ if llm_client:
102
+ try:
103
+ # Only create summarizer if summarize_responses is enabled
104
+ summarizer = None
105
+ if config.summarize_responses:
106
+ summarizer = OutputSummarizer(llm_client)
107
+ logger.info("Response summarization enabled")
108
+ else:
109
+ logger.info("Response summarization disabled")
110
+
111
+ handler = OutputHandler(orchestrator, summarizer)
112
+ formatter = OutputFormatter()
113
+ output_relay = OutputRelay(handler, formatter)
114
+ logger.info("Output relay initialized")
115
+ except Exception as e:
116
+ logger.warning(f"Output relay setup failed: {e}")
117
+
118
+ # Create REPL
119
+ repl = CommanderREPL(
120
+ instance_manager=instance_manager,
121
+ session_manager=session_manager,
122
+ output_relay=output_relay,
123
+ llm_client=llm_client,
124
+ )
125
+
126
+ # Run REPL
127
+ try:
128
+ await repl.run()
129
+ except KeyboardInterrupt:
130
+ logger.info("Commander interrupted by user")
131
+ except Exception as e:
132
+ logger.error(f"Commander error: {e}", exc_info=True)
133
+ finally:
134
+ # Cleanup
135
+ logger.info("Shutting down Commander...")
136
+ if output_relay:
137
+ await output_relay.stop_all()
138
+
139
+
140
+ def main() -> None:
141
+ """Entry point for command-line execution."""
142
+ asyncio.run(run_commander())
143
+
144
+
145
+ if __name__ == "__main__":
146
+ main()
@@ -0,0 +1,96 @@
1
+ """Built-in Commander chat commands."""
2
+
3
+ from dataclasses import dataclass
4
+ from enum import Enum
5
+ from typing import Optional
6
+
7
+
8
+ class CommandType(Enum):
9
+ """Built-in command types."""
10
+
11
+ LIST = "list"
12
+ START = "start"
13
+ STOP = "stop"
14
+ CONNECT = "connect"
15
+ DISCONNECT = "disconnect"
16
+ STATUS = "status"
17
+ HELP = "help"
18
+ EXIT = "exit"
19
+ INSTANCES = "instances" # alias for list
20
+
21
+
22
+ @dataclass
23
+ class Command:
24
+ """Parsed command with args."""
25
+
26
+ type: CommandType
27
+ args: list[str]
28
+ raw: str
29
+
30
+
31
+ class CommandParser:
32
+ """Parses user input into commands."""
33
+
34
+ ALIASES = {
35
+ "ls": CommandType.LIST,
36
+ "instances": CommandType.LIST,
37
+ "quit": CommandType.EXIT,
38
+ "q": CommandType.EXIT,
39
+ }
40
+
41
+ def parse(self, input_text: str) -> Optional[Command]:
42
+ """Parse input into a Command.
43
+
44
+ Returns None if input is not a built-in command (natural language).
45
+
46
+ Args:
47
+ input_text: Raw user input.
48
+
49
+ Returns:
50
+ Command if input is a built-in command, None otherwise.
51
+
52
+ Example:
53
+ >>> parser = CommandParser()
54
+ >>> cmd = parser.parse("list")
55
+ >>> cmd.type
56
+ <CommandType.LIST: 'list'>
57
+ >>> parser.parse("tell me about the code")
58
+ None
59
+ """
60
+ if not input_text:
61
+ return None
62
+
63
+ parts = input_text.split()
64
+ command_str = parts[0].lower()
65
+ args = parts[1:] if len(parts) > 1 else []
66
+
67
+ # Check if it's an alias
68
+ if command_str in self.ALIASES:
69
+ cmd_type = self.ALIASES[command_str]
70
+ return Command(type=cmd_type, args=args, raw=input_text)
71
+
72
+ # Check if it's a direct command
73
+ try:
74
+ cmd_type = CommandType(command_str)
75
+ return Command(type=cmd_type, args=args, raw=input_text)
76
+ except ValueError:
77
+ # Not a built-in command
78
+ return None
79
+
80
+ def is_command(self, input_text: str) -> bool:
81
+ """Check if input is a built-in command.
82
+
83
+ Args:
84
+ input_text: Raw user input.
85
+
86
+ Returns:
87
+ True if input is a built-in command, False otherwise.
88
+
89
+ Example:
90
+ >>> parser = CommandParser()
91
+ >>> parser.is_command("list")
92
+ True
93
+ >>> parser.is_command("tell me about the code")
94
+ False
95
+ """
96
+ return self.parse(input_text) is not None
@@ -0,0 +1,310 @@
1
+ """Commander chat REPL interface."""
2
+
3
+ import asyncio
4
+ from pathlib import Path
5
+ from typing import Optional
6
+
7
+ from prompt_toolkit import PromptSession
8
+ from prompt_toolkit.history import FileHistory
9
+
10
+ from claude_mpm.commander.instance_manager import InstanceManager
11
+ from claude_mpm.commander.llm.openrouter_client import OpenRouterClient
12
+ from claude_mpm.commander.proxy.relay import OutputRelay
13
+ from claude_mpm.commander.session.manager import SessionManager
14
+
15
+ from .commands import Command, CommandParser, CommandType
16
+
17
+
18
+ class CommanderREPL:
19
+ """Interactive REPL for Commander mode."""
20
+
21
+ def __init__(
22
+ self,
23
+ instance_manager: InstanceManager,
24
+ session_manager: SessionManager,
25
+ output_relay: Optional[OutputRelay] = None,
26
+ llm_client: Optional[OpenRouterClient] = None,
27
+ ):
28
+ """Initialize REPL.
29
+
30
+ Args:
31
+ instance_manager: Manages Claude instances.
32
+ session_manager: Manages chat session state.
33
+ output_relay: Optional relay for instance output.
34
+ llm_client: Optional OpenRouter client for chat.
35
+ """
36
+ self.instances = instance_manager
37
+ self.session = session_manager
38
+ self.relay = output_relay
39
+ self.llm = llm_client
40
+ self.parser = CommandParser()
41
+ self._running = False
42
+
43
+ async def run(self) -> None:
44
+ """Start the REPL loop."""
45
+ self._running = True
46
+ self._print_welcome()
47
+
48
+ # Setup history file
49
+ history_path = Path.home() / ".claude-mpm" / "commander_history"
50
+ history_path.parent.mkdir(parents=True, exist_ok=True)
51
+
52
+ prompt = PromptSession(history=FileHistory(str(history_path)))
53
+
54
+ while self._running:
55
+ try:
56
+ user_input = await asyncio.to_thread(prompt.prompt, self._get_prompt())
57
+ await self._handle_input(user_input.strip())
58
+ except KeyboardInterrupt:
59
+ continue
60
+ except EOFError:
61
+ break
62
+
63
+ self._print("\nGoodbye!")
64
+
65
+ async def _handle_input(self, input_text: str) -> None:
66
+ """Handle user input - command or natural language.
67
+
68
+ Args:
69
+ input_text: User input string.
70
+ """
71
+ if not input_text:
72
+ return
73
+
74
+ # Check if it's a built-in command
75
+ command = self.parser.parse(input_text)
76
+ if command:
77
+ await self._execute_command(command)
78
+ else:
79
+ # Natural language - send to connected instance
80
+ await self._send_to_instance(input_text)
81
+
82
+ async def _execute_command(self, cmd: Command) -> None:
83
+ """Execute a built-in command.
84
+
85
+ Args:
86
+ cmd: Parsed command.
87
+ """
88
+ handlers = {
89
+ CommandType.LIST: self._cmd_list,
90
+ CommandType.START: self._cmd_start,
91
+ CommandType.STOP: self._cmd_stop,
92
+ CommandType.CONNECT: self._cmd_connect,
93
+ CommandType.DISCONNECT: self._cmd_disconnect,
94
+ CommandType.STATUS: self._cmd_status,
95
+ CommandType.HELP: self._cmd_help,
96
+ CommandType.EXIT: self._cmd_exit,
97
+ }
98
+ handler = handlers.get(cmd.type)
99
+ if handler:
100
+ await handler(cmd.args)
101
+
102
+ async def _cmd_list(self, args: list[str]) -> None:
103
+ """List active instances."""
104
+ instances = self.instances.list_instances()
105
+ if not instances:
106
+ self._print("No active instances.")
107
+ else:
108
+ self._print("Active instances:")
109
+ for inst in instances:
110
+ status = (
111
+ "→" if inst.name == self.session.context.connected_instance else " "
112
+ )
113
+ git_info = f" [{inst.git_branch}]" if inst.git_branch else ""
114
+ self._print(
115
+ f" {status} {inst.name} ({inst.framework}){git_info} - {inst.project_path}"
116
+ )
117
+
118
+ async def _cmd_start(self, args: list[str]) -> None:
119
+ """Start a new instance: start <path> [--framework cc|mpm] [--name name]."""
120
+ if not args:
121
+ self._print("Usage: start <path> [--framework cc|mpm] [--name name]")
122
+ return
123
+
124
+ # Parse arguments
125
+ project_path = Path(args[0]).expanduser().resolve()
126
+ framework = "cc" # default
127
+ name = project_path.name # default
128
+
129
+ # Parse optional flags
130
+ i = 1
131
+ while i < len(args):
132
+ if args[i] == "--framework" and i + 1 < len(args):
133
+ framework = args[i + 1]
134
+ i += 2
135
+ elif args[i] == "--name" and i + 1 < len(args):
136
+ name = args[i + 1]
137
+ i += 2
138
+ else:
139
+ i += 1
140
+
141
+ # Validate path
142
+ if not project_path.exists():
143
+ self._print(f"Error: Path does not exist: {project_path}")
144
+ return
145
+
146
+ if not project_path.is_dir():
147
+ self._print(f"Error: Path is not a directory: {project_path}")
148
+ return
149
+
150
+ # Start instance
151
+ try:
152
+ instance = await self.instances.start_instance(
153
+ name, project_path, framework
154
+ )
155
+ self._print(f"Started instance '{name}' ({framework}) at {project_path}")
156
+ self._print(f"Tmux: {instance.tmux_session}:{instance.pane_target}")
157
+ except Exception as e:
158
+ self._print(f"Error starting instance: {e}")
159
+
160
+ async def _cmd_stop(self, args: list[str]) -> None:
161
+ """Stop an instance: stop <name>."""
162
+ if not args:
163
+ self._print("Usage: stop <instance-name>")
164
+ return
165
+
166
+ name = args[0]
167
+
168
+ try:
169
+ await self.instances.stop_instance(name)
170
+ self._print(f"Stopped instance '{name}'")
171
+
172
+ # Disconnect if we were connected
173
+ if self.session.context.connected_instance == name:
174
+ self.session.disconnect()
175
+ except Exception as e:
176
+ self._print(f"Error stopping instance: {e}")
177
+
178
+ async def _cmd_connect(self, args: list[str]) -> None:
179
+ """Connect to an instance: connect <name>."""
180
+ if not args:
181
+ self._print("Usage: connect <instance-name>")
182
+ return
183
+
184
+ name = args[0]
185
+ inst = self.instances.get_instance(name)
186
+ if not inst:
187
+ self._print(f"Instance '{name}' not found")
188
+ return
189
+
190
+ self.session.connect_to(name)
191
+ self._print(f"Connected to {name}")
192
+
193
+ async def _cmd_disconnect(self, args: list[str]) -> None:
194
+ """Disconnect from current instance."""
195
+ if not self.session.context.is_connected:
196
+ self._print("Not connected to any instance")
197
+ return
198
+
199
+ name = self.session.context.connected_instance
200
+ self.session.disconnect()
201
+ self._print(f"Disconnected from {name}")
202
+
203
+ async def _cmd_status(self, args: list[str]) -> None:
204
+ """Show status of current session."""
205
+ if self.session.context.is_connected:
206
+ name = self.session.context.connected_instance
207
+ inst = self.instances.get_instance(name)
208
+ if inst:
209
+ self._print(f"Connected to: {name}")
210
+ self._print(f" Framework: {inst.framework}")
211
+ self._print(f" Project: {inst.project_path}")
212
+ if inst.git_branch:
213
+ self._print(f" Git: {inst.git_branch} ({inst.git_status})")
214
+ self._print(f" Tmux: {inst.tmux_session}:{inst.pane_target}")
215
+ else:
216
+ self._print(f"Connected to: {name} (instance no longer exists)")
217
+ else:
218
+ self._print("Not connected to any instance")
219
+
220
+ self._print(f"Messages in history: {len(self.session.context.messages)}")
221
+
222
+ async def _cmd_help(self, args: list[str]) -> None:
223
+ """Show help message."""
224
+ help_text = """
225
+ Commander Commands:
226
+ list, ls, instances List active instances
227
+ start <path> Start new instance at path
228
+ --framework <cc|mpm> Specify framework (default: cc)
229
+ --name <name> Specify instance name (default: dir name)
230
+ stop <name> Stop an instance
231
+ connect <name> Connect to an instance
232
+ disconnect Disconnect from current instance
233
+ status Show current session status
234
+ help Show this help message
235
+ exit, quit, q Exit Commander
236
+
237
+ Natural Language:
238
+ When connected to an instance, any input that is not a built-in
239
+ command will be sent to the connected instance as a message.
240
+
241
+ Examples:
242
+ start ~/myproject --framework cc --name myapp
243
+ connect myapp
244
+ Fix the authentication bug in login.py
245
+ disconnect
246
+ exit
247
+ """
248
+ self._print(help_text)
249
+
250
+ async def _cmd_exit(self, args: list[str]) -> None:
251
+ """Exit the REPL."""
252
+ self._running = False
253
+
254
+ async def _send_to_instance(self, message: str) -> None:
255
+ """Send natural language to connected instance.
256
+
257
+ Args:
258
+ message: User message to send.
259
+ """
260
+ if not self.session.context.is_connected:
261
+ self._print("Not connected to any instance. Use 'connect <name>' first.")
262
+ return
263
+
264
+ name = self.session.context.connected_instance
265
+ inst = self.instances.get_instance(name)
266
+ if not inst:
267
+ self._print(f"Instance '{name}' no longer exists")
268
+ self.session.disconnect()
269
+ return
270
+
271
+ self._print(f"[Sending to {name}...]")
272
+ await self.instances.send_to_instance(name, message)
273
+ self.session.add_user_message(message)
274
+
275
+ # Wait for and display response
276
+ if self.relay:
277
+ try:
278
+ output = await self.relay.get_latest_output(
279
+ name, inst.pane_target, context=message
280
+ )
281
+ self._print(f"\n[Response from {name}]:\n{output}")
282
+ self.session.add_assistant_message(output)
283
+ except Exception as e:
284
+ self._print(f"\n[Error getting response: {e}]")
285
+
286
+ def _get_prompt(self) -> str:
287
+ """Get prompt string based on connection state.
288
+
289
+ Returns:
290
+ Prompt string for input.
291
+ """
292
+ if self.session.context.is_connected:
293
+ return f"Commander ({self.session.context.connected_instance})> "
294
+ return "Commander> "
295
+
296
+ def _print(self, msg: str) -> None:
297
+ """Print message to console.
298
+
299
+ Args:
300
+ msg: Message to print.
301
+ """
302
+ print(msg)
303
+
304
+ def _print_welcome(self) -> None:
305
+ """Print welcome message."""
306
+ print("╔══════════════════════════════════════════╗")
307
+ print("║ MPM Commander - Interactive Mode ║")
308
+ print("╚══════════════════════════════════════════╝")
309
+ print("Type 'help' for commands, or natural language to chat.")
310
+ print()
@@ -0,0 +1,51 @@
1
+ """Daemon configuration for MPM Commander.
2
+
3
+ This module defines configuration structures for the Commander daemon,
4
+ including server settings, resource limits, and persistence options.
5
+ """
6
+
7
+ from dataclasses import dataclass
8
+ from pathlib import Path
9
+
10
+
11
+ @dataclass
12
+ class DaemonConfig:
13
+ """Configuration for Commander daemon.
14
+
15
+ Attributes:
16
+ host: API server bind address
17
+ port: API server port (default: 8766 from NetworkPorts.COMMANDER_DEFAULT)
18
+ log_level: Logging level (DEBUG, INFO, WARNING, ERROR)
19
+ state_dir: Directory for state persistence
20
+ max_projects: Maximum concurrent projects
21
+ healthcheck_interval: Healthcheck interval in seconds
22
+ save_interval: State persistence interval in seconds
23
+ poll_interval: Event polling interval in seconds
24
+ summarize_responses: Whether to use LLM to summarize instance responses
25
+
26
+ Example:
27
+ >>> config = DaemonConfig(port=8766, log_level="DEBUG")
28
+ >>> config.state_dir
29
+ PosixPath('/Users/user/.claude-mpm/commander')
30
+ """
31
+
32
+ host: str = "127.0.0.1"
33
+ port: int = 8766 # Default commander port (from network_config.NetworkPorts.COMMANDER_DEFAULT)
34
+ log_level: str = "INFO"
35
+ state_dir: Path = Path.home() / ".claude-mpm" / "commander"
36
+ max_projects: int = 10
37
+ healthcheck_interval: int = 30
38
+ save_interval: int = 30
39
+ poll_interval: float = 2.0
40
+ summarize_responses: bool = True
41
+
42
+ def __post_init__(self):
43
+ """Ensure state_dir is a Path object and create if needed."""
44
+ if isinstance(self.state_dir, str):
45
+ self.state_dir = Path(self.state_dir)
46
+
47
+ # Expand user home directory
48
+ self.state_dir = self.state_dir.expanduser()
49
+
50
+ # Create state directory if it doesn't exist
51
+ self.state_dir.mkdir(parents=True, exist_ok=True)