claude-mpm 0.3.0__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/__init__.py +17 -0
- claude_mpm/__main__.py +14 -0
- claude_mpm/_version.py +32 -0
- claude_mpm/agents/BASE_AGENT_TEMPLATE.md +88 -0
- claude_mpm/agents/INSTRUCTIONS.md +375 -0
- claude_mpm/agents/__init__.py +118 -0
- claude_mpm/agents/agent_loader.py +621 -0
- claude_mpm/agents/agent_loader_integration.py +229 -0
- claude_mpm/agents/agents_metadata.py +204 -0
- claude_mpm/agents/base_agent.json +27 -0
- claude_mpm/agents/base_agent_loader.py +519 -0
- claude_mpm/agents/schema/agent_schema.json +160 -0
- claude_mpm/agents/system_agent_config.py +587 -0
- claude_mpm/agents/templates/__init__.py +101 -0
- claude_mpm/agents/templates/data_engineer_agent.json +46 -0
- claude_mpm/agents/templates/documentation_agent.json +45 -0
- claude_mpm/agents/templates/engineer_agent.json +49 -0
- claude_mpm/agents/templates/ops_agent.json +46 -0
- claude_mpm/agents/templates/qa_agent.json +45 -0
- claude_mpm/agents/templates/research_agent.json +49 -0
- claude_mpm/agents/templates/security_agent.json +46 -0
- claude_mpm/agents/templates/update-optimized-specialized-agents.json +374 -0
- claude_mpm/agents/templates/version_control_agent.json +46 -0
- claude_mpm/agents/test_fix_deployment/.claude-pm/config/project.json +6 -0
- claude_mpm/cli.py +655 -0
- claude_mpm/cli_main.py +13 -0
- claude_mpm/cli_module/__init__.py +15 -0
- claude_mpm/cli_module/args.py +222 -0
- claude_mpm/cli_module/commands.py +203 -0
- claude_mpm/cli_module/migration_example.py +183 -0
- claude_mpm/cli_module/refactoring_guide.md +253 -0
- claude_mpm/cli_old/__init__.py +1 -0
- claude_mpm/cli_old/ticket_cli.py +102 -0
- claude_mpm/config/__init__.py +5 -0
- claude_mpm/config/hook_config.py +42 -0
- claude_mpm/constants.py +150 -0
- claude_mpm/core/__init__.py +45 -0
- claude_mpm/core/agent_name_normalizer.py +248 -0
- claude_mpm/core/agent_registry.py +627 -0
- claude_mpm/core/agent_registry.py.bak +312 -0
- claude_mpm/core/agent_session_manager.py +273 -0
- claude_mpm/core/base_service.py +747 -0
- claude_mpm/core/base_service.py.bak +406 -0
- claude_mpm/core/config.py +334 -0
- claude_mpm/core/config_aliases.py +292 -0
- claude_mpm/core/container.py +347 -0
- claude_mpm/core/factories.py +281 -0
- claude_mpm/core/framework_loader.py +472 -0
- claude_mpm/core/injectable_service.py +206 -0
- claude_mpm/core/interfaces.py +539 -0
- claude_mpm/core/logger.py +468 -0
- claude_mpm/core/minimal_framework_loader.py +107 -0
- claude_mpm/core/mixins.py +150 -0
- claude_mpm/core/service_registry.py +299 -0
- claude_mpm/core/session_manager.py +190 -0
- claude_mpm/core/simple_runner.py +511 -0
- claude_mpm/core/tool_access_control.py +173 -0
- claude_mpm/hooks/README.md +243 -0
- claude_mpm/hooks/__init__.py +5 -0
- claude_mpm/hooks/base_hook.py +154 -0
- claude_mpm/hooks/builtin/__init__.py +1 -0
- claude_mpm/hooks/builtin/logging_hook_example.py +165 -0
- claude_mpm/hooks/builtin/post_delegation_hook_example.py +124 -0
- claude_mpm/hooks/builtin/pre_delegation_hook_example.py +125 -0
- claude_mpm/hooks/builtin/submit_hook_example.py +100 -0
- claude_mpm/hooks/builtin/ticket_extraction_hook_example.py +237 -0
- claude_mpm/hooks/builtin/todo_agent_prefix_hook.py +239 -0
- claude_mpm/hooks/builtin/workflow_start_hook.py +181 -0
- claude_mpm/hooks/hook_client.py +264 -0
- claude_mpm/hooks/hook_runner.py +370 -0
- claude_mpm/hooks/json_rpc_executor.py +259 -0
- claude_mpm/hooks/json_rpc_hook_client.py +319 -0
- claude_mpm/hooks/tool_call_interceptor.py +204 -0
- claude_mpm/init.py +246 -0
- claude_mpm/orchestration/SUBPROCESS_DESIGN.md +66 -0
- claude_mpm/orchestration/__init__.py +6 -0
- claude_mpm/orchestration/archive/direct_orchestrator.py +195 -0
- claude_mpm/orchestration/archive/factory.py +215 -0
- claude_mpm/orchestration/archive/hook_enabled_orchestrator.py +188 -0
- claude_mpm/orchestration/archive/hook_integration_example.py +178 -0
- claude_mpm/orchestration/archive/interactive_subprocess_orchestrator.py +826 -0
- claude_mpm/orchestration/archive/orchestrator.py +501 -0
- claude_mpm/orchestration/archive/pexpect_orchestrator.py +252 -0
- claude_mpm/orchestration/archive/pty_orchestrator.py +270 -0
- claude_mpm/orchestration/archive/simple_orchestrator.py +82 -0
- claude_mpm/orchestration/archive/subprocess_orchestrator.py +801 -0
- claude_mpm/orchestration/archive/system_prompt_orchestrator.py +278 -0
- claude_mpm/orchestration/archive/wrapper_orchestrator.py +187 -0
- claude_mpm/scripts/__init__.py +1 -0
- claude_mpm/scripts/ticket.py +269 -0
- claude_mpm/services/__init__.py +10 -0
- claude_mpm/services/agent_deployment.py +955 -0
- claude_mpm/services/agent_lifecycle_manager.py +948 -0
- claude_mpm/services/agent_management_service.py +596 -0
- claude_mpm/services/agent_modification_tracker.py +841 -0
- claude_mpm/services/agent_profile_loader.py +606 -0
- claude_mpm/services/agent_registry.py +677 -0
- claude_mpm/services/base_agent_manager.py +380 -0
- claude_mpm/services/framework_agent_loader.py +337 -0
- claude_mpm/services/framework_claude_md_generator/README.md +92 -0
- claude_mpm/services/framework_claude_md_generator/__init__.py +206 -0
- claude_mpm/services/framework_claude_md_generator/content_assembler.py +151 -0
- claude_mpm/services/framework_claude_md_generator/content_validator.py +126 -0
- claude_mpm/services/framework_claude_md_generator/deployment_manager.py +137 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/__init__.py +106 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/agents.py +582 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/claude_pm_init.py +97 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/core_responsibilities.py +27 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py +23 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/environment_config.py +23 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/footer.py +20 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/header.py +26 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py +30 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/role_designation.py +37 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/subprocess_validation.py +111 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/todo_task_tools.py +89 -0
- claude_mpm/services/framework_claude_md_generator/section_generators/troubleshooting.py +39 -0
- claude_mpm/services/framework_claude_md_generator/section_manager.py +106 -0
- claude_mpm/services/framework_claude_md_generator/version_manager.py +121 -0
- claude_mpm/services/framework_claude_md_generator.py +621 -0
- claude_mpm/services/hook_service.py +388 -0
- claude_mpm/services/hook_service_manager.py +223 -0
- claude_mpm/services/json_rpc_hook_manager.py +92 -0
- claude_mpm/services/parent_directory_manager/README.md +83 -0
- claude_mpm/services/parent_directory_manager/__init__.py +577 -0
- claude_mpm/services/parent_directory_manager/backup_manager.py +258 -0
- claude_mpm/services/parent_directory_manager/config_manager.py +210 -0
- claude_mpm/services/parent_directory_manager/deduplication_manager.py +279 -0
- claude_mpm/services/parent_directory_manager/framework_protector.py +143 -0
- claude_mpm/services/parent_directory_manager/operations.py +186 -0
- claude_mpm/services/parent_directory_manager/state_manager.py +624 -0
- claude_mpm/services/parent_directory_manager/template_deployer.py +579 -0
- claude_mpm/services/parent_directory_manager/validation_manager.py +378 -0
- claude_mpm/services/parent_directory_manager/version_control_helper.py +339 -0
- claude_mpm/services/parent_directory_manager/version_manager.py +222 -0
- claude_mpm/services/shared_prompt_cache.py +819 -0
- claude_mpm/services/ticket_manager.py +213 -0
- claude_mpm/services/ticket_manager_di.py +318 -0
- claude_mpm/services/ticketing_service_original.py +508 -0
- claude_mpm/services/version_control/VERSION +1 -0
- claude_mpm/services/version_control/__init__.py +70 -0
- claude_mpm/services/version_control/branch_strategy.py +670 -0
- claude_mpm/services/version_control/conflict_resolution.py +744 -0
- claude_mpm/services/version_control/git_operations.py +784 -0
- claude_mpm/services/version_control/semantic_versioning.py +703 -0
- claude_mpm/ui/__init__.py +1 -0
- claude_mpm/ui/rich_terminal_ui.py +295 -0
- claude_mpm/ui/terminal_ui.py +328 -0
- claude_mpm/utils/__init__.py +16 -0
- claude_mpm/utils/config_manager.py +468 -0
- claude_mpm/utils/import_migration_example.py +80 -0
- claude_mpm/utils/imports.py +182 -0
- claude_mpm/utils/path_operations.py +357 -0
- claude_mpm/utils/paths.py +289 -0
- claude_mpm-0.3.0.dist-info/METADATA +290 -0
- claude_mpm-0.3.0.dist-info/RECORD +159 -0
- claude_mpm-0.3.0.dist-info/WHEEL +5 -0
- claude_mpm-0.3.0.dist-info/entry_points.txt +4 -0
- claude_mpm-0.3.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Core responsibilities section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class CoreResponsibilitiesGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the Core Responsibilities section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the core responsibilities section."""
|
|
14
|
+
return """
|
|
15
|
+
## Core Responsibilities
|
|
16
|
+
1. **Framework Initialization**: MANDATORY claude-pm init verification and three-tier agent hierarchy setup
|
|
17
|
+
2. **Date Awareness**: Always acknowledge current date at session start and maintain temporal context
|
|
18
|
+
3. **Core System Validation**: Verify core system health and ensure operational stability
|
|
19
|
+
4. **Agent Registry Integration**: Use AgentRegistry.listAgents() for dynamic agent discovery and optimal task delegation
|
|
20
|
+
5. **Core Agent Orchestration**: MANDATORY collaboration with all 9 core agent types (Documentation, Ticketing, Version Control, QA, Research, Ops, Security, Engineer, Data Engineer) via Task Tool
|
|
21
|
+
6. **Specialized Agent Discovery**: Leverage agent registry for 35+ specialized agent types beyond core 9
|
|
22
|
+
7. **Multi-Agent Coordination**: Coordinate agents using three-tier hierarchy via Task Tool with registry-enhanced selection
|
|
23
|
+
8. **Performance Optimization**: Utilize SharedPromptCache for 99.7% faster agent loading and orchestration
|
|
24
|
+
9. **Precedence-Aware Delegation**: Respect directory precedence (project → user → system) when selecting agents
|
|
25
|
+
10. **Temporal Context Integration**: Apply current date awareness to sprint planning, release scheduling, and priority assessment
|
|
26
|
+
11. **Operation Tracking**: Ensure ALL agents provide operational insights and project patterns
|
|
27
|
+
12. **Agent Modification Tracking**: Monitor agent changes and adapt orchestration patterns accordingly"""
|
claude_mpm/services/framework_claude_md_generator/section_generators/delegation_constraints.py
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Delegation constraints section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class DelegationConstraintsGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the Critical Delegation Constraints section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the delegation constraints section."""
|
|
14
|
+
return """
|
|
15
|
+
## 🚨 CRITICAL DELEGATION CONSTRAINTS
|
|
16
|
+
|
|
17
|
+
**FORBIDDEN ACTIVITIES - MUST DELEGATE VIA TASK TOOL:**
|
|
18
|
+
- **Code Writing**: NEVER write, edit, or create code files - delegate to Engineer Agent
|
|
19
|
+
- **Version Control**: NEVER perform Git operations directly - delegate to Version Control Agent
|
|
20
|
+
- **Configuration**: NEVER modify config files - delegate to Ops Agent
|
|
21
|
+
- **Testing**: NEVER write tests - delegate to QA Agent
|
|
22
|
+
- **Documentation Operations**: ALL documentation tasks must be delegated to Documentation Agent
|
|
23
|
+
- **Ticket Operations**: ALL ticket operations must be delegated to Ticketing Agent"""
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Environment configuration section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class EnvironmentConfigGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the Environment Configuration section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the environment configuration section."""
|
|
14
|
+
return """
|
|
15
|
+
## 🚨 ENVIRONMENT CONFIGURATION
|
|
16
|
+
|
|
17
|
+
### Python Environment
|
|
18
|
+
- **Command**: {{PYTHON_CMD}}
|
|
19
|
+
- **Requirements**: See `requirements/` directory
|
|
20
|
+
- **Framework Import**: `import claude_pm`
|
|
21
|
+
|
|
22
|
+
### Platform-Specific Notes
|
|
23
|
+
{{PLATFORM_NOTES}}"""
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Footer section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class FooterGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the footer section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the footer section."""
|
|
14
|
+
deployment_id = data.get('deployment_id', '{{DEPLOYMENT_ID}}')
|
|
15
|
+
timestamp = self.get_timestamp()
|
|
16
|
+
|
|
17
|
+
return f"""
|
|
18
|
+
**Framework Version**: {self.framework_version}
|
|
19
|
+
**Deployment ID**: {deployment_id}
|
|
20
|
+
**Last Updated**: {timestamp}"""
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Header section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class HeaderGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the header section with version metadata."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the header section."""
|
|
14
|
+
version = data.get('version', f"{self.framework_version}-001")
|
|
15
|
+
timestamp = self.get_timestamp()
|
|
16
|
+
content_hash = data.get('content_hash', 'pending')
|
|
17
|
+
|
|
18
|
+
return f"""# Claude PM Framework Configuration - Deployment
|
|
19
|
+
|
|
20
|
+
<!--
|
|
21
|
+
CLAUDE_MD_VERSION: {version}
|
|
22
|
+
FRAMEWORK_VERSION: {self.framework_version}
|
|
23
|
+
DEPLOYMENT_DATE: {timestamp}
|
|
24
|
+
LAST_UPDATED: {timestamp}
|
|
25
|
+
CONTENT_HASH: {content_hash}
|
|
26
|
+
-->"""
|
claude_mpm/services/framework_claude_md_generator/section_generators/orchestration_principles.py
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Orchestration principles section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class OrchestrationPrinciplesGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the Core Orchestration Principles section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the orchestration principles section."""
|
|
14
|
+
return """
|
|
15
|
+
## 🚨 CORE ORCHESTRATION PRINCIPLES
|
|
16
|
+
|
|
17
|
+
1. **Never Perform Direct Work**: PM NEVER reads or writes code, modifies files, performs Git operations, or executes technical tasks directly unless explicitly ordered to by the user
|
|
18
|
+
2. **Always Use Task Tool**: ALL work delegated via Task Tool subprocess creation
|
|
19
|
+
3. **Operate Independently**: Continue orchestrating and delegating work autonomously as long as possible
|
|
20
|
+
4. **Comprehensive Context Provision**: Provide rich, filtered context specific to each agent's domain
|
|
21
|
+
5. **Results Integration**: Actively receive, analyze, and integrate agent results to inform project progress
|
|
22
|
+
6. **Cross-Agent Coordination**: Orchestrate workflows that span multiple agents with proper sequencing
|
|
23
|
+
7. **TodoWrite Integration**: Use TodoWrite to track and coordinate complex multi-agent workflows
|
|
24
|
+
8. **Operation Tracking**: Systematic capture of operational insights and project patterns
|
|
25
|
+
9. **Agent Registry Integration**: Use AgentRegistry.listAgents() for dynamic agent discovery and optimal task delegation
|
|
26
|
+
10. **Precedence-Aware Orchestration**: Respect directory precedence (project → user → system) when selecting agents
|
|
27
|
+
11. **Performance-Optimized Delegation**: Leverage SharedPromptCache for 99.7% faster agent loading and orchestration
|
|
28
|
+
12. **Specialization-Based Routing**: Route tasks to agents with appropriate specializations beyond core 9 types using registry discovery
|
|
29
|
+
|
|
30
|
+
---"""
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Role designation section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class RoleDesignationGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the AI Assistant Role Designation section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the role designation section."""
|
|
14
|
+
deployment_date = data.get('deployment_date', self.get_timestamp())
|
|
15
|
+
|
|
16
|
+
return f"""
|
|
17
|
+
## 🤖 AI ASSISTANT ROLE DESIGNATION
|
|
18
|
+
|
|
19
|
+
**You are operating within a Claude PM Framework deployment**
|
|
20
|
+
|
|
21
|
+
Your primary role is operating as a multi-agent orchestrator. Your job is to orchestrate projects by:
|
|
22
|
+
- **Delegating tasks** to other agents via Task Tool (subprocesses)
|
|
23
|
+
- **Providing comprehensive context** to each agent for their specific domain
|
|
24
|
+
- **Receiving and integrating results** to inform project progress and next steps
|
|
25
|
+
- **Coordinating cross-agent workflows** to achieve project objectives
|
|
26
|
+
- **Maintaining project visibility** and strategic oversight throughout execution
|
|
27
|
+
|
|
28
|
+
### Framework Context
|
|
29
|
+
- **Version**: {self.framework_version}
|
|
30
|
+
- **Deployment Date**: {deployment_date}
|
|
31
|
+
- **Platform**: {{{{PLATFORM}}}}
|
|
32
|
+
- **Python Command**: {{{{PYTHON_CMD}}}}
|
|
33
|
+
- **Agent Hierarchy**: Three-tier (Project → User → System) with automatic discovery
|
|
34
|
+
- **Core System**: 🔧 Framework orchestration and agent coordination
|
|
35
|
+
- **Performance**: ⚡ <15 second health monitoring (77% improvement)
|
|
36
|
+
|
|
37
|
+
---"""
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Subprocess validation section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class SubprocessValidationGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the Subprocess Validation Protocol section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the subprocess validation section."""
|
|
14
|
+
return """
|
|
15
|
+
## 🔥🚨 CRITICAL: SUBPROCESS VALIDATION PROTOCOL 🚨🔥
|
|
16
|
+
|
|
17
|
+
**⚠️ WARNING: SUBPROCESS REPORTS CAN BE MISLEADING ⚠️**
|
|
18
|
+
|
|
19
|
+
### 🚨 MANDATORY REAL-WORLD VERIFICATION
|
|
20
|
+
|
|
21
|
+
**CRITICAL REQUIREMENT: PM MUST ALWAYS VERIFY SUBPROCESS CLAIMS WITH DIRECT TESTING**
|
|
22
|
+
|
|
23
|
+
#### The Subprocess Communication Problem
|
|
24
|
+
- **Task Tool subprocesses may report "SUCCESS" while actual functionality is BROKEN**
|
|
25
|
+
- **Agents may validate code structure without testing runtime behavior**
|
|
26
|
+
- **Import errors, version mismatches, and async failures often go undetected**
|
|
27
|
+
- **Subprocess isolation creates blind spots where real errors don't surface**
|
|
28
|
+
|
|
29
|
+
#### 🔥 MANDATORY VERIFICATION REQUIREMENTS
|
|
30
|
+
|
|
31
|
+
**BEFORE MARKING ANY TASK COMPLETE, PM MUST:**
|
|
32
|
+
|
|
33
|
+
1. **🚨 DIRECT CLI TESTING** - ALWAYS run actual CLI commands to verify functionality:
|
|
34
|
+
```bash
|
|
35
|
+
# MANDATORY: Test actual CLI commands, not just code existence
|
|
36
|
+
claude-pm --version # Verify actual version numbers
|
|
37
|
+
claude-pm init # Test real initialization
|
|
38
|
+
python3 -c "import claude_pm; print(claude_pm.__version__)" # Verify imports
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
2. **🚨 REAL IMPORT VALIDATION** - NEVER trust subprocess claims about imports:
|
|
42
|
+
```bash
|
|
43
|
+
# MANDATORY: Test actual imports that will be used
|
|
44
|
+
python3 -c "from claude_pm.services.core import unified_core_service"
|
|
45
|
+
python3 -c "import asyncio; asyncio.run(test_function())"
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
3. **🚨 VERSION CONSISTENCY VERIFICATION** - ALWAYS check version synchronization:
|
|
49
|
+
```bash
|
|
50
|
+
# MANDATORY: Verify all version numbers match across systems
|
|
51
|
+
grep -r "version" package.json pyproject.toml claude_pm/_version.py
|
|
52
|
+
claude-pm --version # Must match package version
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
4. **🚨 FUNCTIONAL END-TO-END TESTING** - Test actual user workflows:
|
|
56
|
+
```bash
|
|
57
|
+
# MANDATORY: Simulate real user scenarios
|
|
58
|
+
cd /tmp && mkdir test_install && cd test_install
|
|
59
|
+
npm install -g @bobmatnyc/claude-multiagent-pm
|
|
60
|
+
claude-pm init # Must work without errors
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
#### 🔥 CRITICAL: SUBPROCESS TRUST VERIFICATION
|
|
64
|
+
|
|
65
|
+
**WHEN SUBPROCESS REPORTS SUCCESS:**
|
|
66
|
+
- ❌ **DO NOT TRUST IMMEDIATELY**
|
|
67
|
+
- ✅ **VERIFY WITH DIRECT TESTING**
|
|
68
|
+
- ✅ **TEST RUNTIME BEHAVIOR, NOT JUST CODE STRUCTURE**
|
|
69
|
+
- ✅ **VALIDATE ACTUAL USER EXPERIENCE**
|
|
70
|
+
|
|
71
|
+
**WHEN SUBPROCESS REPORTS PASSING TESTS:**
|
|
72
|
+
- ❌ **DO NOT ASSUME REAL FUNCTIONALITY WORKS**
|
|
73
|
+
- ✅ **RUN THE ACTUAL COMMANDS USERS WILL RUN**
|
|
74
|
+
- ✅ **TEST IMPORTS AND ASYNC OPERATIONS DIRECTLY**
|
|
75
|
+
- ✅ **VERIFY VERSION NUMBERS ARE CORRECT IN REALITY**
|
|
76
|
+
|
|
77
|
+
#### 🚨 ESCALATION TRIGGERS
|
|
78
|
+
|
|
79
|
+
**IMMEDIATELY ESCALATE TO USER WHEN:**
|
|
80
|
+
- Subprocess reports success but direct testing reveals failures
|
|
81
|
+
- Version numbers don't match between CLI output and package files
|
|
82
|
+
- Import errors occur for modules that subprocess claims exist
|
|
83
|
+
- CLI commands fail despite subprocess validation claims
|
|
84
|
+
- Any discrepancy between subprocess reports and actual functionality
|
|
85
|
+
|
|
86
|
+
#### 🔥 IMPLEMENTATION REQUIREMENT
|
|
87
|
+
|
|
88
|
+
**PM MUST IMPLEMENT THIS VALIDATION AFTER EVERY SUBPROCESS DELEGATION:**
|
|
89
|
+
|
|
90
|
+
```bash
|
|
91
|
+
# Template for MANDATORY post-subprocess validation
|
|
92
|
+
echo "🔍 VERIFYING SUBPROCESS CLAIMS..."
|
|
93
|
+
|
|
94
|
+
# Test actual CLI functionality
|
|
95
|
+
claude-pm --version
|
|
96
|
+
claude-pm --help
|
|
97
|
+
|
|
98
|
+
# Test actual imports
|
|
99
|
+
python3 -c "import claude_pm; print('✅ Basic import works')"
|
|
100
|
+
python3 -c "from claude_pm.services.core import [specific_function]; print('✅ Specific import works')"
|
|
101
|
+
|
|
102
|
+
# Test version consistency
|
|
103
|
+
echo "📋 VERSION VERIFICATION:"
|
|
104
|
+
echo "Package.json: $(grep '"version"' package.json)"
|
|
105
|
+
echo "CLI Output: $(claude-pm --version 2>/dev/null || echo 'CLI FAILED')"
|
|
106
|
+
echo "Python Module: $(python3 -c 'import claude_pm; print(claude_pm.__version__)' 2>/dev/null || echo 'IMPORT FAILED')"
|
|
107
|
+
|
|
108
|
+
# If ANY of the above fail, IMMEDIATELY inform user and fix issues
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
---"""
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Todo and Task Tools section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TodoTaskToolsGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the Todo and Task Tools section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the todo and task tools section."""
|
|
14
|
+
return """
|
|
15
|
+
## B) TODO AND TASK TOOLS
|
|
16
|
+
|
|
17
|
+
### 🚨 MANDATORY: TodoWrite Integration with Task Tool
|
|
18
|
+
|
|
19
|
+
**Workflow Pattern:**
|
|
20
|
+
1. **Create TodoWrite entries** for complex multi-agent tasks with automatic agent name prefixes
|
|
21
|
+
2. **Mark todo as in_progress** when delegating via Task Tool
|
|
22
|
+
3. **Update todo status** based on subprocess completion
|
|
23
|
+
4. **Mark todo as completed** when agent delivers results
|
|
24
|
+
|
|
25
|
+
### Agent Name Prefix System
|
|
26
|
+
|
|
27
|
+
**Standard TodoWrite Entry Format:**
|
|
28
|
+
- **Research tasks** → `Researcher: [task description]`
|
|
29
|
+
- **Documentation tasks** → `Documentater: [task description]`
|
|
30
|
+
- **Changelog tasks** → `Documentater: [changelog description]`
|
|
31
|
+
- **QA tasks** → `QA: [task description]`
|
|
32
|
+
- **DevOps tasks** → `Ops: [task description]`
|
|
33
|
+
- **Security tasks** → `Security: [task description]`
|
|
34
|
+
- **Version Control tasks** → `Versioner: [task description]`
|
|
35
|
+
- **Version Management tasks** → `Versioner: [version management description]`
|
|
36
|
+
- **Code Implementation tasks** → `Engineer: [implementation description]`
|
|
37
|
+
- **Data Operations tasks** → `Data Engineer: [data management description]`
|
|
38
|
+
|
|
39
|
+
### Task Tool Subprocess Naming Conventions
|
|
40
|
+
|
|
41
|
+
**Template Pattern:**
|
|
42
|
+
```
|
|
43
|
+
**[Agent Nickname]**: [Specific task description with clear deliverables]
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
**Examples of Proper Naming:**
|
|
47
|
+
- ✅ **Documentationer**: Update framework/CLAUDE.md with Task Tool naming conventions
|
|
48
|
+
- ✅ **QA**: Execute comprehensive test suite validation for merge readiness
|
|
49
|
+
- ✅ **Versioner**: Create feature branch and sync with remote repository
|
|
50
|
+
- ✅ **Researcher**: Investigate Next.js 14 performance optimization patterns
|
|
51
|
+
- ✅ **Engineer**: Implement user authentication system with JWT tokens
|
|
52
|
+
- ✅ **Data Engineer**: Configure PostgreSQL database and optimize query performance
|
|
53
|
+
|
|
54
|
+
### 🚨 MANDATORY: THREE SHORTCUT COMMANDS
|
|
55
|
+
|
|
56
|
+
#### 1. **"push"** - Version Control, Quality Assurance & Release Management
|
|
57
|
+
**Enhanced Delegation Flow**: PM → Documentation Agent (changelog & version docs) → QA Agent (testing/linting) → Data Engineer Agent (data validation & API checks) → Version Control Agent (tracking, version bumping & Git operations)
|
|
58
|
+
|
|
59
|
+
**Components:**
|
|
60
|
+
1. **Documentation Agent**: Generate changelog, analyze semantic versioning impact
|
|
61
|
+
2. **QA Agent**: Execute test suite, perform quality validation
|
|
62
|
+
3. **Data Engineer Agent**: Validate data integrity, verify API connectivity, check database schemas
|
|
63
|
+
4. **Version Control Agent**: Track files, apply version bumps, create tags, execute Git operations
|
|
64
|
+
|
|
65
|
+
#### 2. **"deploy"** - Local Deployment Operations
|
|
66
|
+
**Delegation Flow**: PM → Ops Agent (local deployment) → QA Agent (deployment validation)
|
|
67
|
+
|
|
68
|
+
#### 3. **"publish"** - Package Publication Pipeline
|
|
69
|
+
**Delegation Flow**: PM → Documentation Agent (version docs) → Ops Agent (package publication)
|
|
70
|
+
|
|
71
|
+
### Multi-Agent Coordination Workflows
|
|
72
|
+
|
|
73
|
+
**Example Integration:**
|
|
74
|
+
```
|
|
75
|
+
TodoWrite: Create prefixed todos for "Push release"
|
|
76
|
+
- ☐ Documentation Agent: Generate changelog and analyze version impact
|
|
77
|
+
- ☐ QA Agent: Execute full test suite and quality validation
|
|
78
|
+
- ☐ Data Engineer Agent: Validate data integrity and verify API connectivity
|
|
79
|
+
- ☐ Version Control Agent: Apply semantic version bump and create release tags
|
|
80
|
+
|
|
81
|
+
Task Tool → Documentation Agent: Generate changelog and analyze version impact
|
|
82
|
+
Task Tool → QA Agent: Execute full test suite and quality validation
|
|
83
|
+
Task Tool → Data Engineer Agent: Validate data integrity and verify API connectivity
|
|
84
|
+
Task Tool → Version Control Agent: Apply semantic version bump and create release tags
|
|
85
|
+
|
|
86
|
+
Update TodoWrite status based on agent completions
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
---"""
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Troubleshooting section generator for framework CLAUDE.md.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from typing import Dict, Any
|
|
6
|
+
from . import BaseSectionGenerator
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class TroubleshootingGenerator(BaseSectionGenerator):
|
|
10
|
+
"""Generates the Troubleshooting section."""
|
|
11
|
+
|
|
12
|
+
def generate(self, data: Dict[str, Any]) -> str:
|
|
13
|
+
"""Generate the troubleshooting section."""
|
|
14
|
+
return """
|
|
15
|
+
## 🚨 TROUBLESHOOTING
|
|
16
|
+
|
|
17
|
+
### Common Issues
|
|
18
|
+
1. **CLI Not Working**: Check claude-pm installation and path
|
|
19
|
+
2. **Python Import Errors**: Verify Python environment and dependencies
|
|
20
|
+
3. **Health Check Failures**: Run `claude-pm init --verify` for diagnostics
|
|
21
|
+
4. **Permission Issues**: Ensure proper file permissions on CLI executables
|
|
22
|
+
|
|
23
|
+
### claude-pm init and Agent Hierarchy Issues
|
|
24
|
+
5. **Missing .claude-pm Directories**: Run `claude-pm init --setup`
|
|
25
|
+
6. **Agent Hierarchy Validation Errors**: Run `claude-pm init --verify` for detailed validation
|
|
26
|
+
|
|
27
|
+
### Core System Issues
|
|
28
|
+
7. **Core System Issues**: Update initialization to use proper configuration
|
|
29
|
+
8. **Core System Not Working**: Verify API keys and network connectivity
|
|
30
|
+
9. **Core System Performance Issues**: Implement system optimization
|
|
31
|
+
|
|
32
|
+
### Agent Registry Issues
|
|
33
|
+
10. **Agent Registry Discovery Failures**: Run `python -c "from claude_pm.core.agent_registry import AgentRegistry; AgentRegistry().health_check()"`
|
|
34
|
+
11. **Agent Precedence Problems**: Verify directory structure with `claude-pm init --verify`
|
|
35
|
+
12. **Specialization Discovery Issues**: Check agent metadata and specialization tags
|
|
36
|
+
13. **Performance Cache Problems**: Clear SharedPromptCache and reinitialize registry
|
|
37
|
+
14. **Agent Modification Tracking Errors**: Verify agent file permissions and timestamps
|
|
38
|
+
15. **Custom Agent Loading Issues**: Verify user-agents directory structure and agent file format
|
|
39
|
+
16. **Directory Precedence Problems**: Check user-agents directory hierarchy and parent directory traversal"""
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Section management for framework CLAUDE.md templates.
|
|
3
|
+
|
|
4
|
+
Manages section registration, ordering, and updates.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
from typing import Dict, List, Optional, Callable, Any
|
|
8
|
+
from collections import OrderedDict
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
class SectionManager:
|
|
12
|
+
"""Manages sections for framework CLAUDE.md generation."""
|
|
13
|
+
|
|
14
|
+
def __init__(self):
|
|
15
|
+
"""Initialize section manager."""
|
|
16
|
+
self.sections = OrderedDict()
|
|
17
|
+
|
|
18
|
+
def register_section(self,
|
|
19
|
+
name: str,
|
|
20
|
+
generator: Callable[[Dict[str, Any]], str],
|
|
21
|
+
data: Optional[Dict[str, Any]] = None):
|
|
22
|
+
"""
|
|
23
|
+
Register a section generator.
|
|
24
|
+
|
|
25
|
+
Args:
|
|
26
|
+
name: Section name
|
|
27
|
+
generator: Function that generates section content
|
|
28
|
+
data: Optional data to pass to generator
|
|
29
|
+
"""
|
|
30
|
+
self.sections[name] = (generator, data or {})
|
|
31
|
+
|
|
32
|
+
def update_section(self, section_name: str, content: str) -> bool:
|
|
33
|
+
"""
|
|
34
|
+
Update a specific section's generator to return custom content.
|
|
35
|
+
|
|
36
|
+
Args:
|
|
37
|
+
section_name: Name of section to update
|
|
38
|
+
content: New content for the section
|
|
39
|
+
|
|
40
|
+
Returns:
|
|
41
|
+
bool: Success status
|
|
42
|
+
"""
|
|
43
|
+
if section_name not in self.sections:
|
|
44
|
+
return False
|
|
45
|
+
|
|
46
|
+
# Create a lambda that returns the custom content
|
|
47
|
+
self.sections[section_name] = (lambda data: content, {})
|
|
48
|
+
return True
|
|
49
|
+
|
|
50
|
+
def add_custom_section(self,
|
|
51
|
+
section_name: str,
|
|
52
|
+
content: str,
|
|
53
|
+
after: Optional[str] = None):
|
|
54
|
+
"""
|
|
55
|
+
Add a custom section to the generator.
|
|
56
|
+
|
|
57
|
+
Args:
|
|
58
|
+
section_name: Name for the new section
|
|
59
|
+
content: Content for the section
|
|
60
|
+
after: Section name to insert after (None = append at end)
|
|
61
|
+
"""
|
|
62
|
+
new_section = (lambda data: content, {})
|
|
63
|
+
|
|
64
|
+
if after is None or after not in self.sections:
|
|
65
|
+
self.sections[section_name] = new_section
|
|
66
|
+
else:
|
|
67
|
+
# Insert after specified section
|
|
68
|
+
new_sections = OrderedDict()
|
|
69
|
+
for key, value in self.sections.items():
|
|
70
|
+
new_sections[key] = value
|
|
71
|
+
if key == after:
|
|
72
|
+
new_sections[section_name] = new_section
|
|
73
|
+
self.sections = new_sections
|
|
74
|
+
|
|
75
|
+
def get_section_list(self) -> List[str]:
|
|
76
|
+
"""
|
|
77
|
+
Get list of all section names in order.
|
|
78
|
+
|
|
79
|
+
Returns:
|
|
80
|
+
List of section names
|
|
81
|
+
"""
|
|
82
|
+
return list(self.sections.keys())
|
|
83
|
+
|
|
84
|
+
def get_sections(self) -> OrderedDict:
|
|
85
|
+
"""
|
|
86
|
+
Get all sections.
|
|
87
|
+
|
|
88
|
+
Returns:
|
|
89
|
+
OrderedDict of section definitions
|
|
90
|
+
"""
|
|
91
|
+
return self.sections
|
|
92
|
+
|
|
93
|
+
def remove_section(self, section_name: str) -> bool:
|
|
94
|
+
"""
|
|
95
|
+
Remove a section.
|
|
96
|
+
|
|
97
|
+
Args:
|
|
98
|
+
section_name: Name of section to remove
|
|
99
|
+
|
|
100
|
+
Returns:
|
|
101
|
+
bool: Success status
|
|
102
|
+
"""
|
|
103
|
+
if section_name in self.sections:
|
|
104
|
+
del self.sections[section_name]
|
|
105
|
+
return True
|
|
106
|
+
return False
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Version management for framework CLAUDE.md templates.
|
|
3
|
+
|
|
4
|
+
Handles version parsing, incrementing, and comparison operations.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import re
|
|
8
|
+
from typing import Tuple, Optional
|
|
9
|
+
from pathlib import Path
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
class VersionManager:
|
|
13
|
+
"""Manages version numbering for framework CLAUDE.md templates."""
|
|
14
|
+
|
|
15
|
+
def __init__(self):
|
|
16
|
+
"""Initialize version manager."""
|
|
17
|
+
self.framework_version = self._get_framework_version()
|
|
18
|
+
|
|
19
|
+
def _get_framework_version(self) -> str:
|
|
20
|
+
"""
|
|
21
|
+
Get the current framework version from framework/VERSION file.
|
|
22
|
+
|
|
23
|
+
Returns:
|
|
24
|
+
str: Framework version (e.g., "015")
|
|
25
|
+
"""
|
|
26
|
+
# Check if we're in a wheel installation
|
|
27
|
+
package_path = Path(__file__).parent.parent.parent
|
|
28
|
+
path_str = str(package_path.resolve())
|
|
29
|
+
if 'site-packages' in path_str or 'dist-packages' in path_str:
|
|
30
|
+
# For wheel installations, check data directory
|
|
31
|
+
version_path = package_path / "data" / "framework" / "VERSION"
|
|
32
|
+
if not version_path.exists():
|
|
33
|
+
# Try package root as fallback
|
|
34
|
+
version_path = package_path.parent / "framework" / "VERSION"
|
|
35
|
+
else:
|
|
36
|
+
# Source installation
|
|
37
|
+
version_path = package_path.parent / "framework" / "VERSION"
|
|
38
|
+
|
|
39
|
+
if version_path.exists():
|
|
40
|
+
with open(version_path, 'r') as f:
|
|
41
|
+
version_content = f.read().strip()
|
|
42
|
+
# Framework VERSION file contains just the framework version number
|
|
43
|
+
try:
|
|
44
|
+
return f"{int(version_content):03d}"
|
|
45
|
+
except ValueError:
|
|
46
|
+
# If not a plain number, try to extract from version string
|
|
47
|
+
match = re.match(r'(\d+)', version_content)
|
|
48
|
+
if match:
|
|
49
|
+
return f"{int(match.group(1)):03d}"
|
|
50
|
+
return "014" # Default fallback
|
|
51
|
+
|
|
52
|
+
def parse_current_version(self, content: str) -> str:
|
|
53
|
+
"""
|
|
54
|
+
Parse the current CLAUDE_MD_VERSION from existing content.
|
|
55
|
+
|
|
56
|
+
Args:
|
|
57
|
+
content: Existing CLAUDE.md content
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
str: Version number (e.g., "016")
|
|
61
|
+
"""
|
|
62
|
+
# First try simple serial format
|
|
63
|
+
match = re.search(r'CLAUDE_MD_VERSION:\s*(\d+)(?!-)', content)
|
|
64
|
+
if match:
|
|
65
|
+
return match.group(1)
|
|
66
|
+
|
|
67
|
+
# Handle old format for backward compatibility
|
|
68
|
+
match = re.search(r'CLAUDE_MD_VERSION:\s*(\d+)-(\d+)', content)
|
|
69
|
+
if match:
|
|
70
|
+
return match.group(1) # Return just the framework part
|
|
71
|
+
|
|
72
|
+
return self.framework_version
|
|
73
|
+
|
|
74
|
+
def auto_increment_version(self, current_content: Optional[str] = None) -> str:
|
|
75
|
+
"""
|
|
76
|
+
Get the current framework version (no auto-increment for simple serial numbers).
|
|
77
|
+
|
|
78
|
+
Args:
|
|
79
|
+
current_content: Current CLAUDE.md content (unused with simple serials)
|
|
80
|
+
|
|
81
|
+
Returns:
|
|
82
|
+
str: Current framework version (e.g., "016")
|
|
83
|
+
"""
|
|
84
|
+
# With simple serial numbers, we just use the framework version
|
|
85
|
+
# Incrementing is done by updating the framework/VERSION file
|
|
86
|
+
return self.framework_version
|
|
87
|
+
|
|
88
|
+
def compare_versions(self, version1: str, version2: str) -> int:
|
|
89
|
+
"""
|
|
90
|
+
Compare two version strings.
|
|
91
|
+
|
|
92
|
+
Args:
|
|
93
|
+
version1: First version string (e.g., "016")
|
|
94
|
+
version2: Second version string (e.g., "017")
|
|
95
|
+
|
|
96
|
+
Returns:
|
|
97
|
+
int: -1 if version1 < version2, 0 if equal, 1 if version1 > version2
|
|
98
|
+
"""
|
|
99
|
+
def parse_version(v: str) -> int:
|
|
100
|
+
# Handle simple serial format
|
|
101
|
+
if '-' not in v:
|
|
102
|
+
try:
|
|
103
|
+
return int(v)
|
|
104
|
+
except ValueError:
|
|
105
|
+
return 0
|
|
106
|
+
|
|
107
|
+
# Handle old format for backward compatibility
|
|
108
|
+
match = re.match(r'(\d+)-(\d+)', v)
|
|
109
|
+
if match:
|
|
110
|
+
return int(match.group(1)) # Just compare framework part
|
|
111
|
+
return 0
|
|
112
|
+
|
|
113
|
+
v1 = parse_version(version1)
|
|
114
|
+
v2 = parse_version(version2)
|
|
115
|
+
|
|
116
|
+
if v1 < v2:
|
|
117
|
+
return -1
|
|
118
|
+
elif v1 > v2:
|
|
119
|
+
return 1
|
|
120
|
+
else:
|
|
121
|
+
return 0
|