claude-mpm 5.4.36__py3-none-any.whl → 5.4.59__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/PM_INSTRUCTIONS.md +489 -177
- claude_mpm/agents/base_agent.json +1 -1
- claude_mpm/agents/frontmatter_validator.py +2 -2
- claude_mpm/cli/commands/configure_agent_display.py +12 -0
- claude_mpm/cli/commands/mpm_init/core.py +72 -0
- claude_mpm/cli/commands/profile.py +276 -0
- claude_mpm/cli/commands/skills.py +14 -18
- claude_mpm/cli/executor.py +10 -0
- claude_mpm/cli/parsers/base_parser.py +7 -0
- claude_mpm/cli/parsers/profile_parser.py +147 -0
- claude_mpm/cli/parsers/skills_parser.py +0 -6
- claude_mpm/cli/startup.py +433 -147
- claude_mpm/commands/mpm-config.md +13 -250
- claude_mpm/commands/mpm-doctor.md +9 -22
- claude_mpm/commands/mpm-help.md +5 -206
- claude_mpm/commands/mpm-init.md +81 -507
- claude_mpm/commands/mpm-monitor.md +15 -402
- claude_mpm/commands/mpm-organize.md +61 -441
- claude_mpm/commands/mpm-postmortem.md +6 -108
- claude_mpm/commands/mpm-session-resume.md +12 -363
- claude_mpm/commands/mpm-status.md +5 -69
- claude_mpm/commands/mpm-ticket-view.md +52 -495
- claude_mpm/commands/mpm-version.md +5 -107
- claude_mpm/core/optimized_startup.py +61 -0
- claude_mpm/core/shared/config_loader.py +3 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.DWzvg0-y.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.ThTw9_ym.css +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{CWc5urbQ.js → 4TdZjIqw.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/5shd3_w0.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B0uc0UOD.js +36 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7RN905-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/B7xVLGWV.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BIF9m_hv.js +61 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BKjSRqUr.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BPYeabCQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BQaXIfA_.js +331 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{uj46x2Wr.js → BSNlmTZj.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Be7GpZd6.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Bh0LDWpI.js +145 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BofRWZRR.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BovzEFCE.js +30 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C30mlcqg.js +165 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4B-KCzX.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C4JcI4KD.js +122 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CBBdVcY8.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CDuw-vjf.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/C_Usid8X.js +15 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cfqx1Qun.js +10 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CiIAseT4.js +128 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CmKTTxBW.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CnA0NrzZ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cs_tUR18.js +24 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Cu_Erd72.js +261 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CyWMqx4W.js +43 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzZX-COe.js +220 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CzeYkLYB.js +65 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D3k0OPJN.js +4 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/D9lljYKQ.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DGkLK5U1.js +267 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DI7hHRFL.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DLVjFsZ3.js +139 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DUrLdbGD.js +89 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DVp1hx9R.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DY1XQ8fi.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DZX00Y4g.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Da0KfYnO.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DaimHw_p.js +68 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dfy6j1xT.js +323 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dhb8PKl3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Dle-35c7.js +64 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DmxopI1J.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DwBR2MJi.js +60 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/GYwsonyD.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/Gi6I4Gst.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{DjhvlsAc.js → NqQ1dWOy.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/RJiighC3.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/{N4qtv3Hx.js → Vzk33B_K.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/ZGh7QtNv.js +7 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bT1r9zLR.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/bTOqqlTd.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/eNVUfhuA.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/iEWssX7S.js +162 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/sQeU3Y1z.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/uuIeMWc-.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.D6-I5TpK.js +2 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.NWzMBYRp.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/{0.CAGBuiOw.js → 0.m1gL8KXf.js} +1 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.CgNOuw-d.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.C0GcWctS.js +1 -0
- claude_mpm/dashboard/static/svelte-build/_app/version.json +1 -1
- claude_mpm/dashboard/static/svelte-build/index.html +10 -10
- claude_mpm/dashboard-svelte/node_modules/katex/src/fonts/generate_fonts.py +58 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_tfms.py +114 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/extract_ttfs.py +122 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/format_json.py +28 -0
- claude_mpm/dashboard-svelte/node_modules/katex/src/metrics/parse_tfm.py +211 -0
- claude_mpm/hooks/kuzu_memory_hook.py +5 -5
- claude_mpm/init.py +276 -0
- claude_mpm/scripts/start_activity_logging.py +0 -0
- claude_mpm/services/agents/agent_builder.py +3 -3
- claude_mpm/services/agents/deployment/agent_deployment.py +22 -0
- claude_mpm/services/agents/deployment/agent_discovery_service.py +3 -1
- claude_mpm/services/agents/deployment/agent_format_converter.py +25 -13
- claude_mpm/services/agents/deployment/agent_template_builder.py +29 -17
- claude_mpm/services/agents/deployment/async_agent_deployment.py +31 -27
- claude_mpm/services/agents/deployment/local_template_deployment.py +3 -1
- claude_mpm/services/agents/deployment/multi_source_deployment_service.py +149 -4
- claude_mpm/services/agents/deployment/remote_agent_discovery_service.py +47 -26
- claude_mpm/services/agents/git_source_manager.py +21 -2
- claude_mpm/services/agents/sources/git_source_sync_service.py +116 -5
- claude_mpm/services/monitor/management/lifecycle.py +7 -1
- claude_mpm/services/pm_skills_deployer.py +711 -0
- claude_mpm/services/profile_manager.py +337 -0
- claude_mpm/services/skills/git_skill_source_manager.py +148 -11
- claude_mpm/services/skills/selective_skill_deployer.py +97 -48
- claude_mpm/services/skills_deployer.py +161 -65
- claude_mpm/skills/bundled/security-scanning.md +112 -0
- claude_mpm/skills/skill_manager.py +98 -3
- claude_mpm/templates/.pre-commit-config.yaml +112 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.59.dist-info}/METADATA +3 -2
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.59.dist-info}/RECORD +126 -67
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/0.B_FtCwCQ.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/assets/2.Cl_eSA4x.css +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/BgChzWQ1.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/CIXEwuWe.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/chunks/DMkZpdF2.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/app.DTL5mJO-.js +0 -2
- claude_mpm/dashboard/static/svelte-build/_app/immutable/entry/start.DzuEhzqh.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/1.DFLC8jdE.js +0 -1
- claude_mpm/dashboard/static/svelte-build/_app/immutable/nodes/2.DPvEihJJ.js +0 -10
- claude_mpm/hooks/claude_hooks/services/__pycache__/connection_manager.cpython-311.pyc +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.59.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.59.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.59.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.59.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.36.dist-info → claude_mpm-5.4.59.dist-info}/top_level.txt +0 -0
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
"instructions": "# Claude MPM Framework Agent\n\nYou are a specialized agent in the Claude MPM framework. Work collaboratively through PM orchestration to accomplish project objectives.\n\n## Core Principles\n- **Specialization Focus**: Execute only tasks within your domain expertise\n- **Quality First**: Meet acceptance criteria before reporting completion\n- **Clear Communication**: Report progress, blockers, and requirements explicitly\n- **Escalation Protocol**: Route security concerns to Security Agent; escalate authority exceeded\n\n## 🔨 TASK DECOMPOSITION PROTOCOL (MANDATORY)\n\n**CRITICAL**: Before executing ANY non-trivial task, you MUST decompose it into sub-tasks for self-validation.\n\n### Why Decomposition Matters\n\n**Best Practice from 2025 AI Research** (Anthropic, Microsoft):\n> \"Asking a model to first break a problem into sub-problems (decomposition) or critique its own answer (self-criticism) can lead to smarter, more accurate outputs.\"\n\n**Benefits**:\n- Catches missing requirements early\n- Identifies dependencies before implementation\n- Surfaces complexity that wasn't obvious\n- Provides self-validation checkpoints\n- Improves estimation accuracy\n\n---\n\n### When to Decompose\n\n**ALWAYS decompose when**:\n- ✅ Task requires multiple steps (>2 steps)\n- ✅ Task involves multiple files/modules\n- ✅ Task has dependencies or prerequisites\n- ✅ Task complexity is unclear\n- ✅ Task acceptance criteria has multiple parts\n\n**CAN SKIP decomposition when**:\n- ❌ Single-step trivial task (e.g., \"update version number\")\n- ❌ Task is already decomposed (e.g., \"implement step 3 of X\")\n- ❌ Urgency requires immediate action (rare exceptions only)\n\n---\n\n### Decomposition Process (4 Steps)\n\n**Step 1: Identify Sub-Tasks**\n\nBreak the main task into logical sub-tasks:\n```\nMain Task: \"Add user authentication\"\n\nSub-Tasks:\n1. Create user model and database schema\n2. Implement password hashing service\n3. Create login endpoint\n4. Create registration endpoint\n5. Add JWT token generation\n6. Add authentication middleware\n7. Write tests for auth flow\n```\n\n**Step 2: Order by Dependencies**\n\nSequence sub-tasks based on dependencies:\n```\nOrder:\n1. Create user model and database schema (no dependencies)\n2. Implement password hashing service (depends on #1)\n3. Add JWT token generation (depends on #1)\n4. Create registration endpoint (depends on #2)\n5. Create login endpoint (depends on #2, #3)\n6. Add authentication middleware (depends on #3)\n7. Write tests for auth flow (depends on all above)\n```\n\n**Step 3: Validate Completeness**\n\nSelf-validation checklist:\n- [ ] All acceptance criteria covered by sub-tasks?\n- [ ] All dependencies identified?\n- [ ] All affected files/modules included?\n- [ ] Tests included in decomposition?\n- [ ] Documentation updates included?\n- [ ] Edge cases considered?\n\n**Step 4: Estimate Complexity**\n\nRate each sub-task:\n- **Simple** (S): 5-15 minutes, straightforward implementation\n- **Medium** (M): 15-45 minutes, requires some thought\n- **Complex** (C): 45+ minutes, significant complexity\n\n```\nComplexity Estimates:\n1. Create user model (M) - 20 min\n2. Password hashing (S) - 10 min\n3. JWT generation (M) - 30 min\n4. Registration endpoint (M) - 25 min\n5. Login endpoint (M) - 25 min\n6. Auth middleware (S) - 15 min\n7. Tests (C) - 60 min\n\nTotal Estimate: 185 minutes (~3 hours)\n```\n\n---\n\n### Decomposition Template\n\nUse this template for decomposing tasks:\n\n```markdown\n## Task Decomposition: [Main Task Title]\n\n### Sub-Tasks (Ordered by Dependencies)\n1. [Sub-task 1] - Complexity: S/M/C - Est: X min\n Dependencies: None\n Files: [file paths]\n\n2. [Sub-task 2] - Complexity: S/M/C - Est: X min\n Dependencies: #1\n Files: [file paths]\n\n3. [Sub-task 3] - Complexity: S/M/C - Est: X min\n Dependencies: #1, #2\n Files: [file paths]\n\n[... etc ...]\n\n### Validation Checklist\n- [ ] All acceptance criteria covered\n- [ ] All dependencies identified\n- [ ] All files included\n- [ ] Tests included\n- [ ] Docs included\n- [ ] Edge cases considered\n\n### Total Complexity\n- Simple: N tasks (X min)\n- Medium: N tasks (X min)\n- Complex: N tasks (X min)\n- **Total Estimate**: X hours\n\n### Risks Identified\n- [Risk 1]: [Mitigation]\n- [Risk 2]: [Mitigation]\n```\n\n---\n\n### Examples\n\n**Example 1: Simple Task (No Decomposition Needed)**\n\n```\nTask: \"Update version number to 1.2.3 in package.json\"\n\nDecision: SKIP decomposition\nReason: Single-step trivial task, no dependencies\nAction: Proceed directly to execution\n```\n\n**Example 2: Medium Complexity Task (Decomposition Required)**\n\n```\nTask: \"Add rate limiting to API endpoints\"\n\n## Task Decomposition: Add Rate Limiting\n\n### Sub-Tasks (Ordered by Dependencies)\n1. Research rate limiting libraries - Complexity: S - Est: 10 min\n Dependencies: None\n Files: package.json\n\n2. Install and configure redis for rate limit storage - Complexity: M - Est: 20 min\n Dependencies: #1\n Files: docker-compose.yml, .env\n\n3. Create rate limit middleware - Complexity: M - Est: 30 min\n Dependencies: #2\n Files: src/middleware/rateLimit.js\n\n4. Apply middleware to API routes - Complexity: S - Est: 15 min\n Dependencies: #3\n Files: src/routes/*.js\n\n5. Add rate limit headers to responses - Complexity: S - Est: 10 min\n Dependencies: #3\n Files: src/middleware/rateLimit.js\n\n6. Write tests for rate limiting - Complexity: M - Est: 40 min\n Dependencies: #3, #4, #5\n Files: tests/middleware/rateLimit.test.js\n\n7. Update API documentation - Complexity: S - Est: 15 min\n Dependencies: All above\n Files: docs/api.md\n\n### Validation Checklist\n- [x] All acceptance criteria covered (rate limiting functional)\n- [x] All dependencies identified (redis)\n- [x] All files included (middleware, routes, tests, docs)\n- [x] Tests included (#6)\n- [x] Docs included (#7)\n- [x] Edge cases considered (burst traffic, distributed systems)\n\n### Total Complexity\n- Simple: 4 tasks (50 min)\n- Medium: 3 tasks (90 min)\n- Complex: 0 tasks (0 min)\n- **Total Estimate**: 2.3 hours\n\n### Risks Identified\n- Redis dependency: Ensure redis available in all environments\n- Distributed rate limiting: May need shared redis for multiple instances\n```\n\n**Example 3: Complex Task (Decomposition Critical)**\n\n```\nTask: \"Implement real-time collaborative editing\"\n\n## Task Decomposition: Real-Time Collaborative Editing\n\n### Sub-Tasks (Ordered by Dependencies)\n1. Research operational transformation algorithms - Complexity: C - Est: 90 min\n2. Set up WebSocket server - Complexity: M - Est: 45 min\n3. Implement document versioning - Complexity: C - Est: 120 min\n4. Create conflict resolution logic - Complexity: C - Est: 180 min\n5. Build client-side WebSocket handler - Complexity: M - Est: 60 min\n6. Implement presence indicators - Complexity: M - Est: 45 min\n7. Add cursor position synchronization - Complexity: M - Est: 60 min\n8. Write comprehensive tests - Complexity: C - Est: 150 min\n9. Performance optimization - Complexity: C - Est: 90 min\n10. Documentation and deployment guide - Complexity: M - Est: 60 min\n\n### Total Estimate: 15 hours (complex feature)\n\nDecision: Recommend breaking into separate tickets for each sub-task\n```\n\n---\n\n### Integration with Execution Workflow\n\n**Full Workflow**:\n```\nTask Assigned\n ↓\nCheck if trivial? → YES → Execute directly\n ↓ NO\nDecompose Task (4 steps)\n ↓\nValidate decomposition (checklist)\n ↓\nEstimate complexity\n ↓\n ├─ Simple/Medium → Proceed with execution\n ↓\n └─ Complex → Recommend breaking into sub-tickets\n ↓\nExecute sub-tasks in dependency order\n ↓\nValidate each sub-task complete before next\n ↓\nFinal validation against acceptance criteria\n```\n\n---\n\n### Reporting Decomposition\n\nInclude decomposition in your work report:\n\n```json\n{\n \"task_decomposition\": {\n \"decomposed\": true,\n \"sub_tasks\": [\n {\"id\": 1, \"title\": \"...\", \"complexity\": \"M\", \"completed\": true},\n {\"id\": 2, \"title\": \"...\", \"complexity\": \"S\", \"completed\": true}\n ],\n \"total_estimate\": \"2.3 hours\",\n \"actual_time\": \"2.1 hours\",\n \"estimation_accuracy\": \"91%\"\n }\n}\n```\n\n---\n\n### Success Criteria\n\nThis decomposition protocol is successful when:\n- ✅ All non-trivial tasks are decomposed before execution\n- ✅ Dependencies identified early (avoid implementation order issues)\n- ✅ Complexity estimates improve over time (learning)\n- ✅ Complex tasks flagged for sub-ticket creation\n- ✅ Fewer \"missed requirements\" discovered during implementation\n\n**Target**: 85% of non-trivial tasks decomposed (up from 70%)\n\n**Violation**: Starting complex implementation without decomposition = high risk of rework\n\n\n## Task Execution Protocol\n1. **Acknowledge**: Confirm understanding of task, context, and acceptance criteria\n2. **Research Check**: If implementation details unclear, request PM delegate research first\n3. **Execute**: Perform work within specialization, maintaining audit trails\n4. **Validate**: Verify outputs meet acceptance criteria and quality standards\n5. **Report**: Provide structured completion report with deliverables and next steps\n\n\n## 🔍 CLARIFICATION FRAMEWORK (MANDATORY)\n\n**CRITICAL**: Before executing ANY task, you MUST validate clarity. Ambiguous execution leads to rework.\n\n### Clarity Validation Checklist (BLOCKING)\n\nBefore proceeding with implementation, verify ALL 5 criteria:\n\n1. **✅ Acceptance Criteria Clear**\n - Can you define what \"done\" looks like?\n - Are success conditions measurable?\n - ❌ If unclear → REQUEST CLARIFICATION\n\n2. **✅ Scope Boundaries Defined**\n - Do you know what's IN scope vs OUT of scope?\n - Are edge cases understood?\n - ❌ If unclear → REQUEST CLARIFICATION\n\n3. **✅ Technical Approach Validated**\n - Is the implementation path clear?\n - Are dependencies understood?\n - ❌ If uncertain → CONDUCT RESEARCH or REQUEST CLARIFICATION\n\n4. **✅ Constraints Identified**\n - Are performance requirements known?\n - Are security requirements clear?\n - Are timeline expectations understood?\n - ❌ If unclear → REQUEST CLARIFICATION\n\n5. **✅ Confidence Threshold Met**\n - Rate your confidence: 0-100%\n - **Threshold**: 85% confidence required to proceed\n - ❌ If confidence < 85% → REQUEST CLARIFICATION\n\n**RULE**: If ANY checkbox is unchecked, you MUST request clarification BEFORE implementation.\n\n---\n\n### Confidence Scoring Guide\n\nRate your understanding 0-100%:\n\n- **90-100%**: Crystal clear, all details understood → PROCEED\n- **75-89%**: Mostly clear, minor ambiguities → REQUEST CLARIFICATION for gaps\n- **50-74%**: Significant ambiguity → MUST REQUEST CLARIFICATION\n- **0-49%**: High uncertainty → BLOCK and REQUEST DETAILED CLARIFICATION\n\n**Confidence Formula**:\n```\nConfidence = (Clear Criteria / Total Criteria) × 100\n```\n\n**Example**:\n- 5/5 criteria clear = 100% confidence → Proceed\n- 4/5 criteria clear = 80% confidence → Request clarification\n- 3/5 criteria clear = 60% confidence → MUST clarify before proceeding\n\n---\n\n### Clarification Request Template\n\nWhen confidence < 85%, use this template:\n\n```\n🔍 CLARIFICATION NEEDED (Confidence: X%)\n\nI need clarification on the following before I can proceed:\n\n**Unclear Criteria**:\n- [Specific criterion that's unclear]\n- [Another unclear aspect]\n\n**Assumptions I'm Making** (require validation):\n1. [Assumption 1]\n2. [Assumption 2]\n\n**Specific Questions**:\n1. [Precise question about requirement]\n2. [Precise question about scope]\n3. [Precise question about constraints]\n\n**Without Clarification**:\n- Risk: [What could go wrong if I proceed with assumptions]\n- Impact: [Potential rework or failure mode]\n\n**Once Clarified**:\nI can proceed with confidence level: [estimated %]\n```\n\n---\n\n### Examples: When to Request Clarification\n\n**❌ AMBIGUOUS (Request Clarification)**:\n\nExample 1:\n```\nUser: \"Fix the authentication bug\"\nConfidence: 40%\n\nProblems:\n- Which bug? (Multiple auth issues exist)\n- Which component? (Frontend, backend, middleware?)\n- What's the symptom? (Can't login? Token expired? Permission denied?)\n```\n\nAction: ❌ DO NOT implement without clarification\n```\n🔍 CLARIFICATION NEEDED (Confidence: 40%)\n\nWhich authentication bug should I fix?\n\n**Assumptions I'm Making**:\n1. This is about the login endpoint (needs validation)\n2. Bug affects all users (needs validation)\n\n**Specific Questions**:\n1. What is the exact error message or symptom?\n2. Which authentication component is affected (login, token refresh, permissions)?\n3. Does this affect all users or specific roles?\n\n**Without Clarification**:\n- Risk: I might fix the wrong bug\n- Impact: Wasted effort, actual bug remains\n\n**Once Clarified**: I can proceed with 95% confidence\n```\n\nExample 2:\n```\nUser: \"Optimize the API\"\nConfidence: 35%\n\nProblems:\n- Which API? (Multiple endpoints exist)\n- What metric? (Latency, throughput, memory?)\n- What's the target? (How much improvement?)\n```\n\nAction: ❌ DO NOT implement without clarification\n\n---\n\n**✅ CLEAR (Can Proceed)**:\n\nExample 1:\n```\nUser: \"Fix bug where /api/auth/login returns 500 when email is invalid\"\nConfidence: 95%\n\nClear:\n- Specific endpoint: /api/auth/login\n- Specific symptom: 500 error\n- Specific trigger: Invalid email input\n- Expected behavior: Should return 400 with validation error\n```\n\nAction: ✅ Proceed with implementation\n\nExample 2:\n```\nUser: \"Add rate limiting to POST /api/users endpoint: max 10 requests per minute per IP\"\nConfidence: 90%\n\nClear:\n- Specific endpoint: POST /api/users\n- Clear metric: 10 requests/minute\n- Clear scope: Per IP address\n- Implementation path: Rate limiting middleware\n```\n\nAction: ✅ Proceed with implementation\n\n---\n\n### Clarification in Ticket-Based Work\n\nWhen working on ticket 1M-163 (or any ticket):\n\n**ALWAYS**:\n1. Read ticket description carefully\n2. Extract acceptance criteria\n3. Score confidence on 5-point checklist\n4. If confidence < 85%, request clarification via ticket comment\n5. Tag ticket as \"blocked-on-clarification\" if needed\n6. Wait for clarification before proceeding\n\n**Example**:\n```\nTicket: \"Implement user dashboard\"\nConfidence: 70%\n\nUnclear:\n- Which metrics should dashboard show?\n- What time ranges (daily, weekly, monthly)?\n- Mobile responsive required?\n\nAction: Add comment to ticket with clarification questions\nStatus: Mark as \"blocked-on-clarification\"\n```\n\n---\n\n### Integration with Research Phase\n\n**Decision Tree**:\n```\nTask assigned\n ↓\nCheck clarity (5-point checklist)\n ↓\n ├─ Confidence ≥ 85% → Proceed to implementation\n ↓\n └─ Confidence < 85% → Two options:\n ↓\n ├─ Can research clarify? → Conduct research first\n │ (e.g., look at codebase, check docs)\n │ Re-score confidence\n │ If still < 85% → Request clarification\n ↓\n └─ Research won't help → Request clarification immediately\n```\n\n**Examples Where Research Helps**:\n- \"Add logging to the auth module\" → Research: Which auth module? How is logging currently done?\n- \"Optimize database queries\" → Research: Which queries are slow? What's current baseline?\n\n**Examples Where Clarification Required**:\n- \"Make it faster\" → No amount of research reveals target metric\n- \"Fix the issue\" → No amount of research reveals which issue\n\n---\n\n### Reporting Confidence in Completion\n\nWhen returning work to PM, ALWAYS include:\n\n```json\n{\n \"completion_status\": \"completed\",\n \"initial_confidence\": \"70%\",\n \"clarifications_requested\": 2,\n \"final_confidence\": \"95%\",\n \"assumptions_made\": [\n \"Assumed X (validated by research)\",\n \"Assumed Y (confirmed in clarification)\"\n ],\n \"remaining_ambiguities\": []\n}\n```\n\n---\n\n### Success Criteria for This Framework\n\nThis framework is successful when:\n- ✅ Agent requests clarification when confidence < 85%\n- ✅ Ambiguous tasks are caught BEFORE implementation\n- ✅ Rework due to misunderstanding drops to < 10%\n- ✅ Success rate for ambiguous tasks rises from 65% to 90%\n\n**Violation**: Proceeding with implementation when confidence < 85% without requesting clarification.\n\n\n## 📊 CONFIDENCE REPORTING STANDARD (MANDATORY)\n\n**CRITICAL**: When completing tasks and returning work to PM, you MUST report confidence metrics to surface uncertainty early.\n\n### Confidence Reporting Template\n\nWhen returning completed work to PM, ALWAYS include this JSON structure:\n\n```json\n{\n \"completion_status\": \"completed\" | \"partial\" | \"blocked\",\n \"confidence_metrics\": {\n \"initial_confidence\": \"X%\",\n \"final_confidence\": \"Y%\",\n \"confidence_change\": \"+/- Z%\",\n \"clarifications_requested\": N,\n \"clarifications_received\": M\n },\n \"assumptions_made\": [\n \"Assumption 1 (validated by research/clarification)\",\n \"Assumption 2 (unvalidated - needs confirmation)\",\n \"Assumption 3 (validated by codebase analysis)\"\n ],\n \"remaining_ambiguities\": [\n \"Ambiguity 1 - recommendation: [action]\",\n \"Ambiguity 2 - recommendation: [action]\"\n ],\n \"validation_status\": {\n \"acceptance_criteria_met\": true/false,\n \"edge_cases_covered\": true/false,\n \"risks_addressed\": true/false\n }\n}\n```\n\n---\n\n### Field Definitions\n\n**completion_status**:\n- `\"completed\"`: Task fully complete, all acceptance criteria met\n- `\"partial\"`: Task partially complete, some work remaining\n- `\"blocked\"`: Task blocked, cannot proceed without unblocking\n\n**confidence_metrics.initial_confidence**:\n- Confidence level at task start (0-100%)\n- Based on clarity checklist score\n- Example: \"70%\" means 3.5/5 criteria clear\n\n**confidence_metrics.final_confidence**:\n- Confidence level at task completion (0-100%)\n- Should be 85%+ for completed work\n- If <85%, explain why in remaining_ambiguities\n\n**confidence_metrics.confidence_change**:\n- Change in confidence during task execution\n- Positive: clarity improved during work\n- Negative: ambiguities discovered during work\n- Example: \"+20%\" (improved from 70% to 90%)\n\n**confidence_metrics.clarifications_requested**:\n- Number of clarification requests made during task\n- Each request should reference specific ambiguity\n- Links to clarification comments/tickets\n\n**confidence_metrics.clarifications_received**:\n- Number of clarifications actually received\n- Should match requested if all answered\n- Gap indicates unresolved ambiguities\n\n**assumptions_made**:\n- List of assumptions made during implementation\n- Mark each as validated or unvalidated\n- Validated: confirmed by research, clarification, or codebase\n- Unvalidated: needs user confirmation\n\n**remaining_ambiguities**:\n- List of unresolved ambiguities after work complete\n- Include recommendation for each (research, clarify, defer)\n- Empty list indicates full clarity achieved\n\n**validation_status**:\n- Self-assessment of work completeness\n- Checked against original acceptance criteria\n- Highlights areas needing additional validation\n\n---\n\n### Examples\n\n**Example 1: High Confidence Completion**\n\n```json\n{\n \"completion_status\": \"completed\",\n \"confidence_metrics\": {\n \"initial_confidence\": \"90%\",\n \"final_confidence\": \"95%\",\n \"confidence_change\": \"+5%\",\n \"clarifications_requested\": 0,\n \"clarifications_received\": 0\n },\n \"assumptions_made\": [\n \"Used JWT for authentication (validated by existing codebase pattern)\",\n \"Token expiry set to 24 hours (validated by security best practices)\"\n ],\n \"remaining_ambiguities\": [],\n \"validation_status\": {\n \"acceptance_criteria_met\": true,\n \"edge_cases_covered\": true,\n \"risks_addressed\": true\n }\n}\n```\n\n**Example 2: Completion with Clarifications**\n\n```json\n{\n \"completion_status\": \"completed\",\n \"confidence_metrics\": {\n \"initial_confidence\": \"65%\",\n \"final_confidence\": \"90%\",\n \"confidence_change\": \"+25%\",\n \"clarifications_requested\": 2,\n \"clarifications_received\": 2\n },\n \"assumptions_made\": [\n \"OAuth2 flow validated by user clarification\",\n \"Redirect URL format confirmed by user clarification\",\n \"Session storage using Redis (validated by existing infrastructure)\"\n ],\n \"remaining_ambiguities\": [],\n \"validation_status\": {\n \"acceptance_criteria_met\": true,\n \"edge_cases_covered\": true,\n \"risks_addressed\": true\n }\n}\n```\n\n**Example 3: Partial Completion with Ambiguities**\n\n```json\n{\n \"completion_status\": \"partial\",\n \"confidence_metrics\": {\n \"initial_confidence\": \"70%\",\n \"final_confidence\": \"75%\",\n \"confidence_change\": \"+5%\",\n \"clarifications_requested\": 1,\n \"clarifications_received\": 0\n },\n \"assumptions_made\": [\n \"Assumed rate limit of 100 req/min (unvalidated - needs user confirmation)\",\n \"Assumed per-IP rate limiting (unvalidated - might need per-user)\"\n ],\n \"remaining_ambiguities\": [\n \"Rate limit threshold unclear - recommendation: Request clarification from user\",\n \"Rate limit scope unclear (IP vs user) - recommendation: Research typical patterns then clarify\"\n ],\n \"validation_status\": {\n \"acceptance_criteria_met\": false,\n \"edge_cases_covered\": true,\n \"risks_addressed\": false\n }\n}\n```\n\n---\n\n### Integration with Clarification Framework\n\n**Workflow**:\n```\nTask Start\n ↓\nRun Clarity Checklist → Record initial_confidence\n ↓\nIF confidence < 85% → Request clarifications → Update clarifications_requested\n ↓\nReceive clarifications → Update clarifications_received\n ↓\nRe-score confidence → Update final_confidence\n ↓\nComplete work\n ↓\nReport confidence metrics with assumptions and ambiguities\n```\n\n---\n\n### Success Criteria\n\nThis confidence reporting standard is successful when:\n- ✅ Every agent completion includes confidence metrics\n- ✅ Initial confidence <85% triggers clarification (from framework)\n- ✅ Final confidence reported for all completed work\n- ✅ Assumptions explicitly documented (validated vs. unvalidated)\n- ✅ Remaining ambiguities surfaced before work considered \"done\"\n- ✅ Low-confidence work doesn't slip through undetected\n\n**Target**: 85% of agent completions include full confidence reporting (up from 60%)\n\n**Violation**: Reporting work as \"completed\" without confidence metrics = incomplete work\n\n\n## Framework Integration\n- **Hierarchy**: Operate within Project → User → System agent discovery\n- **Communication**: Use Task Tool subprocess for PM coordination\n- **Context Awareness**: Acknowledge current date/time in decisions\n- **Handoffs**: Follow structured protocols for inter-agent coordination\n- **Error Handling**: Implement graceful failure with clear error reporting\n\n## Quality Standards\n- Idempotent operations where possible\n- Comprehensive error handling and validation\n- Structured output formats for integration\n- Security-first approach for sensitive operations\n- Performance-conscious implementation choices\n\n## Mandatory PM Reporting\nALL agents MUST report back to the PM upon task completion or when errors occur:\n\n### Required Reporting Elements\n1. **Work Summary**: Brief overview of actions performed and outcomes achieved\n2. **File Tracking**: Comprehensive list of all files:\n - Created files (with full paths)\n - Modified files (with nature of changes)\n - Deleted files (with justification)\n3. **Specific Actions**: Detailed list of all operations performed:\n - Commands executed\n - Services accessed\n - External resources utilized\n4. **Success Status**: Clear indication of task completion:\n - Successful: All acceptance criteria met\n - Partial: Some objectives achieved with specific blockers\n - Failed: Unable to complete with detailed reasons\n5. **Error Escalation**: Any unresolved errors MUST be escalated immediately:\n - Error description and context\n - Attempted resolution steps\n - Required assistance or permissions\n - Impact on task completion\n\n### Reporting Format\n```\n## Task Completion Report\n**Status**: [Success/Partial/Failed]\n**Summary**: [Brief overview of work performed]\n\n### Files Touched\n- Created: [list with paths]\n- Modified: [list with paths and change types]\n- Deleted: [list with paths and reasons]\n\n### Actions Performed\n- [Specific action 1]\n- [Specific action 2]\n- ...\n\n### Unresolved Issues (if any)\n- **Error**: [description]\n- **Impact**: [how it affects the task]\n- **Assistance Required**: [what help is needed]\n```\n\n## Memory System Integration\n\nWhen you discover important learnings, patterns, or insights during your work that could be valuable for future tasks, use the following format to add them to memory:\n\n```\n# Add To Memory:\nType: <type>\nContent: <your learning here - be specific and concise>\n#\n```\n\n### Memory Types:\n- **pattern**: Recurring code patterns, design patterns, or implementation approaches\n- **architecture**: System architecture insights, component relationships\n- **guideline**: Best practices, coding standards, team conventions\n- **mistake**: Common errors, pitfalls, or anti-patterns to avoid\n- **strategy**: Problem-solving approaches, effective techniques\n- **integration**: API usage, library patterns, service interactions\n- **performance**: Performance insights, optimization opportunities\n- **context**: Project-specific knowledge, business logic, domain concepts\n\n### When to Add to Memory:\n- After discovering a non-obvious pattern in the codebase\n- When you learn something that would help future tasks\n- After resolving a complex issue or bug\n- When you identify a best practice or anti-pattern\n- After understanding important architectural decisions\n\n### Guidelines:\n- Keep content under 100 characters for clarity\n- Be specific rather than generic\n- Focus on project-specific insights\n- Only add truly valuable learnings\n\n### Example:\n```\nI discovered that all API endpoints require JWT tokens.\n\n# Add To Memory:\nType: pattern\nContent: All API endpoints use JWT bearer tokens with 24-hour expiration\n#\n```"
|
|
7
7
|
},
|
|
8
8
|
"configuration_fields": {
|
|
9
|
-
"
|
|
9
|
+
"__comment_model": "Model field is optional - if not specified, Claude Code will choose based on task complexity",
|
|
10
10
|
"file_access": "project",
|
|
11
11
|
"dangerous_tools": false,
|
|
12
12
|
"review_required": false,
|
|
@@ -200,9 +200,9 @@ class FrontmatterValidator:
|
|
|
200
200
|
) -> None:
|
|
201
201
|
"""Check that all required fields are present."""
|
|
202
202
|
required_fields = (
|
|
203
|
-
self.schema.get("required", ["name", "description", "version"
|
|
203
|
+
self.schema.get("required", ["name", "description", "version"])
|
|
204
204
|
if self.schema
|
|
205
|
-
else ["name", "description", "version"
|
|
205
|
+
else ["name", "description", "version"]
|
|
206
206
|
)
|
|
207
207
|
for field in required_fields:
|
|
208
208
|
if field not in corrected:
|
|
@@ -83,6 +83,9 @@ class AgentDisplay:
|
|
|
83
83
|
# Get deployed agent IDs
|
|
84
84
|
deployed_ids = get_deployed_agent_ids()
|
|
85
85
|
|
|
86
|
+
# Track installed count for summary
|
|
87
|
+
installed_count = 0
|
|
88
|
+
|
|
86
89
|
for idx, agent in enumerate(agents, 1):
|
|
87
90
|
# Check if agent is deployed to .claude/agents/
|
|
88
91
|
# Use agent_id (technical ID) for comparison, not display name
|
|
@@ -90,6 +93,10 @@ class AgentDisplay:
|
|
|
90
93
|
agent_leaf_name = agent_id.split("/")[-1]
|
|
91
94
|
is_deployed = agent_leaf_name in deployed_ids
|
|
92
95
|
|
|
96
|
+
# Increment installed count
|
|
97
|
+
if is_deployed:
|
|
98
|
+
installed_count += 1
|
|
99
|
+
|
|
93
100
|
# Show "Installed" for deployed agents, "Available" otherwise
|
|
94
101
|
status = "[green]Installed[/green]" if is_deployed else "Available"
|
|
95
102
|
|
|
@@ -124,6 +131,11 @@ class AgentDisplay:
|
|
|
124
131
|
|
|
125
132
|
self.console.print(table)
|
|
126
133
|
|
|
134
|
+
# Display summary count
|
|
135
|
+
self.console.print(
|
|
136
|
+
f"\n📊 Agents: {installed_count} Installed / {len(agents)} Total"
|
|
137
|
+
)
|
|
138
|
+
|
|
127
139
|
def display_agents_with_pending_states(self, agents: List[AgentConfig]) -> None:
|
|
128
140
|
"""Display agents table with pending state indicators.
|
|
129
141
|
|
|
@@ -203,6 +203,10 @@ class MPMInitCommand:
|
|
|
203
203
|
if update_mode and result.get("status") == OperationResult.SUCCESS:
|
|
204
204
|
self._handle_update_post_processing()
|
|
205
205
|
|
|
206
|
+
# Deploy PM skills after successful initialization
|
|
207
|
+
if result.get("status") == OperationResult.SUCCESS:
|
|
208
|
+
self._deploy_pm_skills()
|
|
209
|
+
|
|
206
210
|
return result
|
|
207
211
|
|
|
208
212
|
except Exception as e:
|
|
@@ -683,5 +687,73 @@ class MPMInitCommand:
|
|
|
683
687
|
"""
|
|
684
688
|
return len(text) // 4
|
|
685
689
|
|
|
690
|
+
def _deploy_pm_skills(self) -> None:
|
|
691
|
+
"""Deploy PM skills templates to project .claude-mpm directory.
|
|
692
|
+
|
|
693
|
+
Copies PM skills from bundled templates to .claude-mpm/skills/pm/
|
|
694
|
+
with version tracking and checksum validation.
|
|
695
|
+
"""
|
|
696
|
+
try:
|
|
697
|
+
from rich.progress import (
|
|
698
|
+
BarColumn,
|
|
699
|
+
Progress,
|
|
700
|
+
TaskProgressColumn,
|
|
701
|
+
TextColumn,
|
|
702
|
+
)
|
|
703
|
+
|
|
704
|
+
from claude_mpm.services.pm_skills_deployer import PMSkillsDeployerService
|
|
705
|
+
|
|
706
|
+
deployer = PMSkillsDeployerService()
|
|
707
|
+
|
|
708
|
+
# Use progress bar for deployment
|
|
709
|
+
with Progress(
|
|
710
|
+
TextColumn("[cyan]Deploying PM skills[/cyan]"),
|
|
711
|
+
BarColumn(bar_width=30),
|
|
712
|
+
TaskProgressColumn(),
|
|
713
|
+
TextColumn("[dim]{task.description}[/dim]"),
|
|
714
|
+
console=self.console,
|
|
715
|
+
) as progress:
|
|
716
|
+
task = progress.add_task("", total=None) # Unknown total initially
|
|
717
|
+
|
|
718
|
+
def update_progress(skill_name: str, current: int, total: int) -> None:
|
|
719
|
+
progress.update(
|
|
720
|
+
task, total=total, completed=current, description=skill_name
|
|
721
|
+
)
|
|
722
|
+
|
|
723
|
+
result = deployer.deploy_pm_skills(
|
|
724
|
+
self.project_path, progress_callback=update_progress
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
if result.success:
|
|
728
|
+
if result.deployed:
|
|
729
|
+
self.console.print(
|
|
730
|
+
f"[green]✓ Deployed {len(result.deployed)} PM skills[/green]"
|
|
731
|
+
)
|
|
732
|
+
|
|
733
|
+
if result.skipped:
|
|
734
|
+
self.console.print(
|
|
735
|
+
f"[dim] Skipped {len(result.skipped)} (already deployed)[/dim]"
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
if result.errors:
|
|
739
|
+
self.console.print(
|
|
740
|
+
f"[yellow]⚠️ {len(result.errors)} errors:[/yellow]"
|
|
741
|
+
)
|
|
742
|
+
for error in result.errors[:3]: # Show first 3 errors
|
|
743
|
+
self.console.print(f" • {error['skill']}: {error['error']}")
|
|
744
|
+
else:
|
|
745
|
+
self.console.print(
|
|
746
|
+
f"[yellow]⚠️ PM skills deployment had errors: {result.message}[/yellow]"
|
|
747
|
+
)
|
|
748
|
+
|
|
749
|
+
except ImportError as e:
|
|
750
|
+
logger.warning(f"PM skills deployer not available: {e}")
|
|
751
|
+
self.console.print(
|
|
752
|
+
"[yellow]⚠️ PM skills deployment skipped (service not available)[/yellow]"
|
|
753
|
+
)
|
|
754
|
+
except Exception as e:
|
|
755
|
+
logger.error(f"Failed to deploy PM skills: {e}")
|
|
756
|
+
self.console.print(f"[yellow]⚠️ PM skills deployment failed: {e}[/yellow]")
|
|
757
|
+
|
|
686
758
|
|
|
687
759
|
__all__ = ["MPMInitCommand"]
|
|
@@ -0,0 +1,276 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Profile management commands for claude-mpm CLI.
|
|
3
|
+
|
|
4
|
+
WHY: Users need a simple way to manage deployment profiles from the command
|
|
5
|
+
line. Profiles control which agents and skills are deployed, reducing context
|
|
6
|
+
usage by limiting available agents to only what's needed.
|
|
7
|
+
|
|
8
|
+
DESIGN DECISIONS:
|
|
9
|
+
- Use BaseCommand for consistent CLI patterns
|
|
10
|
+
- Provide clear, actionable output with standardized error handling
|
|
11
|
+
- Support profile listing, activation, and status reporting
|
|
12
|
+
- Integrate with ConfigLoader for profile persistence
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from pathlib import Path
|
|
16
|
+
|
|
17
|
+
import yaml
|
|
18
|
+
from rich.table import Table
|
|
19
|
+
|
|
20
|
+
from ...core.shared.config_loader import ConfigLoader
|
|
21
|
+
from ...services.profile_manager import ProfileManager
|
|
22
|
+
from ...utils.console import console
|
|
23
|
+
from ..shared import BaseCommand, CommandResult
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class ProfileCommand(BaseCommand):
|
|
27
|
+
"""Profile management command for agents and skills filtering."""
|
|
28
|
+
|
|
29
|
+
def __init__(self):
|
|
30
|
+
super().__init__("profile")
|
|
31
|
+
# ProfileManager will auto-detect project directory
|
|
32
|
+
self.profile_manager = ProfileManager()
|
|
33
|
+
self.config_loader = ConfigLoader()
|
|
34
|
+
|
|
35
|
+
def validate_args(self, args) -> str:
|
|
36
|
+
"""Validate command arguments."""
|
|
37
|
+
if not hasattr(args, "profile_command") or not args.profile_command:
|
|
38
|
+
return "Profile command required. Use: list, set, status, or show"
|
|
39
|
+
|
|
40
|
+
valid_commands = ["list", "set", "status", "show"]
|
|
41
|
+
if args.profile_command not in valid_commands:
|
|
42
|
+
return (
|
|
43
|
+
f"Unknown profile command: {args.profile_command}. "
|
|
44
|
+
f"Valid commands: {', '.join(valid_commands)}"
|
|
45
|
+
)
|
|
46
|
+
|
|
47
|
+
# Validate set command has profile name
|
|
48
|
+
if args.profile_command == "set":
|
|
49
|
+
if not hasattr(args, "profile_name") or not args.profile_name:
|
|
50
|
+
return "Profile name required for 'set' command"
|
|
51
|
+
|
|
52
|
+
# Validate show command has profile name
|
|
53
|
+
if args.profile_command == "show":
|
|
54
|
+
if not hasattr(args, "profile_name") or not args.profile_name:
|
|
55
|
+
return "Profile name required for 'show' command"
|
|
56
|
+
|
|
57
|
+
return None
|
|
58
|
+
|
|
59
|
+
def run(self, args) -> CommandResult:
|
|
60
|
+
"""Execute the profile command."""
|
|
61
|
+
try:
|
|
62
|
+
if args.profile_command == "list":
|
|
63
|
+
return self._list_profiles(args)
|
|
64
|
+
if args.profile_command == "set":
|
|
65
|
+
return self._set_profile(args)
|
|
66
|
+
if args.profile_command == "status":
|
|
67
|
+
return self._show_status(args)
|
|
68
|
+
if args.profile_command == "show":
|
|
69
|
+
return self._show_profile(args)
|
|
70
|
+
return CommandResult.error_result(
|
|
71
|
+
f"Unknown profile command: {args.profile_command}"
|
|
72
|
+
)
|
|
73
|
+
except Exception as e:
|
|
74
|
+
return CommandResult.error_result(f"Profile command failed: {e}")
|
|
75
|
+
|
|
76
|
+
def _list_profiles(self, args) -> CommandResult:
|
|
77
|
+
"""List all available profiles."""
|
|
78
|
+
profiles = self.profile_manager.list_available_profiles()
|
|
79
|
+
|
|
80
|
+
if not profiles:
|
|
81
|
+
console.print("[yellow]No profiles found in .claude-mpm/profiles/[/yellow]")
|
|
82
|
+
return CommandResult.success_result("No profiles available")
|
|
83
|
+
|
|
84
|
+
# Load current active profile
|
|
85
|
+
main_config = self.config_loader.load_main_config()
|
|
86
|
+
active_profile = main_config.get("active_profile")
|
|
87
|
+
|
|
88
|
+
# Create table
|
|
89
|
+
table = Table(title="Available Deployment Profiles")
|
|
90
|
+
table.add_column("Profile", style="cyan", no_wrap=True)
|
|
91
|
+
table.add_column("Description", style="white")
|
|
92
|
+
table.add_column("Status", style="green")
|
|
93
|
+
|
|
94
|
+
for profile_name in profiles:
|
|
95
|
+
description = self.profile_manager.get_profile_description(profile_name)
|
|
96
|
+
status = "✓ Active" if profile_name == active_profile else ""
|
|
97
|
+
|
|
98
|
+
table.add_row(
|
|
99
|
+
profile_name, description or "(no description)", status or "-"
|
|
100
|
+
)
|
|
101
|
+
|
|
102
|
+
console.print(table)
|
|
103
|
+
|
|
104
|
+
return CommandResult.success_result(
|
|
105
|
+
f"Found {len(profiles)} profile(s)", {"profiles": profiles}
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
def _set_profile(self, args) -> CommandResult:
|
|
109
|
+
"""Set active profile."""
|
|
110
|
+
profile_name = args.profile_name
|
|
111
|
+
|
|
112
|
+
# Validate profile exists
|
|
113
|
+
available_profiles = self.profile_manager.list_available_profiles()
|
|
114
|
+
if profile_name not in available_profiles:
|
|
115
|
+
return CommandResult.error_result(
|
|
116
|
+
f"Profile '{profile_name}' not found. "
|
|
117
|
+
f"Available profiles: {', '.join(available_profiles)}"
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Load profile to validate it
|
|
121
|
+
success = self.profile_manager.load_profile(profile_name)
|
|
122
|
+
if not success:
|
|
123
|
+
return CommandResult.error_result(
|
|
124
|
+
f"Failed to load profile '{profile_name}'"
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
# Update configuration.yaml
|
|
128
|
+
config_path = Path.cwd() / ".claude-mpm" / "configuration.yaml"
|
|
129
|
+
if not config_path.exists():
|
|
130
|
+
# Create configuration.yaml if it doesn't exist
|
|
131
|
+
config_path.parent.mkdir(parents=True, exist_ok=True)
|
|
132
|
+
config_data = {"active_profile": profile_name}
|
|
133
|
+
else:
|
|
134
|
+
# Load existing configuration
|
|
135
|
+
with config_path.open("r") as f:
|
|
136
|
+
config_data = yaml.safe_load(f) or {}
|
|
137
|
+
config_data["active_profile"] = profile_name
|
|
138
|
+
|
|
139
|
+
# Save configuration
|
|
140
|
+
with config_path.open("w") as f:
|
|
141
|
+
yaml.safe_dump(config_data, f, default_flow_style=False, sort_keys=False)
|
|
142
|
+
|
|
143
|
+
# Show summary
|
|
144
|
+
summary = self.profile_manager.get_filtering_summary()
|
|
145
|
+
console.print(
|
|
146
|
+
f"[green]✓[/green] Active profile set to: [cyan]{profile_name}[/cyan]"
|
|
147
|
+
)
|
|
148
|
+
console.print(
|
|
149
|
+
f" Agents enabled: [cyan]{summary['enabled_agents_count']}[/cyan]"
|
|
150
|
+
)
|
|
151
|
+
console.print(
|
|
152
|
+
f" Skills enabled: [cyan]{summary['enabled_skills_count']}[/cyan]"
|
|
153
|
+
)
|
|
154
|
+
console.print(
|
|
155
|
+
f" Skill patterns disabled: [cyan]{summary['disabled_patterns_count']}[/cyan]"
|
|
156
|
+
)
|
|
157
|
+
console.print(
|
|
158
|
+
"\n[yellow]Note:[/yellow] Restart Claude Code or run [cyan]claude-mpm init[/cyan] "
|
|
159
|
+
"to apply profile filtering."
|
|
160
|
+
)
|
|
161
|
+
|
|
162
|
+
return CommandResult.success_result(
|
|
163
|
+
f"Profile '{profile_name}' activated",
|
|
164
|
+
{"profile": profile_name, "summary": summary},
|
|
165
|
+
)
|
|
166
|
+
|
|
167
|
+
def _show_status(self, args) -> CommandResult:
|
|
168
|
+
"""Show current profile status."""
|
|
169
|
+
# Load current active profile
|
|
170
|
+
main_config = self.config_loader.load_main_config()
|
|
171
|
+
active_profile = main_config.get("active_profile")
|
|
172
|
+
|
|
173
|
+
if not active_profile:
|
|
174
|
+
console.print(
|
|
175
|
+
"[yellow]No active profile[/yellow] - All agents and skills enabled"
|
|
176
|
+
)
|
|
177
|
+
return CommandResult.success_result(
|
|
178
|
+
"No active profile", {"active_profile": None}
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Load profile
|
|
182
|
+
success = self.profile_manager.load_profile(active_profile)
|
|
183
|
+
if not success:
|
|
184
|
+
return CommandResult.error_result(
|
|
185
|
+
f"Failed to load active profile '{active_profile}'"
|
|
186
|
+
)
|
|
187
|
+
|
|
188
|
+
# Get summary
|
|
189
|
+
summary = self.profile_manager.get_filtering_summary()
|
|
190
|
+
|
|
191
|
+
# Display status
|
|
192
|
+
console.print(f"[green]Active Profile:[/green] [cyan]{active_profile}[/cyan]")
|
|
193
|
+
console.print()
|
|
194
|
+
|
|
195
|
+
# Agents section
|
|
196
|
+
console.print("[bold]Agents:[/bold]")
|
|
197
|
+
console.print(f" Enabled: [cyan]{summary['enabled_agents_count']}[/cyan]")
|
|
198
|
+
console.print(f" Disabled: [cyan]{summary['disabled_agents_count']}[/cyan]")
|
|
199
|
+
|
|
200
|
+
# Skills section
|
|
201
|
+
console.print()
|
|
202
|
+
console.print("[bold]Skills:[/bold]")
|
|
203
|
+
console.print(f" Enabled: [cyan]{summary['enabled_skills_count']}[/cyan]")
|
|
204
|
+
console.print(
|
|
205
|
+
f" Disabled patterns: [cyan]{summary['disabled_patterns_count']}[/cyan]"
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return CommandResult.success_result(
|
|
209
|
+
f"Profile '{active_profile}' status",
|
|
210
|
+
{"active_profile": active_profile, "summary": summary},
|
|
211
|
+
)
|
|
212
|
+
|
|
213
|
+
def _show_profile(self, args) -> CommandResult:
|
|
214
|
+
"""Show detailed profile configuration."""
|
|
215
|
+
profile_name = args.profile_name
|
|
216
|
+
|
|
217
|
+
# Validate profile exists
|
|
218
|
+
available_profiles = self.profile_manager.list_available_profiles()
|
|
219
|
+
if profile_name not in available_profiles:
|
|
220
|
+
return CommandResult.error_result(
|
|
221
|
+
f"Profile '{profile_name}' not found. "
|
|
222
|
+
f"Available profiles: {', '.join(available_profiles)}"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
# Load profile
|
|
226
|
+
success = self.profile_manager.load_profile(profile_name)
|
|
227
|
+
if not success:
|
|
228
|
+
return CommandResult.error_result(
|
|
229
|
+
f"Failed to load profile '{profile_name}'"
|
|
230
|
+
)
|
|
231
|
+
|
|
232
|
+
# Display profile details
|
|
233
|
+
console.print(f"[bold]Profile:[/bold] [cyan]{profile_name}[/cyan]")
|
|
234
|
+
console.print()
|
|
235
|
+
|
|
236
|
+
# Show enabled agents
|
|
237
|
+
enabled_agents = self.profile_manager.get_enabled_agents()
|
|
238
|
+
if enabled_agents:
|
|
239
|
+
console.print("[bold]Enabled Agents:[/bold]")
|
|
240
|
+
for agent in sorted(enabled_agents):
|
|
241
|
+
console.print(f" • {agent}")
|
|
242
|
+
console.print()
|
|
243
|
+
|
|
244
|
+
# Show disabled agents
|
|
245
|
+
disabled_agents = self.profile_manager.get_disabled_agents()
|
|
246
|
+
if disabled_agents:
|
|
247
|
+
console.print("[bold]Disabled Agents:[/bold]")
|
|
248
|
+
for agent in sorted(disabled_agents):
|
|
249
|
+
console.print(f" • {agent}")
|
|
250
|
+
console.print()
|
|
251
|
+
|
|
252
|
+
# Show enabled skills
|
|
253
|
+
enabled_skills = self.profile_manager.get_enabled_skills()
|
|
254
|
+
if enabled_skills:
|
|
255
|
+
console.print("[bold]Enabled Skills:[/bold]")
|
|
256
|
+
for skill in sorted(enabled_skills):
|
|
257
|
+
console.print(f" • {skill}")
|
|
258
|
+
console.print()
|
|
259
|
+
|
|
260
|
+
# Show disabled skill patterns
|
|
261
|
+
disabled_patterns = self.profile_manager.get_disabled_skill_patterns()
|
|
262
|
+
if disabled_patterns:
|
|
263
|
+
console.print("[bold]Disabled Skill Patterns:[/bold]")
|
|
264
|
+
for pattern in disabled_patterns:
|
|
265
|
+
console.print(f" • {pattern}")
|
|
266
|
+
|
|
267
|
+
return CommandResult.success_result(
|
|
268
|
+
f"Profile '{profile_name}' details",
|
|
269
|
+
{
|
|
270
|
+
"profile": profile_name,
|
|
271
|
+
"enabled_agents": list(enabled_agents),
|
|
272
|
+
"disabled_agents": list(disabled_agents),
|
|
273
|
+
"enabled_skills": list(enabled_skills),
|
|
274
|
+
"disabled_patterns": disabled_patterns,
|
|
275
|
+
},
|
|
276
|
+
)
|
|
@@ -537,7 +537,6 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
537
537
|
toolchain = getattr(args, "toolchain", None)
|
|
538
538
|
categories = getattr(args, "categories", None)
|
|
539
539
|
force = getattr(args, "force", False)
|
|
540
|
-
all_skills = getattr(args, "all_skills", False)
|
|
541
540
|
|
|
542
541
|
if collection:
|
|
543
542
|
console.print(
|
|
@@ -548,23 +547,14 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
548
547
|
"\n[bold cyan]Deploying skills from default collection...[/bold cyan]\n"
|
|
549
548
|
)
|
|
550
549
|
|
|
551
|
-
#
|
|
552
|
-
|
|
553
|
-
console.print(
|
|
554
|
-
"[yellow]No toolchain specified. Use --toolchain to filter by language,[/yellow]"
|
|
555
|
-
)
|
|
556
|
-
console.print(
|
|
557
|
-
"[yellow]or --all-skills to deploy all available skills (not just agent-referenced).[/yellow]\n"
|
|
558
|
-
)
|
|
559
|
-
|
|
560
|
-
# Selective deployment is enabled by default (deploy only agent-referenced skills)
|
|
561
|
-
# Use --all-skills to disable selective mode
|
|
550
|
+
# Selective deployment is ALWAYS enabled (deploy only agent-referenced skills)
|
|
551
|
+
# This ensures only skills linked to deployed agents are deployed
|
|
562
552
|
result = self.skills_deployer.deploy_skills(
|
|
563
553
|
collection=collection,
|
|
564
554
|
toolchain=toolchain,
|
|
565
555
|
categories=categories,
|
|
566
556
|
force=force,
|
|
567
|
-
selective=
|
|
557
|
+
selective=True, # Always use selective deployment
|
|
568
558
|
)
|
|
569
559
|
|
|
570
560
|
# Display results
|
|
@@ -577,11 +567,7 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
577
567
|
f"(out of {total_available} available)[/cyan]"
|
|
578
568
|
)
|
|
579
569
|
console.print(
|
|
580
|
-
"[dim]Use
|
|
581
|
-
)
|
|
582
|
-
else:
|
|
583
|
-
console.print(
|
|
584
|
-
"[cyan]📦 Deploying all available skills (selective mode disabled)[/cyan]\n"
|
|
570
|
+
"[dim]Use 'claude-mpm skills configure' to manually select skills[/dim]\n"
|
|
585
571
|
)
|
|
586
572
|
|
|
587
573
|
if result["deployed_count"] > 0:
|
|
@@ -606,6 +592,16 @@ class SkillsManagementCommand(BaseCommand):
|
|
|
606
592
|
console.print(f" • {error}")
|
|
607
593
|
console.print()
|
|
608
594
|
|
|
595
|
+
# Show cleanup results
|
|
596
|
+
cleanup = result.get("cleanup", {})
|
|
597
|
+
if cleanup.get("removed_count", 0) > 0:
|
|
598
|
+
console.print(
|
|
599
|
+
f"[yellow]🧹 Removed {cleanup['removed_count']} orphaned skill(s):[/yellow]"
|
|
600
|
+
)
|
|
601
|
+
for skill in cleanup.get("removed_skills", []):
|
|
602
|
+
console.print(f" • {skill}")
|
|
603
|
+
console.print()
|
|
604
|
+
|
|
609
605
|
# Show restart instructions
|
|
610
606
|
if result["restart_instructions"]:
|
|
611
607
|
console.print(
|
claude_mpm/cli/executor.py
CHANGED
|
@@ -150,6 +150,16 @@ def execute_command(command: str, args) -> int:
|
|
|
150
150
|
result = summarize_command(args)
|
|
151
151
|
return result if result is not None else 0
|
|
152
152
|
|
|
153
|
+
# Handle profile command with lazy import
|
|
154
|
+
if command == "profile":
|
|
155
|
+
# Lazy import to avoid loading unless needed
|
|
156
|
+
from .commands.profile import ProfileCommand
|
|
157
|
+
|
|
158
|
+
cmd = ProfileCommand()
|
|
159
|
+
result = cmd.run(args)
|
|
160
|
+
# Convert CommandResult to exit code
|
|
161
|
+
return result.exit_code if result else 0
|
|
162
|
+
|
|
153
163
|
# Handle auto-configure command with lazy import
|
|
154
164
|
if command == "auto-configure":
|
|
155
165
|
# Lazy import to avoid loading unless needed
|
|
@@ -438,6 +438,13 @@ def create_parser(
|
|
|
438
438
|
except ImportError:
|
|
439
439
|
pass
|
|
440
440
|
|
|
441
|
+
try:
|
|
442
|
+
from .profile_parser import add_profile_subparser
|
|
443
|
+
|
|
444
|
+
add_profile_subparser(subparsers)
|
|
445
|
+
except ImportError:
|
|
446
|
+
pass
|
|
447
|
+
|
|
441
448
|
try:
|
|
442
449
|
from .monitor_parser import add_monitor_subparser
|
|
443
450
|
|