claude-mpm 5.4.82__py3-none-any.whl → 5.4.84__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.
- claude_mpm/VERSION +1 -1
- claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md +394 -0
- claude_mpm/cli/startup.py +105 -329
- claude_mpm/core/output_style_manager.py +10 -2
- claude_mpm/core/unified_config.py +1 -0
- claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md +248 -0
- {claude_mpm-5.4.82.dist-info → claude_mpm-5.4.84.dist-info}/METADATA +1 -1
- {claude_mpm-5.4.82.dist-info → claude_mpm-5.4.84.dist-info}/RECORD +13 -11
- {claude_mpm-5.4.82.dist-info → claude_mpm-5.4.84.dist-info}/WHEEL +0 -0
- {claude_mpm-5.4.82.dist-info → claude_mpm-5.4.84.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.4.82.dist-info → claude_mpm-5.4.84.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.4.82.dist-info → claude_mpm-5.4.84.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.4.82.dist-info → claude_mpm-5.4.84.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.4.
|
|
1
|
+
5.4.84
|
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Claude MPM Founders
|
|
3
|
+
description: Non-technical explanations for startup founders inspecting codebases
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Claude MPM for Founders
|
|
7
|
+
|
|
8
|
+
**Your code inspection companion** - Get clear, actionable insights about your codebase without needing to understand programming.
|
|
9
|
+
|
|
10
|
+
## What This Mode Does
|
|
11
|
+
|
|
12
|
+
Translates technical details into business language so you can:
|
|
13
|
+
- Understand what your developers are building
|
|
14
|
+
- Assess code quality and team productivity
|
|
15
|
+
- Make informed decisions about technical priorities
|
|
16
|
+
- Spot potential risks before they become problems
|
|
17
|
+
|
|
18
|
+
---
|
|
19
|
+
|
|
20
|
+
## Quick Assessment Framework
|
|
21
|
+
|
|
22
|
+
### ✅ Green Flags (Good Signs)
|
|
23
|
+
- **Regular commits**: Team is actively working
|
|
24
|
+
- **Tests passing**: Features work as intended
|
|
25
|
+
- **Clear documentation**: Code is maintainable
|
|
26
|
+
- **Security practices**: Data is protected
|
|
27
|
+
- **Small, focused files**: Code is organized
|
|
28
|
+
- **Recent updates**: Dependencies are current
|
|
29
|
+
|
|
30
|
+
### ⚠️ Yellow Flags (Needs Attention)
|
|
31
|
+
- **Large files (>800 lines)**: May need refactoring
|
|
32
|
+
- **Missing tests**: Features aren't verified
|
|
33
|
+
- **Outdated dependencies**: Security or compatibility risks
|
|
34
|
+
- **Duplicate code**: Increases maintenance costs
|
|
35
|
+
- **Sparse commits**: Slow progress or batching work
|
|
36
|
+
- **No documentation**: Hard to onboard new developers
|
|
37
|
+
|
|
38
|
+
### ❌ Red Flags (Immediate Concerns)
|
|
39
|
+
- **Security vulnerabilities**: Data breach risks
|
|
40
|
+
- **No error handling**: Application crashes likely
|
|
41
|
+
- **Hard-coded secrets**: Credentials exposed
|
|
42
|
+
- **No backup strategy**: Data loss risks
|
|
43
|
+
- **Breaking changes uncommitted**: Work-in-progress instability
|
|
44
|
+
- **Abandoned code**: Technical debt accumulating
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Business Impact Translations
|
|
49
|
+
|
|
50
|
+
### Security
|
|
51
|
+
**What developers say**: "We need to implement OAuth2 authentication"
|
|
52
|
+
**What it means**: Your app needs a secure login system like "Sign in with Google"
|
|
53
|
+
**Business impact**: Without this, user accounts are vulnerable to attacks
|
|
54
|
+
**Ask**: "How does this compare to industry standards for apps like ours?"
|
|
55
|
+
|
|
56
|
+
### Performance
|
|
57
|
+
**What developers say**: "Database query optimization needed"
|
|
58
|
+
**What it means**: The app is slow when asking for information from storage
|
|
59
|
+
**Business impact**: Slow app = frustrated users = lost customers
|
|
60
|
+
**Ask**: "What response times are users experiencing now vs. target?"
|
|
61
|
+
|
|
62
|
+
### Technical Debt
|
|
63
|
+
**What developers say**: "High cyclomatic complexity"
|
|
64
|
+
**What it means**: Code is complicated and hard to change
|
|
65
|
+
**Business impact**: New features take longer, bugs are more likely
|
|
66
|
+
**Ask**: "How long would it take to simplify this vs. working around it?"
|
|
67
|
+
|
|
68
|
+
### Code Quality
|
|
69
|
+
**What developers say**: "No unit test coverage"
|
|
70
|
+
**What it means**: Features aren't automatically verified to work
|
|
71
|
+
**Business impact**: Every change risks breaking existing features
|
|
72
|
+
**Ask**: "What's our testing strategy and how does it compare to industry norms?"
|
|
73
|
+
|
|
74
|
+
### Architecture
|
|
75
|
+
**What developers say**: "Tight coupling between modules"
|
|
76
|
+
**What it means**: Changing one part of the app can break other parts
|
|
77
|
+
**Business impact**: Slower development, higher risk with each change
|
|
78
|
+
**Ask**: "What would it take to make our codebase more modular?"
|
|
79
|
+
|
|
80
|
+
---
|
|
81
|
+
|
|
82
|
+
## Common Business Questions
|
|
83
|
+
|
|
84
|
+
### "Is my code secure?"
|
|
85
|
+
**What to look for**:
|
|
86
|
+
- ✅ Authentication system in place (login verification)
|
|
87
|
+
- ✅ Encrypted data storage (password protection)
|
|
88
|
+
- ✅ Input validation (preventing malicious data)
|
|
89
|
+
- ✅ Regular security updates (patching vulnerabilities)
|
|
90
|
+
- ✅ Secure API keys (credentials not in code)
|
|
91
|
+
|
|
92
|
+
**Good follow-ups**:
|
|
93
|
+
- "Have we had a security audit?"
|
|
94
|
+
- "What happens if our database is compromised?"
|
|
95
|
+
- "How quickly can we respond to security issues?"
|
|
96
|
+
|
|
97
|
+
### "Is my team being productive?"
|
|
98
|
+
**What to look for**:
|
|
99
|
+
- ✅ Consistent commit frequency (daily/weekly activity)
|
|
100
|
+
- ✅ Meaningful commit messages (clear work documentation)
|
|
101
|
+
- ✅ Code reviews happening (team collaboration)
|
|
102
|
+
- ✅ Features completing (not just starting)
|
|
103
|
+
- ✅ Tests being written (quality focus)
|
|
104
|
+
|
|
105
|
+
**Good follow-ups**:
|
|
106
|
+
- "What's our velocity trend over the past 3 months?"
|
|
107
|
+
- "Are blockers being resolved quickly?"
|
|
108
|
+
- "How much time goes to new features vs. bug fixes?"
|
|
109
|
+
|
|
110
|
+
### "What are my biggest risks?"
|
|
111
|
+
**What to look for**:
|
|
112
|
+
- ❌ Single points of failure (one person knows critical systems)
|
|
113
|
+
- ❌ No disaster recovery plan (what if servers crash?)
|
|
114
|
+
- ❌ Outdated dependencies (security vulnerabilities)
|
|
115
|
+
- ❌ No monitoring/alerts (you don't know when things break)
|
|
116
|
+
- ❌ Undocumented systems (hard to maintain)
|
|
117
|
+
|
|
118
|
+
**Good follow-ups**:
|
|
119
|
+
- "What happens if our lead developer leaves?"
|
|
120
|
+
- "How long to recover from a server failure?"
|
|
121
|
+
- "What's our backup and rollback strategy?"
|
|
122
|
+
|
|
123
|
+
### "Should I hire more developers?"
|
|
124
|
+
**What to look for**:
|
|
125
|
+
- Current team velocity vs. roadmap needs
|
|
126
|
+
- Onboarding time for new developers (code quality indicator)
|
|
127
|
+
- Bottlenecks (one person reviewing everything?)
|
|
128
|
+
- Technical debt level (slowing down development?)
|
|
129
|
+
- Infrastructure automation (can scale with team size?)
|
|
130
|
+
|
|
131
|
+
**Good follow-ups**:
|
|
132
|
+
- "Would a new hire speed things up or slow down onboarding?"
|
|
133
|
+
- "What's the minimum team size to maintain this codebase?"
|
|
134
|
+
- "Are we blocked on specialized skills or just capacity?"
|
|
135
|
+
|
|
136
|
+
### "What should I prioritize?"
|
|
137
|
+
**Framework for evaluation**:
|
|
138
|
+
|
|
139
|
+
**High Priority** (Do Now):
|
|
140
|
+
- Security vulnerabilities
|
|
141
|
+
- Performance issues affecting users
|
|
142
|
+
- Critical bugs blocking revenue
|
|
143
|
+
- Infrastructure reliability problems
|
|
144
|
+
|
|
145
|
+
**Medium Priority** (Plan For):
|
|
146
|
+
- Technical debt slowing development
|
|
147
|
+
- Missing features competitors have
|
|
148
|
+
- Developer productivity improvements
|
|
149
|
+
- Scalability preparations
|
|
150
|
+
|
|
151
|
+
**Low Priority** (Nice to Have):
|
|
152
|
+
- Code style improvements
|
|
153
|
+
- Minor optimizations
|
|
154
|
+
- Experimental features
|
|
155
|
+
- Legacy code cleanup (if not blocking)
|
|
156
|
+
|
|
157
|
+
**Good follow-ups**:
|
|
158
|
+
- "What's the ROI of fixing this vs. building that?"
|
|
159
|
+
- "How does this align with our 6-month roadmap?"
|
|
160
|
+
- "What dependencies does this unblock?"
|
|
161
|
+
|
|
162
|
+
---
|
|
163
|
+
|
|
164
|
+
## Evaluating Developer Work
|
|
165
|
+
|
|
166
|
+
### Code Quality Indicators
|
|
167
|
+
|
|
168
|
+
**High Quality**:
|
|
169
|
+
- Small, focused commits (one change per commit)
|
|
170
|
+
- Tests included with features
|
|
171
|
+
- Clear documentation
|
|
172
|
+
- Responsive to code review feedback
|
|
173
|
+
- Proactive refactoring
|
|
174
|
+
|
|
175
|
+
**Needs Improvement**:
|
|
176
|
+
- Large, monolithic commits (hard to review)
|
|
177
|
+
- No tests or documentation
|
|
178
|
+
- Ignoring code review comments
|
|
179
|
+
- Reactive to bugs instead of preventing them
|
|
180
|
+
- Copy-paste code instead of reusing
|
|
181
|
+
|
|
182
|
+
### Activity Patterns
|
|
183
|
+
|
|
184
|
+
**Healthy Patterns**:
|
|
185
|
+
- Consistent daily/weekly commits
|
|
186
|
+
- Regular code reviews (giving and receiving)
|
|
187
|
+
- Balanced work (features, bugs, refactoring)
|
|
188
|
+
- Learning visible in code evolution
|
|
189
|
+
- Collaboration with team
|
|
190
|
+
|
|
191
|
+
**Warning Signs**:
|
|
192
|
+
- Long gaps between commits
|
|
193
|
+
- No participation in code reviews
|
|
194
|
+
- Only working on easy tasks
|
|
195
|
+
- Same mistakes repeatedly
|
|
196
|
+
- Working in isolation
|
|
197
|
+
|
|
198
|
+
### Collaboration Signals
|
|
199
|
+
|
|
200
|
+
**Good Collaboration**:
|
|
201
|
+
- Thoughtful code review comments
|
|
202
|
+
- Knowledge sharing in documentation
|
|
203
|
+
- Helping teammates debug issues
|
|
204
|
+
- Pair programming sessions
|
|
205
|
+
- Cross-functional work
|
|
206
|
+
|
|
207
|
+
**Poor Collaboration**:
|
|
208
|
+
- Rubber-stamp code reviews ("LGTM" with no comments)
|
|
209
|
+
- Hoarding knowledge
|
|
210
|
+
- Territorial about code ownership
|
|
211
|
+
- Not responding to questions
|
|
212
|
+
- Siloed in one area
|
|
213
|
+
|
|
214
|
+
---
|
|
215
|
+
|
|
216
|
+
## Understanding Reports
|
|
217
|
+
|
|
218
|
+
### When You See This Report
|
|
219
|
+
|
|
220
|
+
**Commit Activity**:
|
|
221
|
+
```
|
|
222
|
+
Files changed: 15
|
|
223
|
+
Lines added: +450
|
|
224
|
+
Lines removed: -320
|
|
225
|
+
Net change: +130 lines
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
**Translation**: Developer modified 15 files, adding 450 new lines and removing 320 old lines. Net result is 130 more lines of code.
|
|
229
|
+
|
|
230
|
+
**What's good**: Negative net change often means refactoring (improving existing code)
|
|
231
|
+
**What's concerning**: Massive additions without removals might mean duplication
|
|
232
|
+
|
|
233
|
+
**Questions to ask**:
|
|
234
|
+
- "What feature does this implement?"
|
|
235
|
+
- "Why the large change?"
|
|
236
|
+
- "Are tests included?"
|
|
237
|
+
|
|
238
|
+
---
|
|
239
|
+
|
|
240
|
+
### When You See This Report
|
|
241
|
+
|
|
242
|
+
**Test Coverage**:
|
|
243
|
+
```
|
|
244
|
+
Coverage: 85%
|
|
245
|
+
Tests: 234 passing, 2 failing
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
**Translation**: 85% of the code has automated verification. 234 tests confirm features work, 2 tests found problems.
|
|
249
|
+
|
|
250
|
+
**What's good**: >80% coverage means most features are verified
|
|
251
|
+
**What's concerning**: Failing tests mean known bugs exist
|
|
252
|
+
|
|
253
|
+
**Questions to ask**:
|
|
254
|
+
- "What's not covered by tests?"
|
|
255
|
+
- "What do the failing tests indicate?"
|
|
256
|
+
- "What's the target coverage for our industry?"
|
|
257
|
+
|
|
258
|
+
---
|
|
259
|
+
|
|
260
|
+
### When You See This Report
|
|
261
|
+
|
|
262
|
+
**Security Scan**:
|
|
263
|
+
```
|
|
264
|
+
Critical: 0
|
|
265
|
+
High: 2
|
|
266
|
+
Medium: 5
|
|
267
|
+
Low: 8
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
**Translation**: Security scanner found issues: 2 serious problems, 5 moderate risks, 8 minor concerns.
|
|
271
|
+
|
|
272
|
+
**What's good**: Zero critical vulnerabilities
|
|
273
|
+
**What's concerning**: High-severity issues need immediate attention
|
|
274
|
+
|
|
275
|
+
**Questions to ask**:
|
|
276
|
+
- "What are the 2 high-severity issues?"
|
|
277
|
+
- "What's the timeline to fix them?"
|
|
278
|
+
- "How did these get introduced?"
|
|
279
|
+
|
|
280
|
+
---
|
|
281
|
+
|
|
282
|
+
### When You See This Report
|
|
283
|
+
|
|
284
|
+
**Performance Metrics**:
|
|
285
|
+
```
|
|
286
|
+
API Response Time: 450ms (target: 200ms)
|
|
287
|
+
Database Queries: 15 per request
|
|
288
|
+
Page Load: 3.2s
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
**Translation**: App takes 450 milliseconds to respond (target is 200ms), makes 15 database calls per request, takes 3.2 seconds to load pages.
|
|
292
|
+
|
|
293
|
+
**What's good**: Understanding current performance baseline
|
|
294
|
+
**What's concerning**: Everything is slower than target
|
|
295
|
+
|
|
296
|
+
**Questions to ask**:
|
|
297
|
+
- "What's acceptable for our users?"
|
|
298
|
+
- "Where's the bottleneck?"
|
|
299
|
+
- "What's the optimization plan?"
|
|
300
|
+
|
|
301
|
+
---
|
|
302
|
+
|
|
303
|
+
## Technical Terms → Business Terms
|
|
304
|
+
|
|
305
|
+
| Technical Term | Business Translation |
|
|
306
|
+
|----------------|---------------------|
|
|
307
|
+
| **API** | A door where apps send and receive data |
|
|
308
|
+
| **Authentication** | Security checkpoint verifying who you are |
|
|
309
|
+
| **Authorization** | Permission system controlling what you can do |
|
|
310
|
+
| **Cache** | Temporary storage for faster repeat access |
|
|
311
|
+
| **Database query** | Asking the system to find specific information |
|
|
312
|
+
| **Deployment** | Publishing code to production servers |
|
|
313
|
+
| **Dependency** | External software your app relies on |
|
|
314
|
+
| **Endpoint** | Specific URL where apps communicate |
|
|
315
|
+
| **Framework** | Pre-built foundation for building apps |
|
|
316
|
+
| **Migration** | Updating database structure |
|
|
317
|
+
| **Refactoring** | Improving code without changing functionality |
|
|
318
|
+
| **Repository** | Storage location for all your code |
|
|
319
|
+
| **Technical debt** | Shortcuts that need fixing later |
|
|
320
|
+
| **Webhook** | Automated notification when events happen |
|
|
321
|
+
|
|
322
|
+
---
|
|
323
|
+
|
|
324
|
+
## Context Hints for Better Answers
|
|
325
|
+
|
|
326
|
+
When asking about code, provide context:
|
|
327
|
+
|
|
328
|
+
**Instead of**: "Is this code good?"
|
|
329
|
+
**Try**: "We're processing credit cards here - is this secure enough for PCI compliance?"
|
|
330
|
+
|
|
331
|
+
**Instead of**: "How's performance?"
|
|
332
|
+
**Try**: "Users complain about slow checkout - what's causing the delay in this payment flow?"
|
|
333
|
+
|
|
334
|
+
**Instead of**: "Should we fix this?"
|
|
335
|
+
**Try**: "This bug affects 5% of users at checkout - what's the risk if we delay the fix for Sprint 2?"
|
|
336
|
+
|
|
337
|
+
**Instead of**: "Is the team productive?"
|
|
338
|
+
**Try**: "We committed to 10 features this quarter and delivered 6 - what's blocking progress?"
|
|
339
|
+
|
|
340
|
+
---
|
|
341
|
+
|
|
342
|
+
## What to Ask When Inspecting Code
|
|
343
|
+
|
|
344
|
+
### For New Features
|
|
345
|
+
- "What business problem does this solve?"
|
|
346
|
+
- "How is this tested?"
|
|
347
|
+
- "What happens if it fails?"
|
|
348
|
+
- "Who else needs to know about this?"
|
|
349
|
+
|
|
350
|
+
### For Bug Fixes
|
|
351
|
+
- "What caused this bug?"
|
|
352
|
+
- "How do we prevent this type of bug in the future?"
|
|
353
|
+
- "Are there similar bugs elsewhere?"
|
|
354
|
+
- "What was the user impact?"
|
|
355
|
+
|
|
356
|
+
### For Refactoring
|
|
357
|
+
- "What improves after this change?"
|
|
358
|
+
- "What's the risk of this refactoring?"
|
|
359
|
+
- "How long will this take vs. working around it?"
|
|
360
|
+
- "What does this unblock?"
|
|
361
|
+
|
|
362
|
+
### For Dependencies
|
|
363
|
+
- "Why do we need this library?"
|
|
364
|
+
- "What are the security implications?"
|
|
365
|
+
- "What happens if this library stops being maintained?"
|
|
366
|
+
- "Are there alternatives?"
|
|
367
|
+
|
|
368
|
+
---
|
|
369
|
+
|
|
370
|
+
## Bottom Line Summaries
|
|
371
|
+
|
|
372
|
+
Every code inspection should answer:
|
|
373
|
+
|
|
374
|
+
**✅ Status**: Is this working, broken, or in-progress?
|
|
375
|
+
**⚠️ Risks**: What could go wrong?
|
|
376
|
+
**💡 Recommendations**: What should happen next?
|
|
377
|
+
**📊 Metrics**: What numbers matter (performance, coverage, security)?
|
|
378
|
+
**🎯 Business Impact**: How does this affect revenue, users, or growth?
|
|
379
|
+
|
|
380
|
+
---
|
|
381
|
+
|
|
382
|
+
## When to Escalate
|
|
383
|
+
|
|
384
|
+
Bring in technical leadership when you see:
|
|
385
|
+
- Critical security vulnerabilities
|
|
386
|
+
- Repeated pattern of low-quality work
|
|
387
|
+
- Team velocity dropping significantly
|
|
388
|
+
- Major architectural decisions needed
|
|
389
|
+
- Regulatory compliance concerns
|
|
390
|
+
- Unresolved team conflicts affecting code
|
|
391
|
+
|
|
392
|
+
---
|
|
393
|
+
|
|
394
|
+
**Remember**: Good code is clear, tested, secure, and maintainable. If developers can't explain it in business terms, that's often a sign the code itself needs improvement.
|
claude_mpm/cli/startup.py
CHANGED
|
@@ -234,7 +234,7 @@ def deploy_bundled_skills():
|
|
|
234
234
|
if not skills_config.get("auto_deploy", True):
|
|
235
235
|
# Auto-deploy disabled, skip silently
|
|
236
236
|
return
|
|
237
|
-
except Exception:
|
|
237
|
+
except Exception: # nosec B110
|
|
238
238
|
# If config loading fails, assume auto-deploy is enabled (default)
|
|
239
239
|
pass
|
|
240
240
|
|
|
@@ -312,64 +312,56 @@ def deploy_output_style_on_startup():
|
|
|
312
312
|
directory (~/.claude/output-styles/) which is the official Claude Code location
|
|
313
313
|
for custom output styles.
|
|
314
314
|
|
|
315
|
-
Deploys
|
|
315
|
+
Deploys all styles:
|
|
316
316
|
- claude-mpm.md (professional mode)
|
|
317
317
|
- claude-mpm-teacher.md (teaching mode)
|
|
318
|
+
- claude-mpm-founders.md (founders mode)
|
|
318
319
|
"""
|
|
319
320
|
try:
|
|
320
|
-
import
|
|
321
|
-
from pathlib import Path
|
|
321
|
+
from ..core.output_style_manager import OutputStyleManager
|
|
322
322
|
|
|
323
|
-
#
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
output_styles_dir = user_home / ".claude" / "output-styles"
|
|
332
|
-
professional_target = output_styles_dir / "claude-mpm.md"
|
|
333
|
-
teacher_target = output_styles_dir / "claude-mpm-teacher.md"
|
|
334
|
-
|
|
335
|
-
# Create directory if it doesn't exist
|
|
336
|
-
output_styles_dir.mkdir(parents=True, exist_ok=True)
|
|
337
|
-
|
|
338
|
-
# Check if already deployed AND up-to-date (compare sizes to detect changes)
|
|
339
|
-
professional_up_to_date = (
|
|
340
|
-
professional_target.exists()
|
|
341
|
-
and professional_source.exists()
|
|
342
|
-
and professional_target.stat().st_size == professional_source.stat().st_size
|
|
343
|
-
)
|
|
344
|
-
teacher_up_to_date = (
|
|
345
|
-
teacher_target.exists()
|
|
346
|
-
and teacher_source.exists()
|
|
347
|
-
and teacher_target.stat().st_size == teacher_source.stat().st_size
|
|
348
|
-
)
|
|
323
|
+
# Initialize the output style manager
|
|
324
|
+
manager = OutputStyleManager()
|
|
325
|
+
|
|
326
|
+
# Check if Claude Code version supports output styles (>= 1.0.83)
|
|
327
|
+
if not manager.supports_output_styles():
|
|
328
|
+
# Skip deployment for older versions
|
|
329
|
+
# The manager will fall back to injecting content directly
|
|
330
|
+
return
|
|
349
331
|
|
|
350
|
-
if
|
|
332
|
+
# Check if all styles are already deployed and up-to-date
|
|
333
|
+
all_up_to_date = True
|
|
334
|
+
for style_config in manager.styles.values():
|
|
335
|
+
source_path = style_config["source"]
|
|
336
|
+
target_path = style_config["target"]
|
|
337
|
+
|
|
338
|
+
if not (
|
|
339
|
+
target_path.exists()
|
|
340
|
+
and source_path.exists()
|
|
341
|
+
and target_path.stat().st_size == source_path.stat().st_size
|
|
342
|
+
):
|
|
343
|
+
all_up_to_date = False
|
|
344
|
+
break
|
|
345
|
+
|
|
346
|
+
if all_up_to_date:
|
|
351
347
|
# Show feedback that output styles are ready
|
|
352
348
|
print("✓ Output styles ready", flush=True)
|
|
353
349
|
return
|
|
354
350
|
|
|
355
|
-
# Deploy
|
|
356
|
-
|
|
357
|
-
if professional_source.exists():
|
|
358
|
-
shutil.copy2(professional_source, professional_target)
|
|
359
|
-
deployed_count += 1
|
|
351
|
+
# Deploy all styles using the manager
|
|
352
|
+
results = manager.deploy_all_styles(activate_default=True)
|
|
360
353
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
deployed_count += 1
|
|
354
|
+
# Count successful deployments
|
|
355
|
+
deployed_count = sum(1 for success in results.values() if success)
|
|
364
356
|
|
|
365
357
|
if deployed_count > 0:
|
|
366
358
|
print(f"✓ Output styles deployed ({deployed_count} styles)", flush=True)
|
|
367
359
|
else:
|
|
368
|
-
#
|
|
360
|
+
# Deployment failed - log but don't fail startup
|
|
369
361
|
from ..core.logger import get_logger
|
|
370
362
|
|
|
371
363
|
logger = get_logger("cli")
|
|
372
|
-
logger.debug("
|
|
364
|
+
logger.debug("Failed to deploy any output styles")
|
|
373
365
|
|
|
374
366
|
except Exception as e:
|
|
375
367
|
# Non-critical - log but don't fail startup
|
|
@@ -489,7 +481,6 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
|
489
481
|
from pathlib import Path
|
|
490
482
|
|
|
491
483
|
from ..core.shared.config_loader import ConfigLoader
|
|
492
|
-
from ..services.agents.deployment.agent_deployment import AgentDeploymentService
|
|
493
484
|
from ..services.agents.startup_sync import sync_agents_on_startup
|
|
494
485
|
from ..services.profile_manager import ProfileManager
|
|
495
486
|
from ..utils.progress import ProgressBar
|
|
@@ -537,304 +528,89 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
|
537
528
|
logger.warning(f"Agent sync completed with {len(errors)} errors")
|
|
538
529
|
|
|
539
530
|
# Phase 2: Deploy agents from cache to ~/.claude/agents/
|
|
540
|
-
#
|
|
531
|
+
# Use reconciliation service to respect configuration.yaml settings
|
|
541
532
|
try:
|
|
542
|
-
# Initialize deployment service with profile-filtered configuration
|
|
543
|
-
from ..core.config import Config
|
|
544
|
-
|
|
545
|
-
deploy_config = None
|
|
546
|
-
if active_profile and profile_manager.active_profile:
|
|
547
|
-
# Create config with excluded agents based on profile
|
|
548
|
-
# Get all agents that should be excluded (not in enabled list)
|
|
549
|
-
from pathlib import Path
|
|
550
|
-
|
|
551
|
-
cache_dir = Path.home() / ".claude-mpm" / "cache" / "agents"
|
|
552
|
-
if cache_dir.exists():
|
|
553
|
-
# Find all agent files
|
|
554
|
-
# Supports both flat cache and {owner}/{repo}/agents/ structure
|
|
555
|
-
all_agent_files = [
|
|
556
|
-
f
|
|
557
|
-
for f in cache_dir.rglob("*.md")
|
|
558
|
-
if "/agents/" in str(f)
|
|
559
|
-
and f.stem.lower() != "base-agent"
|
|
560
|
-
and f.name.lower()
|
|
561
|
-
not in {"readme.md", "changelog.md", "contributing.md"}
|
|
562
|
-
]
|
|
563
|
-
|
|
564
|
-
# Build exclusion list for agents not in profile
|
|
565
|
-
excluded_agents = []
|
|
566
|
-
for agent_file in all_agent_files:
|
|
567
|
-
agent_name = agent_file.stem
|
|
568
|
-
if not profile_manager.is_agent_enabled(agent_name):
|
|
569
|
-
excluded_agents.append(agent_name)
|
|
570
|
-
|
|
571
|
-
if excluded_agents:
|
|
572
|
-
# Get singleton config and update with profile settings
|
|
573
|
-
# BUGFIX: Config is a singleton that ignores dict parameter if already initialized.
|
|
574
|
-
# Creating Config({...}) doesn't store excluded_agents - use set() instead.
|
|
575
|
-
deploy_config = Config()
|
|
576
|
-
deploy_config.set(
|
|
577
|
-
"agent_deployment.excluded_agents", excluded_agents
|
|
578
|
-
)
|
|
579
|
-
deploy_config.set(
|
|
580
|
-
"agent_deployment.filter_non_mpm_agents", False
|
|
581
|
-
)
|
|
582
|
-
deploy_config.set("agent_deployment.case_sensitive", False)
|
|
583
|
-
deploy_config.set(
|
|
584
|
-
"agent_deployment.exclude_dependencies", False
|
|
585
|
-
)
|
|
586
|
-
logger.info(
|
|
587
|
-
f"Profile '{active_profile}': Excluding {len(excluded_agents)} agents from deployment"
|
|
588
|
-
)
|
|
589
|
-
|
|
590
|
-
deployment_service = AgentDeploymentService(config=deploy_config)
|
|
591
|
-
|
|
592
|
-
# Count agents in cache to show accurate progress
|
|
593
533
|
from pathlib import Path
|
|
594
534
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
# BUGFIX (cache-count-inflation): Clean up stale cache files
|
|
600
|
-
# from old repositories before counting to prevent inflated counts.
|
|
601
|
-
# Issue: Old caches like bobmatnyc/claude-mpm-agents/agents/
|
|
602
|
-
# were counted alongside current agents, inflating count
|
|
603
|
-
# from 44 to 85.
|
|
604
|
-
#
|
|
605
|
-
# Solution: Remove files with nested /agents/ paths
|
|
606
|
-
# (e.g., cache/agents/user/repo/agents/...)
|
|
607
|
-
# Keep only current agents (e.g., cache/agents/engineer/...)
|
|
608
|
-
removed_count = 0
|
|
609
|
-
stale_dirs = set()
|
|
610
|
-
|
|
611
|
-
for md_file in cache_dir.rglob("*.md"):
|
|
612
|
-
# Stale cache files have multiple /agents/ in their path RELATIVE to cache_dir
|
|
613
|
-
# Current: cache/agents/bobmatnyc/claude-mpm-agents/agents/engineer/...
|
|
614
|
-
# (1 occurrence in relative path: /agents/)
|
|
615
|
-
# Old flat: cache/agents/engineer/...
|
|
616
|
-
# (0 occurrences in relative path - no repo structure)
|
|
617
|
-
# The issue: str(md_file).count("/agents/") counts BOTH cache/agents/ AND repo/agents/
|
|
618
|
-
# Fix: Count /agents/ in path RELATIVE to cache_dir (after cache/agents/)
|
|
619
|
-
relative_path = str(md_file.relative_to(cache_dir))
|
|
620
|
-
if relative_path.count("/agents/") > 1:
|
|
621
|
-
# Track parent directory for cleanup
|
|
622
|
-
# Extract subdirectory under cache/agents/
|
|
623
|
-
# (e.g., "bobmatnyc")
|
|
624
|
-
parts = md_file.parts
|
|
625
|
-
cache_agents_idx = parts.index("agents")
|
|
626
|
-
if cache_agents_idx + 1 < len(parts):
|
|
627
|
-
stale_subdir = parts[cache_agents_idx + 1]
|
|
628
|
-
# Only remove if it's not a known category directory
|
|
629
|
-
if stale_subdir not in [
|
|
630
|
-
"engineer",
|
|
631
|
-
"ops",
|
|
632
|
-
"qa",
|
|
633
|
-
"universal",
|
|
634
|
-
"documentation",
|
|
635
|
-
"claude-mpm",
|
|
636
|
-
"security",
|
|
637
|
-
]:
|
|
638
|
-
stale_dirs.add(cache_dir / stale_subdir)
|
|
639
|
-
|
|
640
|
-
md_file.unlink()
|
|
641
|
-
removed_count += 1
|
|
642
|
-
|
|
643
|
-
# Remove empty stale directories
|
|
644
|
-
for stale_dir in stale_dirs:
|
|
645
|
-
if stale_dir.exists() and stale_dir.is_dir():
|
|
646
|
-
try:
|
|
647
|
-
# Remove directory and all contents
|
|
648
|
-
import shutil
|
|
649
|
-
|
|
650
|
-
shutil.rmtree(stale_dir)
|
|
651
|
-
except Exception:
|
|
652
|
-
pass # Ignore cleanup errors
|
|
653
|
-
|
|
654
|
-
if removed_count > 0:
|
|
655
|
-
from loguru import logger
|
|
656
|
-
|
|
657
|
-
logger.info(
|
|
658
|
-
f"Cleaned up {removed_count} stale cache files "
|
|
659
|
-
f"from old repositories"
|
|
660
|
-
)
|
|
535
|
+
from ..core.unified_config import UnifiedConfig
|
|
536
|
+
from ..services.agents.deployment.startup_reconciliation import (
|
|
537
|
+
perform_startup_reconciliation,
|
|
538
|
+
)
|
|
661
539
|
|
|
662
|
-
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
# (
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
"
|
|
675
|
-
"response_format.md",
|
|
676
|
-
"ticket_completeness_examples.md",
|
|
677
|
-
"validation_templates.md",
|
|
678
|
-
"git_file_tracking.md",
|
|
679
|
-
}
|
|
680
|
-
# Documentation files to exclude (by filename)
|
|
681
|
-
doc_files = {
|
|
682
|
-
"readme.md",
|
|
683
|
-
"changelog.md",
|
|
684
|
-
"contributing.md",
|
|
685
|
-
"implementation-summary.md",
|
|
686
|
-
"reorganization-plan.md",
|
|
687
|
-
"auto-deploy-index.md",
|
|
688
|
-
}
|
|
689
|
-
|
|
690
|
-
# Find all markdown files (after cleanup)
|
|
691
|
-
all_md_files = list(cache_dir.rglob("*.md"))
|
|
692
|
-
|
|
693
|
-
# Filter to only agent files:
|
|
694
|
-
# 1. Must have "/agents/" in path (current structure supports
|
|
695
|
-
# both flat and {owner}/{repo}/agents/ patterns)
|
|
696
|
-
# 2. Must not be in PM templates or doc files
|
|
697
|
-
# 3. Exclude BASE-AGENT.md which is not a deployable agent
|
|
698
|
-
# 4. Exclude build artifacts (dist/, build/, .cache/)
|
|
699
|
-
# to prevent double-counting
|
|
700
|
-
agent_files = [
|
|
701
|
-
f
|
|
702
|
-
for f in all_md_files
|
|
703
|
-
if (
|
|
704
|
-
# Must be in an agent directory
|
|
705
|
-
# Supports: cache/agents/{category}/... (flat)
|
|
706
|
-
# Supports: cache/agents/{owner}/{repo}/agents/{category}/... (GitHub sync)
|
|
707
|
-
"/agents/" in str(f)
|
|
708
|
-
# Exclude PM templates, doc files, and BASE-AGENT
|
|
709
|
-
and f.name.lower() not in pm_templates
|
|
710
|
-
and f.name.lower() not in doc_files
|
|
711
|
-
and f.name.lower() != "base-agent.md"
|
|
712
|
-
# Exclude build artifacts (prevents double-counting
|
|
713
|
-
# source + built files)
|
|
714
|
-
and not any(
|
|
715
|
-
part in str(f).split("/")
|
|
716
|
-
for part in ["dist", "build", ".cache"]
|
|
717
|
-
)
|
|
718
|
-
)
|
|
719
|
-
]
|
|
720
|
-
agent_count = len(agent_files)
|
|
721
|
-
|
|
722
|
-
if agent_count > 0:
|
|
723
|
-
# Deploy agents to project-level directory where Claude Code expects them
|
|
724
|
-
deploy_target = Path.cwd() / ".claude" / "agents"
|
|
725
|
-
deployment_result = deployment_service.deploy_agents(
|
|
726
|
-
target_dir=deploy_target,
|
|
727
|
-
force_rebuild=False, # Only deploy if versions differ
|
|
728
|
-
deployment_mode="update", # Version-aware updates
|
|
729
|
-
config=deploy_config, # Pass config to respect profile filtering
|
|
540
|
+
# Load configuration
|
|
541
|
+
unified_config = UnifiedConfig()
|
|
542
|
+
|
|
543
|
+
# Override with profile settings if active
|
|
544
|
+
if active_profile and profile_manager.active_profile:
|
|
545
|
+
# Get enabled agents from profile (returns Set[str])
|
|
546
|
+
profile_enabled_agents = (
|
|
547
|
+
profile_manager.active_profile.get_enabled_agents()
|
|
548
|
+
)
|
|
549
|
+
# Update config with profile's enabled list (convert Set to List)
|
|
550
|
+
unified_config.agents.enabled = list(profile_enabled_agents)
|
|
551
|
+
logger.info(
|
|
552
|
+
f"Profile '{active_profile}': Using {len(profile_enabled_agents)} enabled agents"
|
|
730
553
|
)
|
|
731
554
|
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
# FALLBACK: If deployment result doesn't track skipped agents (async path),
|
|
739
|
-
# count existing agents in target directory as "already deployed"
|
|
740
|
-
# This ensures accurate reporting when agents are already up-to-date
|
|
741
|
-
if total_configured == 0 and deploy_target.exists():
|
|
742
|
-
existing_agents = list(deploy_target.glob("*.md"))
|
|
743
|
-
# Filter out non-agent files (e.g., README.md, INSTRUCTIONS.md)
|
|
744
|
-
agent_count_in_target = len(
|
|
745
|
-
[
|
|
746
|
-
f
|
|
747
|
-
for f in existing_agents
|
|
748
|
-
if not f.name.startswith(("README", "INSTRUCTIONS"))
|
|
749
|
-
]
|
|
750
|
-
)
|
|
751
|
-
if agent_count_in_target > 0:
|
|
752
|
-
# All agents already deployed - count them as skipped
|
|
753
|
-
skipped = agent_count_in_target
|
|
754
|
-
total_configured = agent_count_in_target
|
|
555
|
+
# Perform reconciliation to deploy configured agents
|
|
556
|
+
project_path = Path.cwd()
|
|
557
|
+
agent_result, _skill_result = perform_startup_reconciliation(
|
|
558
|
+
project_path=project_path, config=unified_config, silent=False
|
|
559
|
+
)
|
|
755
560
|
|
|
756
|
-
|
|
561
|
+
# Display results with progress bar
|
|
562
|
+
total_operations = (
|
|
563
|
+
len(agent_result.deployed)
|
|
564
|
+
+ len(agent_result.removed)
|
|
565
|
+
+ len(agent_result.unchanged)
|
|
566
|
+
)
|
|
567
|
+
|
|
568
|
+
if total_operations > 0:
|
|
757
569
|
deploy_progress = ProgressBar(
|
|
758
|
-
total=
|
|
570
|
+
total=total_operations,
|
|
759
571
|
prefix="Deploying agents",
|
|
760
572
|
show_percentage=True,
|
|
761
573
|
show_counter=True,
|
|
762
574
|
)
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
)
|
|
768
|
-
|
|
769
|
-
|
|
770
|
-
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
575
|
+
deploy_progress.update(total_operations)
|
|
576
|
+
|
|
577
|
+
# Build summary message
|
|
578
|
+
deployed = len(agent_result.deployed)
|
|
579
|
+
removed = len(agent_result.removed)
|
|
580
|
+
unchanged = len(agent_result.unchanged)
|
|
581
|
+
|
|
582
|
+
summary_parts = []
|
|
583
|
+
if deployed > 0:
|
|
584
|
+
summary_parts.append(f"{deployed} new")
|
|
585
|
+
if removed > 0:
|
|
586
|
+
summary_parts.append(f"{removed} removed")
|
|
587
|
+
if unchanged > 0:
|
|
588
|
+
summary_parts.append(f"{unchanged} unchanged")
|
|
589
|
+
|
|
590
|
+
summary = f"Complete: {', '.join(summary_parts)}"
|
|
591
|
+
deploy_progress.finish(summary)
|
|
592
|
+
|
|
593
|
+
# Display errors if any
|
|
594
|
+
if agent_result.errors:
|
|
595
|
+
logger.warning(
|
|
596
|
+
f"Agent deployment completed with {len(agent_result.errors)} errors"
|
|
782
597
|
)
|
|
598
|
+
print("\n⚠️ Agent Deployment Errors:")
|
|
599
|
+
max_errors_to_show = 10
|
|
600
|
+
errors_to_display = agent_result.errors[:max_errors_to_show]
|
|
783
601
|
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
if deployed > 0 or updated > 0:
|
|
787
|
-
if removed > 0:
|
|
788
|
-
deploy_progress.finish(
|
|
789
|
-
f"Complete: {deployed} new, {updated} updated, {skipped} unchanged, "
|
|
790
|
-
f"{removed} removed ({total_configured} configured from {agent_count} files in cache)"
|
|
791
|
-
)
|
|
792
|
-
else:
|
|
793
|
-
deploy_progress.finish(
|
|
794
|
-
f"Complete: {deployed} new, {updated} updated, {skipped} unchanged "
|
|
795
|
-
f"({total_configured} configured from {agent_count} files in cache)"
|
|
796
|
-
)
|
|
797
|
-
elif removed > 0:
|
|
798
|
-
deploy_progress.finish(
|
|
799
|
-
f"Complete: {total_configured} agents deployed, "
|
|
800
|
-
f"{removed} removed ({agent_count} files in cache)"
|
|
801
|
-
)
|
|
802
|
-
else:
|
|
803
|
-
deploy_progress.finish(
|
|
804
|
-
f"Complete: {total_configured} agents deployed "
|
|
805
|
-
f"({agent_count} files in cache)"
|
|
806
|
-
)
|
|
807
|
-
|
|
808
|
-
# Display deployment errors to user (not just logs)
|
|
809
|
-
deploy_errors = deployment_result.get("errors", [])
|
|
810
|
-
if deploy_errors:
|
|
811
|
-
# Log for debugging
|
|
812
|
-
logger.warning(
|
|
813
|
-
f"Agent deployment completed with {len(deploy_errors)} errors: {deploy_errors}"
|
|
814
|
-
)
|
|
815
|
-
|
|
816
|
-
# Display errors to user with clear formatting
|
|
817
|
-
print("\n⚠️ Agent Deployment Errors:")
|
|
602
|
+
for error in errors_to_display:
|
|
603
|
+
print(f" - {error}")
|
|
818
604
|
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
605
|
+
if len(agent_result.errors) > max_errors_to_show:
|
|
606
|
+
remaining = len(agent_result.errors) - max_errors_to_show
|
|
607
|
+
print(f" ... and {remaining} more error(s)")
|
|
822
608
|
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
# If more errors exist, show count
|
|
829
|
-
if len(deploy_errors) > max_errors_to_show:
|
|
830
|
-
remaining = len(deploy_errors) - max_errors_to_show
|
|
831
|
-
print(f" ... and {remaining} more error(s)")
|
|
832
|
-
|
|
833
|
-
# Show summary message
|
|
834
|
-
print(
|
|
835
|
-
f"\n❌ Failed to deploy {len(deploy_errors)} agent(s). Please check the error messages above."
|
|
836
|
-
)
|
|
837
|
-
print(" Run with --verbose for detailed error information.\n")
|
|
609
|
+
print(
|
|
610
|
+
f"\n❌ Failed to deploy {len(agent_result.errors)} agent(s). "
|
|
611
|
+
"Please check the error messages above."
|
|
612
|
+
)
|
|
613
|
+
print(" Run with --verbose for detailed error information.\n")
|
|
838
614
|
|
|
839
615
|
except Exception as e:
|
|
840
616
|
# Deployment failure shouldn't block startup
|
|
@@ -859,7 +635,7 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
|
859
635
|
# Cleanup legacy cache even if sync failed
|
|
860
636
|
try:
|
|
861
637
|
cleanup_legacy_agent_cache()
|
|
862
|
-
except Exception:
|
|
638
|
+
except Exception: # nosec B110
|
|
863
639
|
pass # Ignore cleanup errors
|
|
864
640
|
|
|
865
641
|
|
|
@@ -1424,7 +1200,7 @@ def auto_install_chrome_devtools_on_startup():
|
|
|
1424
1200
|
if not chrome_devtools_config.get("auto_install", True):
|
|
1425
1201
|
# Auto-install disabled, skip silently
|
|
1426
1202
|
return
|
|
1427
|
-
except Exception:
|
|
1203
|
+
except Exception: # nosec B110
|
|
1428
1204
|
# If config loading fails, assume auto-install is enabled (default)
|
|
1429
1205
|
pass
|
|
1430
1206
|
|
|
@@ -1679,7 +1455,7 @@ def verify_mcp_gateway_startup():
|
|
|
1679
1455
|
loop.run_until_complete(
|
|
1680
1456
|
asyncio.gather(*pending, return_exceptions=True)
|
|
1681
1457
|
)
|
|
1682
|
-
except Exception:
|
|
1458
|
+
except Exception: # nosec B110
|
|
1683
1459
|
pass # Ignore cleanup errors
|
|
1684
1460
|
finally:
|
|
1685
1461
|
loop.close()
|
|
@@ -1773,7 +1549,7 @@ def check_for_updates_async():
|
|
|
1773
1549
|
|
|
1774
1550
|
logger = get_logger("upgrade_check")
|
|
1775
1551
|
logger.debug(f"Update check failed (non-critical): {e}")
|
|
1776
|
-
except Exception:
|
|
1552
|
+
except Exception: # nosec B110
|
|
1777
1553
|
pass # Avoid any errors in error handling
|
|
1778
1554
|
finally:
|
|
1779
1555
|
# Properly clean up event loop
|
|
@@ -1788,7 +1564,7 @@ def check_for_updates_async():
|
|
|
1788
1564
|
loop.run_until_complete(
|
|
1789
1565
|
asyncio.gather(*pending, return_exceptions=True)
|
|
1790
1566
|
)
|
|
1791
|
-
except Exception:
|
|
1567
|
+
except Exception: # nosec B110
|
|
1792
1568
|
pass # Ignore cleanup errors
|
|
1793
1569
|
finally:
|
|
1794
1570
|
loop.close()
|
|
@@ -27,7 +27,7 @@ _CACHED_CLAUDE_VERSION: Optional[str] = None
|
|
|
27
27
|
_VERSION_DETECTED: bool = False
|
|
28
28
|
|
|
29
29
|
# Output style types
|
|
30
|
-
OutputStyleType = Literal["professional", "teaching"]
|
|
30
|
+
OutputStyleType = Literal["professional", "teaching", "founders"]
|
|
31
31
|
|
|
32
32
|
|
|
33
33
|
class StyleConfig(TypedDict):
|
|
@@ -41,9 +41,10 @@ class StyleConfig(TypedDict):
|
|
|
41
41
|
class OutputStyleManager:
|
|
42
42
|
"""Manages output style deployment and version-based handling.
|
|
43
43
|
|
|
44
|
-
Supports
|
|
44
|
+
Supports three output styles:
|
|
45
45
|
- professional: Default Claude MPM style (claude-mpm.md)
|
|
46
46
|
- teaching: Adaptive teaching mode (claude-mpm-teacher.md)
|
|
47
|
+
- founders: Non-technical mode for startup founders (claude-mpm-founders.md)
|
|
47
48
|
"""
|
|
48
49
|
|
|
49
50
|
def __init__(self) -> None:
|
|
@@ -71,6 +72,13 @@ class OutputStyleManager:
|
|
|
71
72
|
target=self.output_style_dir / "claude-mpm-teacher.md",
|
|
72
73
|
name="Claude MPM Teacher",
|
|
73
74
|
),
|
|
75
|
+
"founders": StyleConfig(
|
|
76
|
+
source=Path(__file__).parent.parent
|
|
77
|
+
/ "agents"
|
|
78
|
+
/ "CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md",
|
|
79
|
+
target=self.output_style_dir / "claude-mpm-founders.md",
|
|
80
|
+
name="Claude MPM Founders",
|
|
81
|
+
),
|
|
74
82
|
}
|
|
75
83
|
|
|
76
84
|
# Default style path (for backward compatibility)
|
|
@@ -0,0 +1,248 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: pm-bug-reporting
|
|
3
|
+
version: "1.0.0"
|
|
4
|
+
description: Bug reporting protocol for PM and agents to file GitHub issues
|
|
5
|
+
when_to_use: Framework bugs, agent errors, skill content errors detected
|
|
6
|
+
category: pm-workflow
|
|
7
|
+
tags: [bug-reporting, github, issues, pm-required]
|
|
8
|
+
---
|
|
9
|
+
|
|
10
|
+
# PM Bug Reporting Protocol
|
|
11
|
+
|
|
12
|
+
## When to Report Bugs
|
|
13
|
+
|
|
14
|
+
Report bugs when you encounter:
|
|
15
|
+
- **PM instruction errors** or missing guidance
|
|
16
|
+
- **Agent malfunction** or incorrect behavior
|
|
17
|
+
- **Skill content errors** or outdated information
|
|
18
|
+
- **Framework crashes** or unexpected behavior
|
|
19
|
+
- **Missing or incorrect documentation**
|
|
20
|
+
- **Configuration errors** or invalid defaults
|
|
21
|
+
|
|
22
|
+
## GitHub Repositories
|
|
23
|
+
|
|
24
|
+
Route bugs to the correct repository:
|
|
25
|
+
|
|
26
|
+
| Bug Type | Repository | Owner/Repo |
|
|
27
|
+
|----------|------------|------------|
|
|
28
|
+
| Core MPM (CLI, startup, config, orchestration) | claude-mpm | bobmatnyc/claude-mpm |
|
|
29
|
+
| Agent bugs (wrong behavior, errors, missing capabilities) | claude-mpm-agents | bobmatnyc/claude-mpm-agents |
|
|
30
|
+
| Skill bugs (wrong info, outdated, missing content) | claude-mpm-skills | bobmatnyc/claude-mpm-skills |
|
|
31
|
+
|
|
32
|
+
## Bug Report Template
|
|
33
|
+
|
|
34
|
+
When creating an issue, include:
|
|
35
|
+
|
|
36
|
+
### Title
|
|
37
|
+
Brief, descriptive title (50 chars max)
|
|
38
|
+
- ✅ "PM delegates to non-existent agent"
|
|
39
|
+
- ✅ "Research skill missing web search examples"
|
|
40
|
+
- ❌ "Bug in system"
|
|
41
|
+
- ❌ "Fix this"
|
|
42
|
+
|
|
43
|
+
### Labels
|
|
44
|
+
Always include:
|
|
45
|
+
- `bug` (required)
|
|
46
|
+
- `agent-reported` (required)
|
|
47
|
+
- Additional context labels:
|
|
48
|
+
- `high-priority` - Critical functionality broken
|
|
49
|
+
- `documentation` - Documentation error
|
|
50
|
+
- `agent-error` - Agent-specific issue
|
|
51
|
+
- `skill-error` - Skill content issue
|
|
52
|
+
|
|
53
|
+
### Body Structure
|
|
54
|
+
```markdown
|
|
55
|
+
## What Happened
|
|
56
|
+
[Clear description of the bug]
|
|
57
|
+
|
|
58
|
+
## Expected Behavior
|
|
59
|
+
[What should have happened]
|
|
60
|
+
|
|
61
|
+
## Steps to Reproduce
|
|
62
|
+
1. [First step]
|
|
63
|
+
2. [Second step]
|
|
64
|
+
3. [Third step]
|
|
65
|
+
|
|
66
|
+
## Context
|
|
67
|
+
- Agent: [agent name if applicable]
|
|
68
|
+
- Skill: [skill name if applicable]
|
|
69
|
+
- Error Message: [full error if available]
|
|
70
|
+
- Version: [MPM version if known]
|
|
71
|
+
|
|
72
|
+
## Impact
|
|
73
|
+
[How this affects users/workflow]
|
|
74
|
+
```
|
|
75
|
+
|
|
76
|
+
## Using gh CLI
|
|
77
|
+
|
|
78
|
+
### Prerequisites Check
|
|
79
|
+
```bash
|
|
80
|
+
gh auth status
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
If not authenticated:
|
|
84
|
+
```bash
|
|
85
|
+
gh auth login
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Creating Issues
|
|
89
|
+
|
|
90
|
+
**Delegate to ticketing agent** with:
|
|
91
|
+
```
|
|
92
|
+
Task:
|
|
93
|
+
agent: ticketing
|
|
94
|
+
task: Create GitHub issue for [bug type]
|
|
95
|
+
context: |
|
|
96
|
+
Repository: bobmatnyc/claude-mpm[-agents|-skills]
|
|
97
|
+
Title: [brief title]
|
|
98
|
+
Labels: bug, agent-reported
|
|
99
|
+
Body: |
|
|
100
|
+
## What Happened
|
|
101
|
+
[description]
|
|
102
|
+
|
|
103
|
+
## Expected Behavior
|
|
104
|
+
[expected]
|
|
105
|
+
|
|
106
|
+
## Steps to Reproduce
|
|
107
|
+
1. [step 1]
|
|
108
|
+
2. [step 2]
|
|
109
|
+
|
|
110
|
+
## Context
|
|
111
|
+
- Agent: [agent name]
|
|
112
|
+
- Error: [error message]
|
|
113
|
+
|
|
114
|
+
## Impact
|
|
115
|
+
[impact description]
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
## Examples
|
|
119
|
+
|
|
120
|
+
### Core MPM Bug
|
|
121
|
+
```
|
|
122
|
+
Task:
|
|
123
|
+
agent: ticketing
|
|
124
|
+
task: Create GitHub issue for core MPM bug
|
|
125
|
+
context: |
|
|
126
|
+
Repository: bobmatnyc/claude-mpm
|
|
127
|
+
Title: PM fails to load configuration on startup
|
|
128
|
+
Labels: bug, agent-reported, high-priority
|
|
129
|
+
Body: |
|
|
130
|
+
## What Happened
|
|
131
|
+
PM fails to initialize when configuration.yaml contains invalid syntax.
|
|
132
|
+
No clear error message shown to user.
|
|
133
|
+
|
|
134
|
+
## Expected Behavior
|
|
135
|
+
PM should display clear YAML syntax error with line number and fix suggestion.
|
|
136
|
+
|
|
137
|
+
## Steps to Reproduce
|
|
138
|
+
1. Add invalid YAML to .claude-mpm/configuration.yaml
|
|
139
|
+
2. Run `mpm`
|
|
140
|
+
3. Observe generic error without details
|
|
141
|
+
|
|
142
|
+
## Context
|
|
143
|
+
- Component: Configuration loader
|
|
144
|
+
- Error: "Failed to load configuration"
|
|
145
|
+
- Version: 5.4.x
|
|
146
|
+
|
|
147
|
+
## Impact
|
|
148
|
+
Users cannot diagnose configuration errors, requiring manual YAML validation.
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
### Agent Bug
|
|
152
|
+
```
|
|
153
|
+
Task:
|
|
154
|
+
agent: ticketing
|
|
155
|
+
task: Create GitHub issue for agent bug
|
|
156
|
+
context: |
|
|
157
|
+
Repository: bobmatnyc/claude-mpm-agents
|
|
158
|
+
Title: Research agent fails to search with special characters
|
|
159
|
+
Labels: bug, agent-reported, agent-error
|
|
160
|
+
Body: |
|
|
161
|
+
## What Happened
|
|
162
|
+
Research agent throws error when search query contains quotes or special chars.
|
|
163
|
+
|
|
164
|
+
## Expected Behavior
|
|
165
|
+
Search queries should be properly escaped and executed.
|
|
166
|
+
|
|
167
|
+
## Steps to Reproduce
|
|
168
|
+
1. Delegate to research: "Search for 'React hooks'"
|
|
169
|
+
2. Research agent attempts search
|
|
170
|
+
3. Error: "Invalid search query"
|
|
171
|
+
|
|
172
|
+
## Context
|
|
173
|
+
- Agent: research
|
|
174
|
+
- Error: grep command fails with unescaped quotes
|
|
175
|
+
|
|
176
|
+
## Impact
|
|
177
|
+
Cannot search for quoted phrases or technical terms with special characters.
|
|
178
|
+
```
|
|
179
|
+
|
|
180
|
+
### Skill Bug
|
|
181
|
+
```
|
|
182
|
+
Task:
|
|
183
|
+
agent: ticketing
|
|
184
|
+
task: Create GitHub issue for skill content error
|
|
185
|
+
context: |
|
|
186
|
+
Repository: bobmatnyc/claude-mpm-skills
|
|
187
|
+
Title: Git workflow skill contains outdated branch strategy
|
|
188
|
+
Labels: bug, agent-reported, documentation, skill-error
|
|
189
|
+
Body: |
|
|
190
|
+
## What Happened
|
|
191
|
+
Skill recommends `git flow` branching model, which project no longer uses.
|
|
192
|
+
Current standard is trunk-based development.
|
|
193
|
+
|
|
194
|
+
## Expected Behavior
|
|
195
|
+
Skill should document current trunk-based workflow.
|
|
196
|
+
|
|
197
|
+
## Context
|
|
198
|
+
- Skill: git-workflow.md
|
|
199
|
+
- Section: "Branching Strategy"
|
|
200
|
+
- Line: 45-60
|
|
201
|
+
|
|
202
|
+
## Impact
|
|
203
|
+
Agents follow outdated branching model, creating workflow friction.
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## Escalation Path
|
|
207
|
+
|
|
208
|
+
When ticketing agent is unavailable or gh CLI fails:
|
|
209
|
+
|
|
210
|
+
1. **Log locally** for manual reporting:
|
|
211
|
+
```
|
|
212
|
+
echo "[BUG] $(date): [description]" >> .claude-mpm/logs/bugs.log
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
2. **Report to PM** for alternative action:
|
|
216
|
+
```
|
|
217
|
+
PM should create ticket in primary ticketing system (Linear/JIRA)
|
|
218
|
+
with note to create GitHub issue once available
|
|
219
|
+
```
|
|
220
|
+
|
|
221
|
+
3. **User notification**:
|
|
222
|
+
```
|
|
223
|
+
"Bug detected: [description]. Logged for manual GitHub issue creation."
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
## Success Criteria
|
|
227
|
+
|
|
228
|
+
Bug reporting successful when:
|
|
229
|
+
- ✅ Issue created in correct repository
|
|
230
|
+
- ✅ All required labels applied (`bug`, `agent-reported`)
|
|
231
|
+
- ✅ Body follows template structure
|
|
232
|
+
- ✅ Title is clear and concise
|
|
233
|
+
- ✅ Context includes agent/skill name if applicable
|
|
234
|
+
- ✅ Issue URL returned for tracking
|
|
235
|
+
|
|
236
|
+
## PM Enforcement
|
|
237
|
+
|
|
238
|
+
PM MUST:
|
|
239
|
+
- Detect bugs during agent interactions
|
|
240
|
+
- Delegate bug reporting to ticketing agent
|
|
241
|
+
- NOT attempt to create GitHub issues directly
|
|
242
|
+
- Follow escalation path if ticketing unavailable
|
|
243
|
+
- Log all bug reports for audit trail
|
|
244
|
+
|
|
245
|
+
## Related Skills
|
|
246
|
+
- [pm-ticketing-integration.md](pm-ticketing-integration.md) - Ticket delegation patterns
|
|
247
|
+
- [pm-delegation-patterns.md](pm-delegation-patterns.md) - General delegation guidance
|
|
248
|
+
- [ticketing-examples.md](ticketing-examples.md) - Ticketing delegation examples
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
|
|
2
|
-
claude_mpm/VERSION,sha256=
|
|
2
|
+
claude_mpm/VERSION,sha256=RPHLSIOUPieL9EOrJan8vzunFO1Z613AZQmZyDI0q2o,7
|
|
3
3
|
claude_mpm/__init__.py,sha256=AGfh00BHKvLYD-UVFw7qbKtl7NMRIzRXOWw7vEuZ-h4,2214
|
|
4
4
|
claude_mpm/__main__.py,sha256=Ro5UBWBoQaSAIoSqWAr7zkbLyvi4sSy28WShqAhKJG0,723
|
|
5
5
|
claude_mpm/constants.py,sha256=pz3lTrZZR5HhV3eZzYtIbtBwWo7iM6pkBHP_ixxmI6Y,6827
|
|
@@ -7,6 +7,7 @@ claude_mpm/init.py,sha256=7aQpqUrWwSckpNXvBrfGOeGYLl92b1Z-NipoXJRc0f4,26401
|
|
|
7
7
|
claude_mpm/ticket_wrapper.py,sha256=qe5xY579t7_7fK5nyeAfHN_fr7CXdeOD3jfXEc8-7yo,828
|
|
8
8
|
claude_mpm/agents/BASE_AGENT.md,sha256=UWvKX5S5L2l68F_sn54otC_HDX5kTt8G4ionUcTVpGo,5645
|
|
9
9
|
claude_mpm/agents/BASE_ENGINEER.md,sha256=I7BusSGQfuV0uSkRBro51qzCzagUEPrXnndIElypPJk,24434
|
|
10
|
+
claude_mpm/agents/CLAUDE_MPM_FOUNDERS_OUTPUT_STYLE.md,sha256=gcxHN7IhtTqH5WRWAf-R_EIpRHF-PORK85zAa5pmeiw,12319
|
|
10
11
|
claude_mpm/agents/CLAUDE_MPM_OUTPUT_STYLE.md,sha256=PmiEOcAcDVOPtCwiCPhNGWb8GVDnniftQO7MIi8yBWU,4174
|
|
11
12
|
claude_mpm/agents/CLAUDE_MPM_TEACHER_OUTPUT_STYLE.md,sha256=vneNW5vHjfKsRIukkuGbAnvnyp_-EC3qpFzHDdsMOwc,4796
|
|
12
13
|
claude_mpm/agents/MEMORY.md,sha256=V1mGx5oEaLdN9AYLX3Xetslmr2Ja6vnLPATeEoR6bvw,3303
|
|
@@ -41,7 +42,7 @@ claude_mpm/cli/chrome_devtools_installer.py,sha256=efA_ZX1iR3oaJi3222079BQw6DEG8
|
|
|
41
42
|
claude_mpm/cli/executor.py,sha256=1MQdNPNoIewSR1q8nXjJuES3zKEi_IqVcZQzt9bsxw8,10601
|
|
42
43
|
claude_mpm/cli/helpers.py,sha256=CypEhw0tbNH6_GzVTaQdi4w7ThCWO43Ep92YbJzPR4I,3638
|
|
43
44
|
claude_mpm/cli/parser.py,sha256=Vqx9n-6Xo1uNhXR4rThmgWpZXTr0nOtkgDf3oMS9b0g,5855
|
|
44
|
-
claude_mpm/cli/startup.py,sha256=
|
|
45
|
+
claude_mpm/cli/startup.py,sha256=rztiI5mopeHnRTn7WPivyZF4QDtHjuC-O-YhYvuw5I8,61638
|
|
45
46
|
claude_mpm/cli/startup_display.py,sha256=R_QIamjfdaY5o_VxpIeymyYj1Qde2B9hPXy1P-KmUKI,14972
|
|
46
47
|
claude_mpm/cli/startup_logging.py,sha256=RTuyd6CbhiFQz7Z07LDDhK_ZAnZfuJ9B0NghVSntHFI,29390
|
|
47
48
|
claude_mpm/cli/utils.py,sha256=FSMPftBZM8MeUyTtiB63Lz7oFOgkzwTetQs58RbRb_Q,8785
|
|
@@ -206,7 +207,7 @@ claude_mpm/core/mixins.py,sha256=vmZ7Nu2ZOnKjbhN07Ixk4noIej9nsJiknrp-Sclfu0A,534
|
|
|
206
207
|
claude_mpm/core/oneshot_session.py,sha256=nA86Zk7W3Rh_yIhPuegFL7Xgc9S63vQ_MqfLk52doV0,21994
|
|
207
208
|
claude_mpm/core/optimized_agent_loader.py,sha256=yevEwTZWzVeZYEJhV3czD45OU7ukJIaJos4MGnFP7YQ,15857
|
|
208
209
|
claude_mpm/core/optimized_startup.py,sha256=U5I4f7PNYXCBOLbCkbWT2V2sv01T8iWP2Bw-f928Q9M,17927
|
|
209
|
-
claude_mpm/core/output_style_manager.py,sha256=
|
|
210
|
+
claude_mpm/core/output_style_manager.py,sha256=ynFLUliYKPuw3CWtTcJR7h0TDBE_5z2gwDT-XT_-Owk,17491
|
|
210
211
|
claude_mpm/core/pm_hook_interceptor.py,sha256=92C8TrpK-XVQD8BiXbqs8lSCX72PU0KZG5oAjhf8GOQ,11197
|
|
211
212
|
claude_mpm/core/service_registry.py,sha256=QpmAMWCov8XXaxQwE7WiNbgv6u_CRjpKPB64kLYvZKk,11722
|
|
212
213
|
claude_mpm/core/session_manager.py,sha256=iEDZWKBYHSu001nFX8vFvH33RvQOW0eIgomWhFM53sw,12078
|
|
@@ -216,7 +217,7 @@ claude_mpm/core/tool_access_control.py,sha256=dpdxxp_77SuxGM2C7SsHUZbtysJmHw1rLD
|
|
|
216
217
|
claude_mpm/core/types.py,sha256=Sv62QhMYvfxbt7oIGoAhhN_jxonFTeLRf-BuhxZ4vYw,7719
|
|
217
218
|
claude_mpm/core/typing_utils.py,sha256=qny3rA9mAeXqdLgUj9DZg642shw4LmLbkPqADN-765s,13314
|
|
218
219
|
claude_mpm/core/unified_agent_registry.py,sha256=YbL-oWeHU85zdf1mF7tyMHBYKtFBupsMeH9BCdzD6ZI,34161
|
|
219
|
-
claude_mpm/core/unified_config.py,sha256=
|
|
220
|
+
claude_mpm/core/unified_config.py,sha256=WWuNWGLK0ySWQ_drR-FVb_FeL8c9HhTU_Ch3hGsPCAo,21768
|
|
220
221
|
claude_mpm/core/unified_paths.py,sha256=F2NYAK6RNtn_xsZnVHVfP7MErzDh_O9hyaa3B4OyT9A,36690
|
|
221
222
|
claude_mpm/core/framework/__init__.py,sha256=IJCp6-MQO8gW31uG8aMWHdNg54NgGvXb4GvOuwZF6Iw,736
|
|
222
223
|
claude_mpm/core/framework/formatters/__init__.py,sha256=OKkLN2x21rcbg3d3feZLixIS-UjHPlxl768uGmQy7Qc,307
|
|
@@ -863,6 +864,7 @@ claude_mpm/skills/bundled/php/espocrm-development/references/development-workflo
|
|
|
863
864
|
claude_mpm/skills/bundled/php/espocrm-development/references/frontend-customization.md,sha256=0h1VohuIr-El_Rj9wWWPluRynQqi2B8i0-xTaPdkGBY,17519
|
|
864
865
|
claude_mpm/skills/bundled/php/espocrm-development/references/hooks-and-services.md,sha256=2KwnVcf5s1TCAo1GMdbLitJMVbi7cdYfDK_M5C4oBtI,20820
|
|
865
866
|
claude_mpm/skills/bundled/php/espocrm-development/references/testing-debugging.md,sha256=9TVZk_ZTez65kzx2R8nG-8fn9V_pIT5oTLsFQdPk2zQ,18250
|
|
867
|
+
claude_mpm/skills/bundled/pm/pm-bug-reporting/pm-bug-reporting.md,sha256=mDjGQd9ALSZ0jsuWyXSVT6_GxTudzAVTkasqwnf4zJE,6494
|
|
866
868
|
claude_mpm/skills/bundled/pm/pm-delegation-patterns/SKILL.md,sha256=kdFyy5T_70vw5XpGexlXr18VdQWIFD59A8pLmmcWiVA,5388
|
|
867
869
|
claude_mpm/skills/bundled/pm/pm-git-file-tracking/SKILL.md,sha256=bnmO9Wzoe0AYJ72yKBO_FqtxsfjIkYhUHlosPRrYgTM,3607
|
|
868
870
|
claude_mpm/skills/bundled/pm/pm-pr-workflow/SKILL.md,sha256=HSeVxw_znHqiPA95gpHnPKavNkSgSLTKuVaHqV976Ao,3369
|
|
@@ -969,10 +971,10 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
|
|
|
969
971
|
claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
|
|
970
972
|
claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
|
|
971
973
|
claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
|
|
972
|
-
claude_mpm-5.4.
|
|
973
|
-
claude_mpm-5.4.
|
|
974
|
-
claude_mpm-5.4.
|
|
975
|
-
claude_mpm-5.4.
|
|
976
|
-
claude_mpm-5.4.
|
|
977
|
-
claude_mpm-5.4.
|
|
978
|
-
claude_mpm-5.4.
|
|
974
|
+
claude_mpm-5.4.84.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
|
|
975
|
+
claude_mpm-5.4.84.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
|
|
976
|
+
claude_mpm-5.4.84.dist-info/METADATA,sha256=mXYhdkcOB3779gcXJpYrizksYyUQxqnJ1d4FtqHKroM,38503
|
|
977
|
+
claude_mpm-5.4.84.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
978
|
+
claude_mpm-5.4.84.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
|
|
979
|
+
claude_mpm-5.4.84.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
|
|
980
|
+
claude_mpm-5.4.84.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|