claude-mpm 5.6.16__py3-none-any.whl → 5.6.18__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/cli/startup.py +94 -0
- claude_mpm/core/claude_runner.py +10 -5
- {claude_mpm-5.6.16.dist-info → claude_mpm-5.6.18.dist-info}/METADATA +1 -1
- {claude_mpm-5.6.16.dist-info → claude_mpm-5.6.18.dist-info}/RECORD +10 -10
- {claude_mpm-5.6.16.dist-info → claude_mpm-5.6.18.dist-info}/WHEEL +0 -0
- {claude_mpm-5.6.16.dist-info → claude_mpm-5.6.18.dist-info}/entry_points.txt +0 -0
- {claude_mpm-5.6.16.dist-info → claude_mpm-5.6.18.dist-info}/licenses/LICENSE +0 -0
- {claude_mpm-5.6.16.dist-info → claude_mpm-5.6.18.dist-info}/licenses/LICENSE-FAQ.md +0 -0
- {claude_mpm-5.6.16.dist-info → claude_mpm-5.6.18.dist-info}/top_level.txt +0 -0
claude_mpm/VERSION
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
5.6.
|
|
1
|
+
5.6.18
|
claude_mpm/cli/startup.py
CHANGED
|
@@ -478,6 +478,94 @@ def _cleanup_orphaned_agents(deploy_target: Path, deployed_agents: list[str]) ->
|
|
|
478
478
|
return removed_count
|
|
479
479
|
|
|
480
480
|
|
|
481
|
+
def _save_deployment_state_after_reconciliation(
|
|
482
|
+
agent_result, project_path: Path
|
|
483
|
+
) -> None:
|
|
484
|
+
"""Save deployment state after reconciliation to prevent duplicate deployment.
|
|
485
|
+
|
|
486
|
+
WHY: After perform_startup_reconciliation() deploys agents to .claude/agents/,
|
|
487
|
+
we need to save a deployment state file so that ClaudeRunner.setup_agents()
|
|
488
|
+
can detect agents are already deployed and skip redundant deployment.
|
|
489
|
+
|
|
490
|
+
This prevents the "✓ Deployed 31 native agents" duplicate deployment that
|
|
491
|
+
occurs when setup_agents() doesn't know reconciliation already ran.
|
|
492
|
+
|
|
493
|
+
Args:
|
|
494
|
+
agent_result: DeploymentResult from perform_startup_reconciliation()
|
|
495
|
+
project_path: Project root directory
|
|
496
|
+
|
|
497
|
+
DESIGN DECISION: Use same state file format as ClaudeRunner._save_deployment_state()
|
|
498
|
+
Located at: .claude-mpm/cache/deployment_state.json
|
|
499
|
+
|
|
500
|
+
State file format:
|
|
501
|
+
{
|
|
502
|
+
"version": "5.6.13",
|
|
503
|
+
"agent_count": 15,
|
|
504
|
+
"deployment_hash": "sha256:...",
|
|
505
|
+
"deployed_at": 1234567890.123
|
|
506
|
+
}
|
|
507
|
+
"""
|
|
508
|
+
import hashlib
|
|
509
|
+
import json
|
|
510
|
+
import time
|
|
511
|
+
|
|
512
|
+
from ..core.logger import get_logger
|
|
513
|
+
|
|
514
|
+
logger = get_logger("cli")
|
|
515
|
+
|
|
516
|
+
try:
|
|
517
|
+
# Get version from package
|
|
518
|
+
from claude_mpm import __version__
|
|
519
|
+
|
|
520
|
+
# Path to state file (matches ClaudeRunner._get_deployment_state_path())
|
|
521
|
+
state_file = project_path / ".claude-mpm" / "cache" / "deployment_state.json"
|
|
522
|
+
agents_dir = project_path / ".claude" / "agents"
|
|
523
|
+
|
|
524
|
+
# Count deployed agents
|
|
525
|
+
if agents_dir.exists():
|
|
526
|
+
agent_count = len(list(agents_dir.glob("*.md")))
|
|
527
|
+
else:
|
|
528
|
+
agent_count = 0
|
|
529
|
+
|
|
530
|
+
# Calculate deployment hash (matches ClaudeRunner._calculate_deployment_hash())
|
|
531
|
+
# CRITICAL: Must match exact hash algorithm used in ClaudeRunner
|
|
532
|
+
# Hashes filename + file content (not mtime) for consistency
|
|
533
|
+
deployment_hash = ""
|
|
534
|
+
if agents_dir.exists():
|
|
535
|
+
agent_files = sorted(agents_dir.glob("*.md"))
|
|
536
|
+
hash_obj = hashlib.sha256()
|
|
537
|
+
for agent_file in agent_files:
|
|
538
|
+
# Include filename and content in hash (matches ClaudeRunner)
|
|
539
|
+
hash_obj.update(agent_file.name.encode())
|
|
540
|
+
try:
|
|
541
|
+
hash_obj.update(agent_file.read_bytes())
|
|
542
|
+
except Exception as e:
|
|
543
|
+
logger.debug(f"Error reading {agent_file} for hash: {e}")
|
|
544
|
+
|
|
545
|
+
deployment_hash = hash_obj.hexdigest()
|
|
546
|
+
|
|
547
|
+
# Create state data
|
|
548
|
+
state_data = {
|
|
549
|
+
"version": __version__,
|
|
550
|
+
"agent_count": agent_count,
|
|
551
|
+
"deployment_hash": deployment_hash,
|
|
552
|
+
"deployed_at": time.time(),
|
|
553
|
+
}
|
|
554
|
+
|
|
555
|
+
# Ensure directory exists
|
|
556
|
+
state_file.parent.mkdir(parents=True, exist_ok=True)
|
|
557
|
+
|
|
558
|
+
# Write state file
|
|
559
|
+
state_file.write_text(json.dumps(state_data, indent=2))
|
|
560
|
+
logger.debug(
|
|
561
|
+
f"Saved deployment state after reconciliation: {agent_count} agents"
|
|
562
|
+
)
|
|
563
|
+
|
|
564
|
+
except Exception as e:
|
|
565
|
+
# Non-critical error - log but don't fail startup
|
|
566
|
+
logger.debug(f"Failed to save deployment state: {e}")
|
|
567
|
+
|
|
568
|
+
|
|
481
569
|
def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
482
570
|
"""
|
|
483
571
|
Synchronize agent templates from remote sources on startup.
|
|
@@ -640,6 +728,12 @@ def sync_remote_agents_on_startup(force_sync: bool = False):
|
|
|
640
728
|
)
|
|
641
729
|
print(" Run with --verbose for detailed error information.\n")
|
|
642
730
|
|
|
731
|
+
# Save deployment state to prevent duplicate deployment in ClaudeRunner
|
|
732
|
+
# This ensures setup_agents() skips deployment since we already reconciled
|
|
733
|
+
_save_deployment_state_after_reconciliation(
|
|
734
|
+
agent_result=agent_result, project_path=project_path
|
|
735
|
+
)
|
|
736
|
+
|
|
643
737
|
except Exception as e:
|
|
644
738
|
# Deployment failure shouldn't block startup
|
|
645
739
|
from ..core.logger import get_logger
|
claude_mpm/core/claude_runner.py
CHANGED
|
@@ -214,8 +214,12 @@ class ClaudeRunner:
|
|
|
214
214
|
)
|
|
215
215
|
|
|
216
216
|
def _get_deployment_state_path(self) -> Path:
|
|
217
|
-
"""Get path to deployment state file.
|
|
218
|
-
|
|
217
|
+
"""Get path to deployment state file.
|
|
218
|
+
|
|
219
|
+
CRITICAL: Must match path used by startup.py::_save_deployment_state_after_reconciliation()
|
|
220
|
+
Located at: .claude-mpm/cache/deployment_state.json
|
|
221
|
+
"""
|
|
222
|
+
return Path.cwd() / ".claude-mpm" / "cache" / "deployment_state.json"
|
|
219
223
|
|
|
220
224
|
def _calculate_deployment_hash(self, agents_dir: Path) -> str:
|
|
221
225
|
"""Calculate hash of all agent files for change detection.
|
|
@@ -332,14 +336,15 @@ class ClaudeRunner:
|
|
|
332
336
|
"""Deploy native agents to .claude/agents/."""
|
|
333
337
|
try:
|
|
334
338
|
# Check if agents are already deployed and up-to-date
|
|
339
|
+
# This detects if reconciliation already ran during startup
|
|
335
340
|
if self._check_deployment_state():
|
|
336
341
|
agents_dir = Path.cwd() / ".claude" / "agents"
|
|
337
342
|
agent_count = len(list(agents_dir.glob("*.md")))
|
|
338
|
-
|
|
343
|
+
# Silent return - reconciliation already logged deployment
|
|
339
344
|
if self.project_logger:
|
|
340
345
|
self.project_logger.log_system(
|
|
341
|
-
f"Agents already deployed: {agent_count}
|
|
342
|
-
level="
|
|
346
|
+
f"Agents already deployed via reconciliation: {agent_count} agents",
|
|
347
|
+
level="DEBUG",
|
|
343
348
|
component="deployment",
|
|
344
349
|
)
|
|
345
350
|
return True
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
claude_mpm/BUILD_NUMBER,sha256=9JfxhnDtr-8l3kCP2U5TVXSErptHoga8m7XA8zqgGOc,4
|
|
2
|
-
claude_mpm/VERSION,sha256=
|
|
2
|
+
claude_mpm/VERSION,sha256=PpRjpQ0ZyEXfEuMQSDx-5ZFFR07Dgt649GTI-_b7Xyk,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
|
|
@@ -42,7 +42,7 @@ claude_mpm/cli/chrome_devtools_installer.py,sha256=efA_ZX1iR3oaJi3222079BQw6DEG8
|
|
|
42
42
|
claude_mpm/cli/executor.py,sha256=eerqDVszBfTm8N2FgreLr-132Jb9BVZGNrrukvb_b-I,15106
|
|
43
43
|
claude_mpm/cli/helpers.py,sha256=CypEhw0tbNH6_GzVTaQdi4w7ThCWO43Ep92YbJzPR4I,3638
|
|
44
44
|
claude_mpm/cli/parser.py,sha256=Vqx9n-6Xo1uNhXR4rThmgWpZXTr0nOtkgDf3oMS9b0g,5855
|
|
45
|
-
claude_mpm/cli/startup.py,sha256=
|
|
45
|
+
claude_mpm/cli/startup.py,sha256=NtfKcGY3F7JnPqg19xMstV6h8i6gKLWTT2JteAx50E4,67175
|
|
46
46
|
claude_mpm/cli/startup_display.py,sha256=KI4GZ0uVoK7FXeK5jsS4JAyaKaKf5rCkY3h5tNeEY7M,17209
|
|
47
47
|
claude_mpm/cli/startup_logging.py,sha256=wHokzcCA0AJPxAqFrpY5PMOBh1iOhdhgP1gY1OvD0gY,29392
|
|
48
48
|
claude_mpm/cli/utils.py,sha256=5e3v-ow1gd-5nlad9OWCsL-3SRJcPjBJ9HS3zygwkiQ,8988
|
|
@@ -271,7 +271,7 @@ claude_mpm/core/agent_session_manager.py,sha256=F10LS-nyTQxzMP3fkhbI94klsJy5xpSA
|
|
|
271
271
|
claude_mpm/core/api_validator.py,sha256=zxeUykC2asy1KwHBDu5w3Eoo64E51PJyNe4PT7CTJf0,12282
|
|
272
272
|
claude_mpm/core/base_service.py,sha256=4Zrt-vQ6g_KVk4hEfvd4QccuItYoOf7wUHCimIW6zJQ,29953
|
|
273
273
|
claude_mpm/core/cache.py,sha256=orh8B40oYnRRGmXdANR4P4f-KVMIHV0vg7vrsemk0no,17232
|
|
274
|
-
claude_mpm/core/claude_runner.py,sha256=
|
|
274
|
+
claude_mpm/core/claude_runner.py,sha256=41qTAA9rrtS33Ta_FHsyjcn7TSh0Zs7i_8oBMHWxQuI,39649
|
|
275
275
|
claude_mpm/core/config.py,sha256=0R1ZLdwxTM2N3-uIBgcbr37jDiEe-G7h7x4YmYIVit0,43385
|
|
276
276
|
claude_mpm/core/config_aliases.py,sha256=QpNNECkTY4TYYAhVlFZvB-msPnZrui90g19u0-v0HDE,9703
|
|
277
277
|
claude_mpm/core/config_constants.py,sha256=MEF35Y2Lj5FMzRdhgSgZrZeTzHfCzistPGZVY8INta4,10073
|
|
@@ -1128,10 +1128,10 @@ claude_mpm/utils/subprocess_utils.py,sha256=D0izRT8anjiUb_JG72zlJR_JAw1cDkb7kalN
|
|
|
1128
1128
|
claude_mpm/validation/__init__.py,sha256=YZhwE3mhit-lslvRLuwfX82xJ_k4haZeKmh4IWaVwtk,156
|
|
1129
1129
|
claude_mpm/validation/agent_validator.py,sha256=GprtAvu80VyMXcKGsK_VhYiXWA6BjKHv7O6HKx0AB9w,20917
|
|
1130
1130
|
claude_mpm/validation/frontmatter_validator.py,sha256=YpJlYNNYcV8u6hIOi3_jaRsDnzhbcQpjCBE6eyBKaFY,7076
|
|
1131
|
-
claude_mpm-5.6.
|
|
1132
|
-
claude_mpm-5.6.
|
|
1133
|
-
claude_mpm-5.6.
|
|
1134
|
-
claude_mpm-5.6.
|
|
1135
|
-
claude_mpm-5.6.
|
|
1136
|
-
claude_mpm-5.6.
|
|
1137
|
-
claude_mpm-5.6.
|
|
1131
|
+
claude_mpm-5.6.18.dist-info/licenses/LICENSE,sha256=ca3y_Rk4aPrbF6f62z8Ht5MJM9OAvbGlHvEDcj9vUQ4,3867
|
|
1132
|
+
claude_mpm-5.6.18.dist-info/licenses/LICENSE-FAQ.md,sha256=TxfEkXVCK98RzDOer09puc7JVCP_q_bN4dHtZKHCMcM,5104
|
|
1133
|
+
claude_mpm-5.6.18.dist-info/METADATA,sha256=iY6Kyv52jHootEtQ0iciyiF4_ji9kWh1MGrPxFNtdhM,15245
|
|
1134
|
+
claude_mpm-5.6.18.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
1135
|
+
claude_mpm-5.6.18.dist-info/entry_points.txt,sha256=n-Uk4vwHPpuvu-g_I7-GHORzTnN_m6iyOsoLveKKD0E,228
|
|
1136
|
+
claude_mpm-5.6.18.dist-info/top_level.txt,sha256=1nUg3FEaBySgm8t-s54jK5zoPnu3_eY6EP6IOlekyHA,11
|
|
1137
|
+
claude_mpm-5.6.18.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|