claude-mpm 5.4.96__py3-none-any.whl → 5.6.17__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 (214) hide show
  1. claude_mpm/VERSION +1 -1
  2. claude_mpm/agents/{CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md → CLAUDE_MPM_RESEARCH_OUTPUT_STYLE.md} +14 -6
  3. claude_mpm/agents/PM_INSTRUCTIONS.md +44 -10
  4. claude_mpm/agents/WORKFLOW.md +2 -0
  5. claude_mpm/agents/templates/circuit-breakers.md +26 -17
  6. claude_mpm/cli/commands/autotodos.py +45 -5
  7. claude_mpm/cli/commands/commander.py +216 -0
  8. claude_mpm/cli/commands/hook_errors.py +60 -60
  9. claude_mpm/cli/commands/run.py +35 -3
  10. claude_mpm/cli/commands/skill_source.py +51 -2
  11. claude_mpm/cli/commands/skills.py +5 -3
  12. claude_mpm/cli/executor.py +32 -17
  13. claude_mpm/cli/parsers/base_parser.py +17 -0
  14. claude_mpm/cli/parsers/commander_parser.py +116 -0
  15. claude_mpm/cli/parsers/run_parser.py +10 -0
  16. claude_mpm/cli/parsers/skill_source_parser.py +4 -0
  17. claude_mpm/cli/parsers/skills_parser.py +5 -0
  18. claude_mpm/cli/startup.py +124 -3
  19. claude_mpm/cli/startup_display.py +2 -1
  20. claude_mpm/cli/utils.py +7 -3
  21. claude_mpm/commander/__init__.py +78 -0
  22. claude_mpm/commander/adapters/__init__.py +60 -0
  23. claude_mpm/commander/adapters/auggie.py +260 -0
  24. claude_mpm/commander/adapters/base.py +288 -0
  25. claude_mpm/commander/adapters/claude_code.py +392 -0
  26. claude_mpm/commander/adapters/codex.py +237 -0
  27. claude_mpm/commander/adapters/communication.py +366 -0
  28. claude_mpm/commander/adapters/example_usage.py +310 -0
  29. claude_mpm/commander/adapters/mpm.py +389 -0
  30. claude_mpm/commander/adapters/registry.py +204 -0
  31. claude_mpm/commander/api/__init__.py +16 -0
  32. claude_mpm/commander/api/app.py +121 -0
  33. claude_mpm/commander/api/errors.py +133 -0
  34. claude_mpm/commander/api/routes/__init__.py +8 -0
  35. claude_mpm/commander/api/routes/events.py +184 -0
  36. claude_mpm/commander/api/routes/inbox.py +171 -0
  37. claude_mpm/commander/api/routes/messages.py +148 -0
  38. claude_mpm/commander/api/routes/projects.py +271 -0
  39. claude_mpm/commander/api/routes/sessions.py +226 -0
  40. claude_mpm/commander/api/routes/work.py +296 -0
  41. claude_mpm/commander/api/schemas.py +186 -0
  42. claude_mpm/commander/chat/__init__.py +7 -0
  43. claude_mpm/commander/chat/cli.py +111 -0
  44. claude_mpm/commander/chat/commands.py +96 -0
  45. claude_mpm/commander/chat/repl.py +310 -0
  46. claude_mpm/commander/config.py +49 -0
  47. claude_mpm/commander/config_loader.py +115 -0
  48. claude_mpm/commander/core/__init__.py +10 -0
  49. claude_mpm/commander/core/block_manager.py +325 -0
  50. claude_mpm/commander/core/response_manager.py +323 -0
  51. claude_mpm/commander/daemon.py +594 -0
  52. claude_mpm/commander/env_loader.py +59 -0
  53. claude_mpm/commander/events/__init__.py +26 -0
  54. claude_mpm/commander/events/manager.py +332 -0
  55. claude_mpm/commander/frameworks/__init__.py +12 -0
  56. claude_mpm/commander/frameworks/base.py +143 -0
  57. claude_mpm/commander/frameworks/claude_code.py +58 -0
  58. claude_mpm/commander/frameworks/mpm.py +62 -0
  59. claude_mpm/commander/inbox/__init__.py +16 -0
  60. claude_mpm/commander/inbox/dedup.py +128 -0
  61. claude_mpm/commander/inbox/inbox.py +224 -0
  62. claude_mpm/commander/inbox/models.py +70 -0
  63. claude_mpm/commander/instance_manager.py +337 -0
  64. claude_mpm/commander/llm/__init__.py +6 -0
  65. claude_mpm/commander/llm/openrouter_client.py +167 -0
  66. claude_mpm/commander/llm/summarizer.py +70 -0
  67. claude_mpm/commander/memory/__init__.py +45 -0
  68. claude_mpm/commander/memory/compression.py +347 -0
  69. claude_mpm/commander/memory/embeddings.py +230 -0
  70. claude_mpm/commander/memory/entities.py +310 -0
  71. claude_mpm/commander/memory/example_usage.py +290 -0
  72. claude_mpm/commander/memory/integration.py +325 -0
  73. claude_mpm/commander/memory/search.py +381 -0
  74. claude_mpm/commander/memory/store.py +657 -0
  75. claude_mpm/commander/models/__init__.py +18 -0
  76. claude_mpm/commander/models/events.py +121 -0
  77. claude_mpm/commander/models/project.py +162 -0
  78. claude_mpm/commander/models/work.py +214 -0
  79. claude_mpm/commander/parsing/__init__.py +20 -0
  80. claude_mpm/commander/parsing/extractor.py +132 -0
  81. claude_mpm/commander/parsing/output_parser.py +270 -0
  82. claude_mpm/commander/parsing/patterns.py +100 -0
  83. claude_mpm/commander/persistence/__init__.py +11 -0
  84. claude_mpm/commander/persistence/event_store.py +274 -0
  85. claude_mpm/commander/persistence/state_store.py +309 -0
  86. claude_mpm/commander/persistence/work_store.py +164 -0
  87. claude_mpm/commander/polling/__init__.py +13 -0
  88. claude_mpm/commander/polling/event_detector.py +104 -0
  89. claude_mpm/commander/polling/output_buffer.py +49 -0
  90. claude_mpm/commander/polling/output_poller.py +153 -0
  91. claude_mpm/commander/project_session.py +268 -0
  92. claude_mpm/commander/proxy/__init__.py +12 -0
  93. claude_mpm/commander/proxy/formatter.py +89 -0
  94. claude_mpm/commander/proxy/output_handler.py +191 -0
  95. claude_mpm/commander/proxy/relay.py +155 -0
  96. claude_mpm/commander/registry.py +410 -0
  97. claude_mpm/commander/runtime/__init__.py +10 -0
  98. claude_mpm/commander/runtime/executor.py +191 -0
  99. claude_mpm/commander/runtime/monitor.py +346 -0
  100. claude_mpm/commander/session/__init__.py +6 -0
  101. claude_mpm/commander/session/context.py +81 -0
  102. claude_mpm/commander/session/manager.py +59 -0
  103. claude_mpm/commander/tmux_orchestrator.py +361 -0
  104. claude_mpm/commander/web/__init__.py +1 -0
  105. claude_mpm/commander/work/__init__.py +30 -0
  106. claude_mpm/commander/work/executor.py +207 -0
  107. claude_mpm/commander/work/queue.py +405 -0
  108. claude_mpm/commander/workflow/__init__.py +27 -0
  109. claude_mpm/commander/workflow/event_handler.py +241 -0
  110. claude_mpm/commander/workflow/notifier.py +146 -0
  111. claude_mpm/commands/mpm-config.md +8 -0
  112. claude_mpm/commands/mpm-doctor.md +8 -0
  113. claude_mpm/commands/mpm-help.md +8 -0
  114. claude_mpm/commands/mpm-init.md +8 -0
  115. claude_mpm/commands/mpm-monitor.md +8 -0
  116. claude_mpm/commands/mpm-organize.md +8 -0
  117. claude_mpm/commands/mpm-postmortem.md +8 -0
  118. claude_mpm/commands/mpm-session-resume.md +8 -0
  119. claude_mpm/commands/mpm-status.md +8 -0
  120. claude_mpm/commands/mpm-ticket-view.md +8 -0
  121. claude_mpm/commands/mpm-version.md +8 -0
  122. claude_mpm/commands/mpm.md +8 -0
  123. claude_mpm/config/agent_presets.py +8 -7
  124. claude_mpm/config/skill_sources.py +16 -0
  125. claude_mpm/core/claude_runner.py +143 -0
  126. claude_mpm/core/config.py +32 -19
  127. claude_mpm/core/logger.py +26 -9
  128. claude_mpm/core/logging_utils.py +35 -11
  129. claude_mpm/core/output_style_manager.py +49 -12
  130. claude_mpm/core/unified_config.py +10 -6
  131. claude_mpm/core/unified_paths.py +68 -80
  132. claude_mpm/experimental/cli_enhancements.py +2 -1
  133. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-312.pyc +0 -0
  134. claude_mpm/hooks/claude_hooks/__pycache__/__init__.cpython-314.pyc +0 -0
  135. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-311.pyc +0 -0
  136. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-312.pyc +0 -0
  137. claude_mpm/hooks/claude_hooks/__pycache__/auto_pause_handler.cpython-314.pyc +0 -0
  138. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-311.pyc +0 -0
  139. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-312.pyc +0 -0
  140. claude_mpm/hooks/claude_hooks/__pycache__/event_handlers.cpython-314.pyc +0 -0
  141. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-311.pyc +0 -0
  142. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-312.pyc +0 -0
  143. claude_mpm/hooks/claude_hooks/__pycache__/hook_handler.cpython-314.pyc +0 -0
  144. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-311.pyc +0 -0
  145. claude_mpm/hooks/claude_hooks/__pycache__/installer.cpython-314.pyc +0 -0
  146. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-311.pyc +0 -0
  147. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-312.pyc +0 -0
  148. claude_mpm/hooks/claude_hooks/__pycache__/memory_integration.cpython-314.pyc +0 -0
  149. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-311.pyc +0 -0
  150. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-312.pyc +0 -0
  151. claude_mpm/hooks/claude_hooks/__pycache__/response_tracking.cpython-314.pyc +0 -0
  152. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-312.pyc +0 -0
  153. claude_mpm/hooks/claude_hooks/__pycache__/tool_analysis.cpython-314.pyc +0 -0
  154. claude_mpm/hooks/claude_hooks/auto_pause_handler.py +29 -30
  155. claude_mpm/hooks/claude_hooks/event_handlers.py +112 -99
  156. claude_mpm/hooks/claude_hooks/hook_handler.py +81 -88
  157. claude_mpm/hooks/claude_hooks/hook_wrapper.sh +6 -11
  158. claude_mpm/hooks/claude_hooks/installer.py +116 -8
  159. claude_mpm/hooks/claude_hooks/memory_integration.py +51 -31
  160. claude_mpm/hooks/claude_hooks/response_tracking.py +39 -58
  161. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-312.pyc +0 -0
  162. claude_mpm/hooks/claude_hooks/services/__pycache__/__init__.cpython-314.pyc +0 -0
  163. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
  164. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-311.pyc +0 -0
  165. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-312.pyc +0 -0
  166. claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager_http.cpython-314.pyc +0 -0
  167. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-312.pyc +0 -0
  168. claude_mpm/hooks/claude_hooks/services/__pycache__/duplicate_detector.cpython-314.pyc +0 -0
  169. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-311.pyc +0 -0
  170. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-312.pyc +0 -0
  171. claude_mpm/hooks/claude_hooks/services/__pycache__/state_manager.cpython-314.pyc +0 -0
  172. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-311.pyc +0 -0
  173. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-312.pyc +0 -0
  174. claude_mpm/hooks/claude_hooks/services/__pycache__/subagent_processor.cpython-314.pyc +0 -0
  175. claude_mpm/hooks/claude_hooks/services/connection_manager.py +23 -28
  176. claude_mpm/hooks/claude_hooks/services/connection_manager_http.py +36 -103
  177. claude_mpm/hooks/claude_hooks/services/state_manager.py +23 -36
  178. claude_mpm/hooks/claude_hooks/services/subagent_processor.py +47 -73
  179. claude_mpm/hooks/session_resume_hook.py +22 -18
  180. claude_mpm/hooks/templates/pre_tool_use_template.py +10 -2
  181. claude_mpm/scripts/claude-hook-handler.sh +43 -16
  182. claude_mpm/scripts/start_activity_logging.py +0 -0
  183. claude_mpm/services/agents/agent_recommendation_service.py +8 -8
  184. claude_mpm/services/agents/agent_selection_service.py +2 -2
  185. claude_mpm/services/agents/loading/framework_agent_loader.py +75 -2
  186. claude_mpm/services/agents/single_tier_deployment_service.py +4 -4
  187. claude_mpm/services/event_log.py +8 -0
  188. claude_mpm/services/pm_skills_deployer.py +84 -6
  189. claude_mpm/services/skills/git_skill_source_manager.py +130 -10
  190. claude_mpm/services/skills/selective_skill_deployer.py +28 -0
  191. claude_mpm/services/skills/skill_discovery_service.py +74 -4
  192. claude_mpm/services/skills_deployer.py +31 -5
  193. claude_mpm/skills/__init__.py +2 -1
  194. claude_mpm/skills/bundled/pm/mpm/SKILL.md +38 -0
  195. claude_mpm/skills/bundled/pm/mpm-config/SKILL.md +29 -0
  196. claude_mpm/skills/bundled/pm/mpm-doctor/SKILL.md +53 -0
  197. claude_mpm/skills/bundled/pm/mpm-help/SKILL.md +35 -0
  198. claude_mpm/skills/bundled/pm/mpm-init/SKILL.md +125 -0
  199. claude_mpm/skills/bundled/pm/mpm-monitor/SKILL.md +32 -0
  200. claude_mpm/skills/bundled/pm/mpm-organize/SKILL.md +121 -0
  201. claude_mpm/skills/bundled/pm/mpm-postmortem/SKILL.md +22 -0
  202. claude_mpm/skills/bundled/pm/mpm-session-pause/SKILL.md +170 -0
  203. claude_mpm/skills/bundled/pm/mpm-session-resume/SKILL.md +31 -0
  204. claude_mpm/skills/bundled/pm/mpm-status/SKILL.md +37 -0
  205. claude_mpm/skills/bundled/pm/mpm-ticket-view/SKILL.md +110 -0
  206. claude_mpm/skills/bundled/pm/mpm-version/SKILL.md +21 -0
  207. claude_mpm/skills/registry.py +295 -90
  208. {claude_mpm-5.4.96.dist-info → claude_mpm-5.6.17.dist-info}/METADATA +22 -6
  209. {claude_mpm-5.4.96.dist-info → claude_mpm-5.6.17.dist-info}/RECORD +213 -83
  210. {claude_mpm-5.4.96.dist-info → claude_mpm-5.6.17.dist-info}/WHEEL +0 -0
  211. {claude_mpm-5.4.96.dist-info → claude_mpm-5.6.17.dist-info}/entry_points.txt +0 -0
  212. {claude_mpm-5.4.96.dist-info → claude_mpm-5.6.17.dist-info}/licenses/LICENSE +0 -0
  213. {claude_mpm-5.4.96.dist-info → claude_mpm-5.6.17.dist-info}/licenses/LICENSE-FAQ.md +0 -0
  214. {claude_mpm-5.4.96.dist-info → claude_mpm-5.6.17.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION CHANGED
@@ -1 +1 @@
1
- 5.4.96
1
+ 5.6.17
@@ -1,11 +1,11 @@
1
1
  ---
2
- name: Claude MPM Founders
3
- description: Non-technical explanations for startup founders inspecting codebases
2
+ name: Claude MPM Research
3
+ description: Codebase research tool for founders, PMs, and developers - deep analysis in accessible language
4
4
  ---
5
5
 
6
- # Claude MPM for Founders
6
+ # Claude MPM Research Mode
7
7
 
8
- **Your code inspection companion** - Get clear, actionable insights about your codebase without needing to understand programming.
8
+ **Your codebase research companion** - Get clear, actionable insights about any codebase, whether you're a founder, PM, or developer.
9
9
 
10
10
  ## Core Principle: Accurate but Accessible
11
11
 
@@ -18,14 +18,22 @@ Technical accuracy is never sacrificed for simplicity. You get the same accurate
18
18
  - Use analogies to explain, but note when the analogy has limits
19
19
  - When precision matters (security, compliance, data integrity), call it out explicitly
20
20
 
21
- ## What This Mode Does
21
+ ## What Research Mode Does
22
22
 
23
- Translates technical details into business language so you can:
23
+ Research Mode provides deep codebase analysis that's accessible to everyone:
24
+
25
+ **For Founders & PMs:**
24
26
  - Understand what your developers are building
25
27
  - Assess code quality and team productivity
26
28
  - Make informed decisions about technical priorities
27
29
  - Spot potential risks before they become problems
28
30
 
31
+ **For Developers:**
32
+ - Quickly understand unfamiliar codebases
33
+ - Get architectural overviews of complex systems
34
+ - Identify technical debt and improvement opportunities
35
+ - Research best practices and patterns in existing code
36
+
29
37
  ---
30
38
 
31
39
  ## Quick Assessment Framework
@@ -8,6 +8,16 @@
8
8
 
9
9
  The Project Manager (PM) agent coordinates work across specialized agents in the Claude MPM framework. The PM's responsibility is orchestration and quality assurance, not direct execution.
10
10
 
11
+ ## 🔴 DELEGATION-BY-DEFAULT PRINCIPLE 🔴
12
+
13
+ **PM ALWAYS delegates unless the user explicitly asks PM to do something directly.**
14
+
15
+ This is the opposite of "delegate when you see trigger keywords." Instead:
16
+ - **DEFAULT action = Delegate to appropriate agent**
17
+ - **EXCEPTION = User says "you do it", "don't delegate", "handle this yourself"**
18
+
19
+ When in doubt, delegate. The PM's value is orchestration, not execution.
20
+
11
21
  ## 🔴 ABSOLUTE PROHIBITIONS 🔴
12
22
 
13
23
  **PM must NEVER:**
@@ -15,7 +25,9 @@ The Project Manager (PM) agent coordinates work across specialized agents in the
15
25
  2. Use Read tool more than ONCE per session - DELEGATE to Research
16
26
  3. Investigate, debug, or analyze code directly - DELEGATE to Research
17
27
  4. Use Edit/Write tools on any file - DELEGATE to Engineer
18
- 5. Run verification commands (curl, lsof) - DELEGATE to local-ops
28
+ 5. Run verification commands (`curl`, `wget`, `lsof`, `netstat`, `ps`, `pm2`, `docker ps`) - DELEGATE to local-ops/QA
29
+ 6. Attempt ANY task directly without first considering delegation
30
+ 7. Assume "simple" tasks don't need delegation - delegate anyway
19
31
 
20
32
  **Violation of any prohibition = Circuit Breaker triggered**
21
33
 
@@ -266,10 +278,11 @@ See mpm-tool-usage-guide skill for complete tool usage patterns and examples.
266
278
  - NEVER source code files (`.py`, `.js`, `.ts`, `.tsx`, etc.)
267
279
  - Investigation keywords trigger delegation, not Read
268
280
 
269
- **Bash Tool** (Navigation and git tracking ONLY):
270
- - Allowed: `ls`, `pwd`, `cd`, `git status`, `git add`, `git commit`
271
- - FORBIDDEN: `curl`, `lsof`, `sed`, `awk`, `echo >`, `grep`, `find`, `cat`
272
- - Verification/implementation → Delegate to appropriate agent
281
+ **Bash Tool** (MINIMAL - navigation and git tracking ONLY):
282
+ - **ALLOWED**: `ls`, `pwd`, `git status`, `git add`, `git commit`, `git push`, `git log`
283
+ - **EVERYTHING ELSE**: Delegate to appropriate agent
284
+
285
+ If you're about to run ANY other command, stop and delegate instead.
273
286
 
274
287
  **Vector Search** (Quick semantic search):
275
288
  - MANDATORY: Use mcp-vector-search BEFORE Read/Research if available
@@ -281,6 +294,8 @@ See mpm-tool-usage-guide skill for complete tool usage patterns and examples.
281
294
  - Grep (>1), Glob (investigation) → Delegate to research
282
295
  - `mcp__mcp-ticketer__*` → Delegate to ticketing
283
296
  - `mcp__chrome-devtools__*` → Delegate to web-qa
297
+ - `mcp__claude-in-chrome__*` → Delegate to web-qa
298
+ - `mcp__playwright__*` → Delegate to web-qa
284
299
 
285
300
  ## Agent Deployment Architecture
286
301
 
@@ -317,13 +332,14 @@ All agents inherit from BASE_AGENT.md which includes:
317
332
  See `src/claude_mpm/agents/BASE_AGENT.md` for complete base instructions.
318
333
 
319
334
 
320
- ## Ops Agent Routing (MANDATORY)
335
+ ## Ops Agent Routing (Examples)
321
336
 
322
- PM MUST route ops tasks to the correct specialized agent:
337
+ These are EXAMPLES of routing, not an exhaustive list. **Default to delegation for ALL ops/infrastructure/deployment/build tasks.**
323
338
 
324
339
  | Trigger Keywords | Agent | Use Case |
325
340
  |------------------|-------|----------|
326
341
  | localhost, PM2, npm, docker-compose, port, process | **local-ops** | Local development |
342
+ | version, release, publish, bump, pyproject.toml, package.json | **local-ops** | Version management, releases |
327
343
  | vercel, edge function, serverless | **vercel-ops** | Vercel platform |
328
344
  | gcp, google cloud, IAM, OAuth consent | **gcp-ops** | Google Cloud |
329
345
  | clerk, auth middleware, OAuth provider | **clerk-ops** | Clerk authentication |
@@ -344,7 +360,7 @@ PM MUST route ops tasks to the correct specialized agent:
344
360
  | **Research** | Understanding codebase, investigating approaches, analyzing files | Grep, Glob, Read multiple files, WebSearch | Investigation tools |
345
361
  | **Engineer** | Writing/modifying code, implementing features, refactoring | Edit, Write, codebase knowledge, testing workflows | - |
346
362
  | **Ops** (local-ops) | Deploying apps, managing infrastructure, starting servers, port/process management | Environment config, deployment procedures | Use `local-ops` for localhost/PM2/docker |
347
- | **QA** (web-qa, api-qa) | Testing implementations, verifying deployments, regression tests, browser testing | Playwright (web), fetch (APIs), verification protocols | For browser: use **web-qa** (never use chrome-devtools directly) |
363
+ | **QA** (web-qa, api-qa) | Testing implementations, verifying deployments, regression tests, browser testing | Playwright (web), fetch (APIs), verification protocols | For browser: use **web-qa** (never use chrome-devtools, claude-in-chrome, or playwright directly) |
348
364
  | **Documentation** | Creating/updating docs, README, API docs, guides | Style consistency, organization standards | - |
349
365
  | **Ticketing** | ALL ticket operations (CRUD, search, hierarchy, comments) | Direct mcp-ticketer access | PM never uses `mcp__mcp-ticketer__*` directly |
350
366
  | **Version Control** | Creating PRs, managing branches, complex git ops | PR workflows, branch management | Check git user for main branch access (bobmatnyc@users.noreply.github.com only) |
@@ -714,7 +730,7 @@ Circuit breakers automatically detect and enforce delegation requirements. All c
714
730
  | 3 | Unverified Assertions | PM claiming status without agent evidence | Require verification evidence | [Details](#circuit-breaker-3-unverified-assertions) |
715
731
  | 4 | File Tracking | PM marking task complete without tracking new files | Run git tracking sequence | [Details](#circuit-breaker-4-file-tracking-enforcement) |
716
732
  | 5 | Delegation Chain | PM claiming completion without full workflow delegation | Execute missing phases | [Details](#circuit-breaker-5-delegation-chain) |
717
- | 6 | Forbidden Tool Usage | PM using ticketing/browser MCP tools directly | Delegate to specialist agent | [Details](#circuit-breaker-6-forbidden-tool-usage) |
733
+ | 6 | Forbidden Tool Usage | PM using ticketing/browser MCP tools (ticketer, chrome-devtools, claude-in-chrome, playwright) directly | Delegate to specialist agent | [Details](#circuit-breaker-6-forbidden-tool-usage) |
718
734
  | 7 | Verification Commands | PM using curl/lsof/ps/wget/nc | Delegate to local-ops or QA | [Details](#circuit-breaker-7-verification-command-detection) |
719
735
  | 8 | QA Verification Gate | PM claiming work complete without QA delegation | BLOCK - Delegate to QA now | [Details](#circuit-breaker-8-qa-verification-gate) |
720
736
  | 9 | User Delegation | PM instructing user to run commands | Delegate to appropriate agent | [Details](#circuit-breaker-9-user-delegation-detection) |
@@ -733,6 +749,9 @@ Circuit breakers automatically detect and enforce delegation requirements. All c
733
749
  - "It works" / "It's deployed" → Circuit Breaker #3
734
750
  - Marks todo complete without `git status` → Circuit Breaker #4
735
751
  - Uses `mcp__mcp-ticketer__*` → Circuit Breaker #6
752
+ - Uses `mcp__chrome-devtools__*` → Circuit Breaker #6
753
+ - Uses `mcp__claude-in-chrome__*` → Circuit Breaker #6
754
+ - Uses `mcp__playwright__*` → Circuit Breaker #6
736
755
  - Uses curl/lsof directly → Circuit Breaker #7
737
756
  - Claims complete without QA → Circuit Breaker #8
738
757
  - "You'll need to run..." → Circuit Breaker #9
@@ -760,16 +779,22 @@ The skill contains:
760
779
 
761
780
  ## Common User Request Patterns
762
781
 
782
+ **DEFAULT**: Delegate to appropriate agent.
783
+
784
+ The patterns below are guidance for WHICH agent to delegate to, not WHETHER to delegate. Always delegate unless user explicitly says otherwise.
785
+
763
786
  When the user says "just do it" or "handle it", delegate to the full workflow pipeline (Research → Engineer → Ops → QA → Documentation).
764
787
 
765
788
  When the user says "verify", "check", or "test", delegate to the QA agent with specific verification criteria.
766
789
 
767
- When the user mentions "browser", "screenshot", "click", "navigate", "DOM", "console errors", delegate to web-qa agent for browser testing (NEVER use chrome-devtools tools directly).
790
+ When the user mentions "browser", "screenshot", "click", "navigate", "DOM", "console errors", "tabs", "window", delegate to web-qa agent for browser testing (NEVER use chrome-devtools, claude-in-chrome, or playwright tools directly).
768
791
 
769
792
  When the user mentions "localhost", "local server", or "PM2", delegate to **local-ops** as the primary choice for local development operations.
770
793
 
771
794
  When the user mentions "verify running", "check port", or requests verification of deployments, delegate to **local-ops** for local verification or QA agents for deployed endpoints.
772
795
 
796
+ When the user mentions "version", "release", "publish", "bump", or modifying version files (pyproject.toml, package.json, Cargo.toml), delegate to **local-ops** for all version and release management.
797
+
773
798
  When the user mentions ticket IDs or says "ticket", "issue", "create ticket", delegate to ticketing agent for all ticket operations.
774
799
 
775
800
  When the user requests "stacked PRs" or "dependent PRs", delegate to version-control agent with stacked PR parameters.
@@ -778,6 +803,15 @@ When the user says "commit to main" or "push to main", check git user email firs
778
803
 
779
804
  When the user mentions "skill", "add skill", "create skill", "improve skill", "recommend skills", or asks about "project stack", "technologies", "frameworks", delegate to mpm-skills-manager agent for all skill operations and technology analysis.
780
805
 
806
+ ## When PM Acts Directly (Exceptions)
807
+
808
+ PM acts directly ONLY when:
809
+ 1. User explicitly says "you do this", "don't delegate", "handle this yourself"
810
+ 2. Pure orchestration tasks (updating TodoWrite, reporting status)
811
+ 3. Answering questions about PM capabilities or agent availability
812
+
813
+ Everything else = Delegate.
814
+
781
815
  ## Session Management
782
816
 
783
817
  **[SKILL: mpm-session-management]**
@@ -64,6 +64,8 @@ Return: Clean or list of blocked items
64
64
 
65
65
  ## Publish and Release Workflow
66
66
 
67
+ **CRITICAL**: PM MUST DELEGATE all version bumps and releases to local-ops. PM never edits version files (pyproject.toml, package.json, VERSION) directly.
68
+
67
69
  **Note**: Release workflows are project-specific and should be customized per project. See the local-ops agent memory for this project's release workflow, or create one using `/mpm-init` for new projects.
68
70
 
69
71
  For projects with specific release requirements (PyPI, npm, Homebrew, Docker, etc.), the local-ops agent should have the complete workflow documented in its memory file.
@@ -523,23 +523,25 @@ PM: Task(agent="qa", task="Verify bug fix with regression test")
523
523
 
524
524
  ### KEY PRINCIPLE
525
525
 
526
- PM delegates implementation work, then MAY verify results.
526
+ PM delegates ALL work - implementation AND verification.
527
527
 
528
528
  **Workflow:**
529
- 1. **DELEGATE** to agent (using Task tool)
529
+ 1. **DELEGATE** implementation to appropriate agent (using Task tool)
530
530
  2. **WAIT** for agent to complete work
531
- 3. **VERIFY** results (using Bash verification commands OR delegating verification)
532
- 4. **REPORT** verified results with evidence
531
+ 3. **DELEGATE** verification to appropriate agent (local-ops, QA, web-qa)
532
+ 4. **REPORT** verified results with evidence from verification agent
533
533
 
534
- ### Allowed Verification Commands (AFTER Delegation)
534
+ ### PM NEVER Uses Verification Commands
535
535
 
536
- These commands are ALLOWED for quality assurance AFTER delegating implementation:
536
+ **FORBIDDEN for PM** (must delegate to local-ops or QA):
537
537
 
538
- - `curl`, `wget` - HTTP endpoint testing
539
- - `lsof`, `netstat`, `ss` - Port and network checks
540
- - `ps`, `pgrep` - Process status checks
541
- - `pm2 status`, `docker ps` - Service status
542
- - Health check endpoints
538
+ - `curl`, `wget` - HTTP endpoint testing → Delegate to api-qa or local-ops
539
+ - `lsof`, `netstat`, `ss` - Port and network checks → Delegate to local-ops
540
+ - `ps`, `pgrep` - Process status checks → Delegate to local-ops
541
+ - `pm2 status`, `docker ps` - Service status → Delegate to local-ops
542
+ - Health check endpoints → Delegate to api-qa or web-qa
543
+
544
+ **Why PM doesn't verify**: Verification is technical work requiring domain expertise. local-ops and QA agents have the tools, context, and expertise to verify correctly.
543
545
 
544
546
  ### Examples
545
547
 
@@ -550,23 +552,29 @@ These commands are ALLOWED for quality assurance AFTER delegating implementation
550
552
  PM: Bash("npm start") # VIOLATION - implementing
551
553
  PM: "App running on localhost:3000" # VIOLATION - no delegation
552
554
 
555
+ # Wrong: PM using verification commands
556
+ PM: Bash("lsof -i :3000") # VIOLATION - should delegate to local-ops
557
+ PM: Bash("curl http://localhost:3000") # VIOLATION - should delegate to api-qa
558
+
553
559
  # Wrong: PM testing before delegating implementation
554
560
  PM: Bash("npm test") # VIOLATION - testing without implementation
555
561
 
556
562
  # Wrong: "Let me" thinking
557
563
  PM: "Let me check the code..." # VIOLATION - should delegate
558
564
  PM: "Let me fix this bug..." # VIOLATION - should delegate
565
+ PM: "Let me verify the deployment..." # VIOLATION - should delegate to local-ops
559
566
  ```
560
567
 
561
568
  #### ✅ CORRECT Examples
562
569
 
563
570
  ```
564
- # Correct: Delegate first, then verify
565
- PM: Task(agent="local-ops-agent", task="Start app on localhost:3000 using npm")
566
- [Agent starts app]
567
- PM: Bash("lsof -i :3000 | grep LISTEN") # ALLOWED - verifying after delegation
568
- PM: Bash("curl http://localhost:3000") # ALLOWED - confirming deployment
569
- PM: "App verified: Port 3000 listening, HTTP 200 response"
571
+ # Correct: Delegate implementation, then delegate verification
572
+ PM: Task(agent="local-ops", task="Start app on localhost:3000 using npm")
573
+ [local-ops starts app]
574
+ PM: Task(agent="local-ops", task="Verify app is running on port 3000")
575
+ [local-ops uses lsof and curl to verify]
576
+ [local-ops returns: "Port 3000 listening, HTTP 200 response"]
577
+ PM: "App verified by local-ops: Port 3000 listening, HTTP 200 response"
570
578
 
571
579
  # Correct: Delegate implementation, then delegate testing
572
580
  PM: Task(agent="engineer", task="Fix authentication bug")
@@ -578,6 +586,7 @@ PM: "Bug fix verified by QA: All tests passed"
578
586
  # Correct: Thinking in delegation terms
579
587
  PM: "I'll have Research check the code..."
580
588
  PM: "I'll delegate this fix to Engineer..."
589
+ PM: "I'll have local-ops verify the deployment..."
581
590
  ```
582
591
 
583
592
  ---
@@ -16,7 +16,7 @@ DESIGN DECISION: Event-driven architecture
16
16
  import json
17
17
  from datetime import datetime, timezone
18
18
  from pathlib import Path
19
- from typing import Any, Dict, List
19
+ from typing import Any, Dict, List, Optional
20
20
 
21
21
  import click
22
22
 
@@ -101,13 +101,16 @@ def format_delegation_event_as_todo(event: Dict[str, Any]) -> Dict[str, str]:
101
101
  }
102
102
 
103
103
 
104
- def get_autotodos() -> List[Dict[str, Any]]:
104
+ def get_autotodos(max_todos: int = 100) -> List[Dict[str, Any]]:
105
105
  """Get all pending hook error events formatted as todos.
106
106
 
107
107
  DESIGN DECISION: Only autotodo.error events are returned
108
108
  - autotodo.error = Script/coding failures → PM should delegate fix
109
109
  - pm.violation = Delegation anti-patterns → PM behavior error (not todo)
110
110
 
111
+ Args:
112
+ max_todos: Maximum number of todos to return (default: 100)
113
+
111
114
  Returns:
112
115
  List of todo dictionaries ready for PM injection
113
116
  """
@@ -119,7 +122,44 @@ def get_autotodos() -> List[Dict[str, Any]]:
119
122
  event_type="autotodo.error", status="pending"
120
123
  )
121
124
 
122
- for event in pending_error_events:
125
+ for event in pending_error_events[:max_todos]:
126
+ todo = format_error_event_as_todo(event)
127
+ todos.append(todo)
128
+
129
+ return todos
130
+
131
+
132
+ def get_pending_todos(
133
+ max_todos: int = 10, working_dir: Optional[Path] = None
134
+ ) -> List[Dict[str, Any]]:
135
+ """Get pending autotodo errors for injection.
136
+
137
+ WHY this function exists:
138
+ - Provides a consistent API for retrieving pending autotodos
139
+ - Used by CLI inject command AND SessionStart hook
140
+ - Supports limiting number of todos to avoid overwhelming PM
141
+
142
+ Args:
143
+ max_todos: Maximum number of todos to return (default: 10)
144
+ working_dir: Working directory to use for event log path (default: Path.cwd())
145
+
146
+ Returns:
147
+ List of todo dicts with content, activeForm, status, metadata
148
+ """
149
+ # Construct log file path from working_dir if provided
150
+ log_file = None
151
+ if working_dir:
152
+ log_file = Path(working_dir) / ".claude-mpm" / "event_log.json"
153
+
154
+ event_log = get_event_log(log_file)
155
+ todos = []
156
+
157
+ # Get all pending autotodo.error events (script failures)
158
+ pending_error_events = event_log.list_events(
159
+ event_type="autotodo.error", status="pending"
160
+ )
161
+
162
+ for event in pending_error_events[:max_todos]:
123
163
  todo = format_error_event_as_todo(event)
124
164
  todos.append(todo)
125
165
 
@@ -397,7 +437,7 @@ def list_pm_violations(format):
397
437
  for i, violation in enumerate(violations, 1):
398
438
  payload = violation.get("payload", {})
399
439
  click.echo(f"{i}. Pattern: {payload.get('pattern_type', 'Unknown')}")
400
- click.echo(f" Original: \"{payload.get('original_text', '')}\"")
440
+ click.echo(f' Original: "{payload.get("original_text", "")}"')
401
441
  click.echo(f" Should delegate: {payload.get('suggested_action', '')}")
402
442
  click.echo(f" Severity: {payload.get('severity', 'unknown')}")
403
443
  click.echo(f" Timestamp: {violation.get('timestamp', 'Unknown')}")
@@ -502,7 +542,7 @@ def scan_delegation_patterns(text, file, format, save):
502
542
 
503
543
  for i, detection in enumerate(detections, 1):
504
544
  click.echo(f"{i}. Pattern: {detection['pattern_type']}")
505
- click.echo(f" Original: \"{detection['original_text']}\"")
545
+ click.echo(f' Original: "{detection["original_text"]}"')
506
546
  click.echo(f" Suggested Todo: {detection['suggested_todo']}")
507
547
  click.echo(f" Action: {detection['action']}")
508
548
  click.echo()
@@ -0,0 +1,216 @@
1
+ """Commander command handler for CLI."""
2
+
3
+ import asyncio
4
+ import logging
5
+ import shutil
6
+ import threading
7
+ import time
8
+ from pathlib import Path
9
+
10
+ logger = logging.getLogger(__name__)
11
+
12
+ # ANSI colors
13
+ CYAN = "\033[36m"
14
+ DIM = "\033[2m"
15
+ BOLD = "\033[1m"
16
+ YELLOW = "\033[33m"
17
+ GREEN = "\033[32m"
18
+ RED = "\033[31m"
19
+ RESET = "\033[0m"
20
+
21
+
22
+ def _get_terminal_width() -> int:
23
+ """Get terminal width with reasonable bounds."""
24
+ try:
25
+ width = shutil.get_terminal_size().columns
26
+ return max(80, min(width, 120))
27
+ except Exception:
28
+ return 100
29
+
30
+
31
+ def _get_version() -> str:
32
+ """Get Commander version."""
33
+ version_file = Path(__file__).parent.parent.parent / "VERSION"
34
+ if version_file.exists():
35
+ return version_file.read_text().strip()
36
+ return "unknown"
37
+
38
+
39
+ def display_commander_banner():
40
+ """Display Commander-specific startup banner."""
41
+ width = _get_terminal_width()
42
+ version = _get_version()
43
+
44
+ # Commander ASCII art banner
45
+ banner = f"""
46
+ {CYAN}╭{'─' * (width - 2)}╮{RESET}
47
+ {CYAN}│{RESET}{BOLD} ⚡ MPM Commander {RESET}{DIM}v{version}{RESET}{' ' * (width - 24 - len(version))}│
48
+ {CYAN}│{RESET}{DIM} Multi-Project AI Orchestration{RESET}{' ' * (width - 36)}│
49
+ {CYAN}├{'─' * (width - 2)}┤{RESET}
50
+ {CYAN}│{RESET} {YELLOW}ALPHA{RESET} - APIs may change {' ' * (width - 55)}│
51
+ {CYAN}╰{'─' * (width - 2)}╯{RESET}
52
+ """
53
+ print(banner)
54
+
55
+
56
+ def _count_cached_agents() -> int:
57
+ """Count cached agents from ~/.claude-mpm/cache/agents/."""
58
+ try:
59
+ cache_agents_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
60
+ if not cache_agents_dir.exists():
61
+ return 0
62
+ # Recursively find all .md files excluding base/README files
63
+ agent_files = [
64
+ f
65
+ for f in cache_agents_dir.rglob("*.md")
66
+ if f.is_file()
67
+ and not f.name.startswith(".")
68
+ and f.name not in ("README.md", "BASE-AGENT.md", "INSTRUCTIONS.md")
69
+ ]
70
+ return len(agent_files)
71
+ except Exception:
72
+ return 0
73
+
74
+
75
+ def _count_cached_skills() -> int:
76
+ """Count cached skills from ~/.claude-mpm/cache/skills/."""
77
+ try:
78
+ cache_skills_dir = Path.home() / ".claude-mpm" / "cache" / "skills"
79
+ if not cache_skills_dir.exists():
80
+ return 0
81
+ # Recursively find all directories containing SKILL.md
82
+ skill_files = list(cache_skills_dir.rglob("SKILL.md"))
83
+ return len(skill_files)
84
+ except Exception:
85
+ return 0
86
+
87
+
88
+ def load_agents_and_skills():
89
+ """Load agents and skills for Commander sessions."""
90
+ try:
91
+ print(f"{DIM}Loading agents...{RESET}", end=" ", flush=True)
92
+ agent_count = _count_cached_agents()
93
+ print(f"{GREEN}✓{RESET} {agent_count} agents")
94
+
95
+ print(f"{DIM}Loading skills...{RESET}", end=" ", flush=True)
96
+ skill_count = _count_cached_skills()
97
+ print(f"{GREEN}✓{RESET} {skill_count} skills")
98
+
99
+ return agent_count, skill_count
100
+ except Exception as e:
101
+ logger.warning(f"Could not load agents/skills: {e}")
102
+ print(f"{YELLOW}⚠{RESET} Could not load agents/skills")
103
+ return 0, 0
104
+
105
+
106
+ def handle_commander_command(args) -> int:
107
+ """Handle the commander command with auto-starting daemon.
108
+
109
+ Args:
110
+ args: Parsed command line arguments with:
111
+ - port: Port for daemon (default: 8765)
112
+ - host: Host for daemon (default: 127.0.0.1)
113
+ - state_dir: Optional state directory path
114
+ - debug: Enable debug logging
115
+ - no_chat: Start daemon only without interactive chat
116
+ - daemon_only: Alias for no_chat
117
+
118
+ Returns:
119
+ Exit code (0 for success, 1 for error)
120
+ """
121
+ try:
122
+ # Import here to avoid circular dependencies
123
+ import requests
124
+
125
+ from claude_mpm.commander.chat.cli import run_commander
126
+ from claude_mpm.commander.config import DaemonConfig
127
+ from claude_mpm.commander.daemon import main as daemon_main
128
+
129
+ # Setup debug logging if requested
130
+ if getattr(args, "debug", False):
131
+ logging.basicConfig(
132
+ level=logging.DEBUG,
133
+ format="%(asctime)s - %(name)s - %(levelname)s - %(message)s",
134
+ )
135
+
136
+ # Display Commander banner
137
+ display_commander_banner()
138
+
139
+ # Load agents and skills
140
+ load_agents_and_skills()
141
+
142
+ print() # Blank line after loading
143
+
144
+ # Get arguments
145
+ port = getattr(args, "port", 8765)
146
+ host = getattr(args, "host", "127.0.0.1")
147
+ state_dir = getattr(args, "state_dir", None)
148
+ no_chat = getattr(args, "no_chat", False) or getattr(args, "daemon_only", False)
149
+
150
+ # Check if daemon already running
151
+ daemon_running = False
152
+ try:
153
+ resp = requests.get(f"http://{host}:{port}/api/health", timeout=1)
154
+ if resp.status_code == 200:
155
+ print(f"{GREEN}✓{RESET} Daemon already running on {host}:{port}")
156
+ daemon_running = True
157
+ except (requests.RequestException, requests.ConnectionError):
158
+ pass
159
+
160
+ # Start daemon if not running
161
+ if not daemon_running:
162
+ print(
163
+ f"{DIM}Starting daemon on {host}:{port}...{RESET}", end=" ", flush=True
164
+ )
165
+
166
+ # Create daemon config
167
+ config_kwargs = {"host": host, "port": port}
168
+ if state_dir:
169
+ config_kwargs["state_dir"] = state_dir
170
+ config = DaemonConfig(**config_kwargs)
171
+
172
+ # Start daemon in background thread
173
+ daemon_thread = threading.Thread(
174
+ target=lambda: asyncio.run(daemon_main(config)), daemon=True
175
+ )
176
+ daemon_thread.start()
177
+
178
+ # Wait for daemon to be ready (max 3 seconds)
179
+ for _ in range(30):
180
+ time.sleep(0.1)
181
+ try:
182
+ resp = requests.get(f"http://{host}:{port}/api/health", timeout=1)
183
+ if resp.status_code == 200:
184
+ print(f"{GREEN}✓{RESET}")
185
+ daemon_running = True
186
+ break
187
+ except (requests.RequestException, requests.ConnectionError):
188
+ pass
189
+ else:
190
+ print(f"{RED}✗{RESET} Failed (timeout)")
191
+ return 1
192
+
193
+ # If daemon-only mode, keep running until interrupted
194
+ if no_chat:
195
+ print(f"\n{CYAN}Daemon running.{RESET} API at http://{host}:{port}")
196
+ print(f"{DIM}Press Ctrl+C to stop{RESET}\n")
197
+ try:
198
+ while True:
199
+ time.sleep(1)
200
+ except KeyboardInterrupt:
201
+ print(f"\n{DIM}Shutting down...{RESET}")
202
+ return 0
203
+
204
+ # Launch interactive chat
205
+ print(f"\n{CYAN}Entering Commander chat...{RESET}\n")
206
+ asyncio.run(run_commander(port=port, state_dir=state_dir))
207
+
208
+ return 0
209
+
210
+ except KeyboardInterrupt:
211
+ logger.info("Commander interrupted by user")
212
+ return 0
213
+ except Exception as e:
214
+ logger.error(f"Commander error: {e}", exc_info=True)
215
+ print(f"{RED}Error:{RESET} {e}")
216
+ return 1