feat: implement comprehensive capability inclusion management system
Added systematic approach to manage capability inclusion via subrepos and prevent code duplication. This addresses the architectural challenge of ensuring Claude recognizes, uses, and respects included capabilities. New Capability Management System: - CAPABILITY_REGISTRY.md: Complete registry of all included capabilities - CLAUDE_CAPABILITY_REFERENCE.md: Quick lookup guide for Claude to prevent duplication - tools/capability_discovery.py: Automated discovery and validation tool - Makefile targets: capability-report, capability-search, capability-validate Registry Coverage: - Submodule capabilities: issue-facade (universal issue tracking), wiki (documentation) - Local capabilities: markitect-content (content parsing), markitect-utils (utilities) - External dependencies: Click, pytest, SQLAlchemy, requests Agent Integration: - Updated project-management and tdd-workflow agents with capability awareness - Clear guidelines for checking existing functionality before implementing - Integration patterns for using capabilities properly Discovery & Validation: - Automated capability discovery across submodules and local directories - Search functionality to find existing implementations - Validation tools to detect potential code duplication - Claude-readable interfaces and usage patterns Benefits: - Prevents accidental functionality duplication - Ensures proper separation of concerns - Provides easy capability extension and bugfixing - Maintains clean interfaces between core and capabilities - Guides Claude to use existing capabilities efficiently Usage: - make capability-report: Generate complete capability overview - make capability-search TERM=xyz: Find existing implementations - make capability-validate FILE=path: Check for proper capability usage 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
200
CAPABILITY_REGISTRY.md
Normal file
200
CAPABILITY_REGISTRY.md
Normal file
@@ -0,0 +1,200 @@
|
||||
# MarkiTect Capability Registry
|
||||
|
||||
> **Unified registry for all included capabilities to prevent code duplication and ensure proper separation of concerns**
|
||||
|
||||
## Overview
|
||||
|
||||
This registry documents all capabilities included in the MarkiTect project, whether as git submodules, local capabilities, or external dependencies. It serves as the authoritative source for Claude and developers to understand available functionality.
|
||||
|
||||
## Capability Inclusion Patterns
|
||||
|
||||
### 1. **Submodule Capabilities** (External Repositories)
|
||||
Full repositories included as git submodules for independent development and versioning.
|
||||
|
||||
### 2. **Local Capabilities** (Extracted Components)
|
||||
Self-contained capabilities extracted from the main codebase but maintained locally.
|
||||
|
||||
### 3. **External Dependencies** (Package Dependencies)
|
||||
Third-party packages providing specific capabilities via pip/pypi.
|
||||
|
||||
---
|
||||
|
||||
## 🔍 **ACTIVE CAPABILITIES REGISTRY**
|
||||
|
||||
### Universal Issue Management
|
||||
- **Type**: Submodule Capability
|
||||
- **Location**: `issue-facade/`
|
||||
- **Repository**: `coulomb/issue-facade`
|
||||
- **Purpose**: Backend-agnostic issue tracking with unified CLI
|
||||
- **Interfaces**:
|
||||
- CLI: `cd issue-facade && python -m cli.main [command]`
|
||||
- API: Core models, backends (local SQLite, Gitea, GitHub, GitLab)
|
||||
- **Usage Guidelines**:
|
||||
- ✅ **USE**: For all issue management tasks
|
||||
- ❌ **DON'T**: Implement custom issue tracking, duplicate CLI commands
|
||||
- 🔧 **Integration**: Reference submodule for issue operations
|
||||
|
||||
### Content Processing Capability
|
||||
- **Type**: Local Capability
|
||||
- **Location**: `capabilities/markitect-content/`
|
||||
- **Purpose**: MarkdownMatters content parsing without frontmatter/tailmatter
|
||||
- **Interfaces**:
|
||||
- `ContentParser` class for content extraction
|
||||
- `ContentStats` for document statistics
|
||||
- CLI commands for content operations
|
||||
- **Usage Guidelines**:
|
||||
- ✅ **USE**: For content extraction and analysis
|
||||
- ❌ **DON'T**: Reimplement markdown content parsing
|
||||
- 🔧 **Integration**: Import from `capabilities.markitect_content`
|
||||
|
||||
### Utility Functions Capability
|
||||
- **Type**: Local Capability
|
||||
- **Location**: `capabilities/markitect-utils/`
|
||||
- **Purpose**: Common utility functions and helpers
|
||||
- **Interfaces**: Shared utilities and helper functions
|
||||
- **Usage Guidelines**:
|
||||
- ✅ **USE**: For common operations and utilities
|
||||
- ❌ **DON'T**: Duplicate utility functions
|
||||
- 🔧 **Integration**: Import from `capabilities.markitect_utils`
|
||||
|
||||
### Documentation and Knowledge Base
|
||||
- **Type**: Submodule Capability
|
||||
- **Location**: `wiki/`
|
||||
- **Repository**: `coulomb/markitect_project.wiki`
|
||||
- **Purpose**: Comprehensive project documentation and knowledge base
|
||||
- **Interfaces**: Markdown documentation files
|
||||
- **Usage Guidelines**:
|
||||
- ✅ **USE**: For project documentation, architectural decisions
|
||||
- ❌ **DON'T**: Create duplicate documentation
|
||||
- 🔧 **Integration**: Reference wiki for authoritative documentation
|
||||
|
||||
---
|
||||
|
||||
## 🚫 **CAPABILITY CONFLICT PREVENTION**
|
||||
|
||||
### Before Implementing New Functionality:
|
||||
|
||||
1. **Check This Registry**: Verify no existing capability provides the functionality
|
||||
2. **Search Submodules**: Check `issue-facade/`, `wiki/` for existing solutions
|
||||
3. **Check Local Capabilities**: Review `capabilities/` directory
|
||||
4. **Consult Documentation**: Check capability READMEs for interface details
|
||||
|
||||
### Implementation Guidelines:
|
||||
|
||||
- **Extend, Don't Duplicate**: If functionality exists, extend or interface with it
|
||||
- **Clear Boundaries**: New code should complement, not replace, existing capabilities
|
||||
- **Interface Respect**: Use documented interfaces rather than reimplementing
|
||||
- **Separation of Concerns**: Maintain clear boundaries between core MarkiTect and capabilities
|
||||
|
||||
---
|
||||
|
||||
## 🔧 **INTEGRATION PATTERNS**
|
||||
|
||||
### Submodule Integration
|
||||
```bash
|
||||
# Issue management
|
||||
cd issue-facade && python -m cli.main list
|
||||
|
||||
# Documentation updates
|
||||
cd wiki && git pull origin main
|
||||
```
|
||||
|
||||
### Local Capability Integration
|
||||
```python
|
||||
# Content processing
|
||||
from capabilities.markitect_content import ContentParser
|
||||
parser = ContentParser()
|
||||
|
||||
# Utilities
|
||||
from capabilities.markitect_utils import helper_function
|
||||
```
|
||||
|
||||
### External Dependency Integration
|
||||
```python
|
||||
# Standard package imports
|
||||
import click # CLI framework
|
||||
import pytest # Testing framework
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 📋 **CLAUDE USAGE GUIDELINES**
|
||||
|
||||
### When Asked to Implement Functionality:
|
||||
|
||||
1. **First**: Check this registry for existing capabilities
|
||||
2. **If Exists**: Use/extend the existing capability rather than reimplementing
|
||||
3. **If Missing**: Implement new functionality with clear separation from existing capabilities
|
||||
4. **Document**: Update this registry when adding new capabilities
|
||||
|
||||
### Capability Respect Rules:
|
||||
|
||||
- **Issue Management**: Always use `issue-facade` submodule, never implement custom issue tracking
|
||||
- **Content Processing**: Use `markitect-content` capability for MarkdownMatters parsing
|
||||
- **Documentation**: Reference `wiki` submodule for authoritative project information
|
||||
- **Utilities**: Check `markitect-utils` before creating new utility functions
|
||||
|
||||
### Integration Commands:
|
||||
- **Issue Operations**: `cd issue-facade && python -m cli.main [command]`
|
||||
- **Content Analysis**: Import from `capabilities.markitect_content`
|
||||
- **Utility Functions**: Import from `capabilities.markitect_utils`
|
||||
- **Documentation**: Reference files in `wiki/`
|
||||
|
||||
---
|
||||
|
||||
## 🔄 **CAPABILITY LIFECYCLE MANAGEMENT**
|
||||
|
||||
### Adding New Capabilities
|
||||
|
||||
1. **Evaluate**: Does this warrant capability extraction?
|
||||
2. **Choose Pattern**: Submodule (external repo) vs Local capability vs External dependency
|
||||
3. **Implement**: Follow capability inclusion patterns
|
||||
4. **Document**: Update this registry with interface details
|
||||
5. **Update Agents**: Inform specialized agents of new capability
|
||||
|
||||
### Updating Existing Capabilities
|
||||
|
||||
1. **Submodules**: Update submodule reference (`git submodule update`)
|
||||
2. **Local Capabilities**: Update local code and interfaces
|
||||
3. **External Dependencies**: Update package versions in `pyproject.toml`
|
||||
4. **Registry**: Update interface documentation if changed
|
||||
|
||||
### Removing Capabilities
|
||||
|
||||
1. **Deprecation Notice**: Document deprecation timeline
|
||||
2. **Migration Path**: Provide alternative solutions
|
||||
3. **Remove References**: Update all code using the capability
|
||||
4. **Clean Registry**: Remove from this registry
|
||||
5. **Update Documentation**: Update all relevant documentation
|
||||
|
||||
---
|
||||
|
||||
## 📊 **CAPABILITY METRICS**
|
||||
|
||||
- **Total Capabilities**: 4 active capabilities
|
||||
- **Submodule Capabilities**: 2 (issue-facade, wiki)
|
||||
- **Local Capabilities**: 2 (markitect-content, markitect-utils)
|
||||
- **External Dependencies**: Multiple (see pyproject.toml)
|
||||
- **Coverage**: Issue management, content processing, utilities, documentation
|
||||
|
||||
---
|
||||
|
||||
## 🎯 **SUCCESS CRITERIA**
|
||||
|
||||
### For Developers:
|
||||
- [ ] Zero accidental functionality duplication
|
||||
- [ ] Clear interface boundaries respected
|
||||
- [ ] Efficient capability discovery and usage
|
||||
- [ ] Proper separation of concerns maintained
|
||||
|
||||
### For Claude:
|
||||
- [ ] Registry consulted before implementing new functionality
|
||||
- [ ] Existing capabilities used when available
|
||||
- [ ] Clear understanding of capability boundaries
|
||||
- [ ] Proper integration patterns followed
|
||||
|
||||
### For the Project:
|
||||
- [ ] Modular architecture maintained
|
||||
- [ ] Easy capability extension and bugfixing
|
||||
- [ ] Clean separation between core and capabilities
|
||||
- [ ] Scalable capability inclusion patterns
|
||||
135
CLAUDE_CAPABILITY_REFERENCE.md
Normal file
135
CLAUDE_CAPABILITY_REFERENCE.md
Normal file
@@ -0,0 +1,135 @@
|
||||
# Claude Capability Reference - Quick Lookup
|
||||
|
||||
> **Essential reference for Claude to prevent code duplication and ensure proper capability usage**
|
||||
|
||||
## 🚨 **BEFORE IMPLEMENTING: CHECK EXISTING CAPABILITIES**
|
||||
|
||||
### Issue Management ➜ USE `issue-facade/`
|
||||
```bash
|
||||
# ✅ DO: Use existing issue facade
|
||||
cd issue-facade && python -m cli.main list
|
||||
cd issue-facade && python -m cli.main show 42
|
||||
cd issue-facade && python -m cli.main create "Title" "Description"
|
||||
|
||||
# ❌ DON'T: Implement custom issue tracking
|
||||
# ❌ DON'T: Create new CLI commands for issues
|
||||
# ❌ DON'T: Build custom Gitea/GitHub API clients
|
||||
```
|
||||
|
||||
### Content Processing ➜ USE `capabilities/markitect-content/`
|
||||
```python
|
||||
# ✅ DO: Use existing content capability
|
||||
from capabilities.markitect_content import ContentParser, ContentStats
|
||||
parser = ContentParser()
|
||||
stats = ContentStats()
|
||||
|
||||
# ❌ DON'T: Reimplement markdown parsing
|
||||
# ❌ DON'T: Create new content statistics functions
|
||||
# ❌ DON'T: Duplicate frontmatter/tailmatter handling
|
||||
```
|
||||
|
||||
### Utilities ➜ USE `capabilities/markitect-utils/`
|
||||
```python
|
||||
# ✅ DO: Use existing utilities
|
||||
from capabilities.markitect_utils import utility_function
|
||||
|
||||
# ❌ DON'T: Recreate common utility functions
|
||||
# ❌ DON'T: Duplicate helper functions
|
||||
```
|
||||
|
||||
### Documentation ➜ USE `wiki/`
|
||||
```markdown
|
||||
# ✅ DO: Reference existing documentation
|
||||
See wiki/ComposableRepositoryParadigm.md
|
||||
See wiki/MarkdownMatters.md
|
||||
|
||||
# ❌ DON'T: Create duplicate documentation
|
||||
# ❌ DON'T: Rewrite architectural decisions
|
||||
```
|
||||
|
||||
## 🔍 **CAPABILITY DISCOVERY COMMANDS**
|
||||
|
||||
### Quick Capability Check
|
||||
```bash
|
||||
# Check all capabilities
|
||||
ls -la capabilities/ # Local capabilities
|
||||
ls -la issue-facade/ # Issue management capability
|
||||
ls -la wiki/ # Documentation capability
|
||||
cat CAPABILITY_REGISTRY.md # Full registry
|
||||
|
||||
# Verify functionality exists
|
||||
grep -r "function_name" capabilities/
|
||||
grep -r "class_name" issue-facade/
|
||||
```
|
||||
|
||||
### Interface Documentation
|
||||
- **Issue Facade**: `issue-facade/README.md`
|
||||
- **Content Processing**: `capabilities/markitect-content/README.md`
|
||||
- **Utilities**: `capabilities/markitect-utils/README.md`
|
||||
- **Documentation**: `wiki/` (multiple files)
|
||||
|
||||
## ⚡ **QUICK DECISION TREE**
|
||||
|
||||
1. **Need Issue Management?** ➜ Use `issue-facade/`
|
||||
2. **Need Content Parsing?** ➜ Use `capabilities/markitect-content/`
|
||||
3. **Need Utility Functions?** ➜ Check `capabilities/markitect-utils/`
|
||||
4. **Need Documentation?** ➜ Reference `wiki/`
|
||||
5. **Something New?** ➜ Check `CAPABILITY_REGISTRY.md` first
|
||||
|
||||
## 🎯 **CLAUDE IMPLEMENTATION RULES**
|
||||
|
||||
### Rule 1: Registry First
|
||||
- **Always check** `CAPABILITY_REGISTRY.md` before implementing
|
||||
- **Search existing** capabilities for similar functionality
|
||||
- **Extend, don't duplicate** existing capabilities
|
||||
|
||||
### Rule 2: Use Documented Interfaces
|
||||
- **Follow interface patterns** documented in capability READMEs
|
||||
- **Use provided CLI commands** rather than reimplementing
|
||||
- **Import from documented modules** rather than copying code
|
||||
|
||||
### Rule 3: Maintain Separation
|
||||
- **Core MarkiTect**: Focus on markdown processing and database operations
|
||||
- **Capabilities**: Use for specialized functionality (issues, content, utils)
|
||||
- **Clear boundaries**: Don't mix core and capability concerns
|
||||
|
||||
### Rule 4: Update Registry
|
||||
- **When adding capabilities**: Update `CAPABILITY_REGISTRY.md`
|
||||
- **When changing interfaces**: Update documentation
|
||||
- **When removing capabilities**: Clean up references
|
||||
|
||||
## 📋 **COMMON INTEGRATION PATTERNS**
|
||||
|
||||
### Submodule Usage
|
||||
```bash
|
||||
# Issue management via submodule
|
||||
cd issue-facade && python -m cli.main [command]
|
||||
|
||||
# Update submodule
|
||||
git submodule update --remote issue-facade
|
||||
```
|
||||
|
||||
### Local Capability Usage
|
||||
```python
|
||||
# Content processing
|
||||
from capabilities.markitect_content import ContentParser
|
||||
|
||||
# Utilities
|
||||
from capabilities.markitect_utils import helper_function
|
||||
```
|
||||
|
||||
### Error Prevention
|
||||
```python
|
||||
# ❌ BAD: Duplicating functionality
|
||||
def create_issue(title, body):
|
||||
# Custom implementation
|
||||
|
||||
# ✅ GOOD: Using existing capability
|
||||
import subprocess
|
||||
result = subprocess.run(['python', '-m', 'cli.main', 'create', title, body],
|
||||
cwd='issue-facade')
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**💡 Remember: When in doubt, check the registry first!**
|
||||
26
Makefile
26
Makefile
@@ -86,6 +86,11 @@ help:
|
||||
@echo " update-digest - Update ProjectStatusDigest.md (requires Claude Code)"
|
||||
@echo " add-diary-entry - Add new entry to ProjectDiary.md (requires Claude Code)"
|
||||
@echo ""
|
||||
@echo "Capability Management:"
|
||||
@echo " capability-report - Generate capability discovery report"
|
||||
@echo " capability-search TERM=xyz - Search for functionality across capabilities"
|
||||
@echo " capability-validate FILE=path - Validate proper capability usage in file"
|
||||
@echo ""
|
||||
@echo ""
|
||||
@echo "Requirements Engineering:"
|
||||
@echo " validate-requirements - Analyze foundations before development"
|
||||
@@ -545,6 +550,27 @@ add-diary-entry:
|
||||
@echo ""
|
||||
@echo "💡 Tip: New entries are added to the top for reverse chronological order"
|
||||
|
||||
# Capability discovery and management targets
|
||||
capability-report: $(VENV)/bin/activate
|
||||
@echo "📋 Generating capability discovery report..."
|
||||
@$(VENV_PYTHON) tools/capability_discovery.py report
|
||||
|
||||
capability-search: $(VENV)/bin/activate
|
||||
@if [ -z "$(TERM)" ]; then \
|
||||
echo "❌ Please specify search term: make capability-search TERM=issue_management"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "🔍 Searching for '$(TERM)' across capabilities..."
|
||||
@$(VENV_PYTHON) tools/capability_discovery.py search "$(TERM)"
|
||||
|
||||
capability-validate: $(VENV)/bin/activate
|
||||
@if [ -z "$(FILE)" ]; then \
|
||||
echo "❌ Please specify file path: make capability-validate FILE=path/to/file.py"; \
|
||||
exit 1; \
|
||||
fi
|
||||
@echo "✅ Validating capability usage in $(FILE)..."
|
||||
@$(VENV_PYTHON) tools/capability_discovery.py validate "$(FILE)"
|
||||
|
||||
# Git repository and API configuration
|
||||
GITEA_URL := http://92.205.130.254:32166
|
||||
|
||||
|
||||
@@ -33,6 +33,11 @@ You are the MarkiTect project assistant, specialized in providing project status
|
||||
- Issue management via universal issue-facade CLI that works with multiple backends
|
||||
- All commits require green test state
|
||||
|
||||
**Capability Inclusion Management:**
|
||||
- Before implementing: Check `CAPABILITY_REGISTRY.md` for existing functionality
|
||||
- Use `CLAUDE_CAPABILITY_REFERENCE.md` for quick capability lookup
|
||||
- Respect capability boundaries to prevent code duplication
|
||||
|
||||
**Issue Management Protocol:**
|
||||
- **Gitea-First**: Feature requests, bugs, and enhancements should be documented as Gitea issues
|
||||
- **Issue Creation**: When new requirements emerge, create issues in Gitea immediately but do NOT implement immediately
|
||||
|
||||
@@ -104,6 +104,11 @@ You are the authoritative guide for the TDD8 workflow using the issue-facade sys
|
||||
- `cd issue-facade && python -m cli.main create "Title" "Description"` - Create new issue
|
||||
- `cd issue-facade && python -m cli.main close ISSUE_NUM` - Close completed issue
|
||||
|
||||
**Capability Awareness:**
|
||||
- **Before implementing**: Check `CAPABILITY_REGISTRY.md` for existing functionality
|
||||
- **Use existing capabilities**: Never reimplement issue management, content parsing, or utilities
|
||||
- **Capability discovery**: Use `make capability-search TERM=function_name` to find existing implementations
|
||||
|
||||
**Supporting Commands:**
|
||||
- `make test-coverage` - Analyze test coverage
|
||||
- `make test` - Run all tests
|
||||
|
||||
292
tools/capability_discovery.py
Executable file
292
tools/capability_discovery.py
Executable file
@@ -0,0 +1,292 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Capability Discovery Tool
|
||||
|
||||
Provides automated discovery and validation of included capabilities
|
||||
to prevent code duplication and ensure proper capability usage.
|
||||
"""
|
||||
|
||||
import os
|
||||
import json
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
from typing import Dict, List, Optional, Tuple
|
||||
|
||||
|
||||
class CapabilityDiscovery:
|
||||
"""Tool for discovering and validating included capabilities."""
|
||||
|
||||
def __init__(self, project_root: str = "."):
|
||||
self.project_root = Path(project_root).resolve()
|
||||
self.capabilities = {}
|
||||
self._discover_capabilities()
|
||||
|
||||
def _discover_capabilities(self):
|
||||
"""Discover all available capabilities."""
|
||||
# Submodule capabilities
|
||||
self._discover_submodules()
|
||||
|
||||
# Local capabilities
|
||||
self._discover_local_capabilities()
|
||||
|
||||
# External dependencies
|
||||
self._discover_external_dependencies()
|
||||
|
||||
def _discover_submodules(self):
|
||||
"""Discover git submodule capabilities."""
|
||||
gitmodules_path = self.project_root / ".gitmodules"
|
||||
if not gitmodules_path.exists():
|
||||
return
|
||||
|
||||
with open(gitmodules_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Parse submodules
|
||||
submodules = []
|
||||
current_submodule = {}
|
||||
|
||||
for line in content.split('\n'):
|
||||
line = line.strip()
|
||||
if line.startswith('[submodule'):
|
||||
if current_submodule:
|
||||
submodules.append(current_submodule)
|
||||
current_submodule = {'name': line.split('"')[1]}
|
||||
elif '=' in line and current_submodule:
|
||||
key, value = line.split('=', 1)
|
||||
current_submodule[key.strip()] = value.strip()
|
||||
|
||||
if current_submodule:
|
||||
submodules.append(current_submodule)
|
||||
|
||||
# Add to capabilities
|
||||
for submodule in submodules:
|
||||
path = submodule.get('path', '')
|
||||
if path:
|
||||
self.capabilities[path] = {
|
||||
'type': 'submodule',
|
||||
'name': submodule['name'],
|
||||
'path': path,
|
||||
'url': submodule.get('url', ''),
|
||||
'status': self._check_submodule_status(path)
|
||||
}
|
||||
|
||||
def _discover_local_capabilities(self):
|
||||
"""Discover local capability directories."""
|
||||
capabilities_dir = self.project_root / "capabilities"
|
||||
if not capabilities_dir.exists():
|
||||
return
|
||||
|
||||
for cap_dir in capabilities_dir.iterdir():
|
||||
if cap_dir.is_dir() and not cap_dir.name.startswith('.'):
|
||||
readme_path = cap_dir / "README.md"
|
||||
self.capabilities[f"capabilities/{cap_dir.name}"] = {
|
||||
'type': 'local',
|
||||
'name': cap_dir.name,
|
||||
'path': f"capabilities/{cap_dir.name}",
|
||||
'has_readme': readme_path.exists(),
|
||||
'status': 'available'
|
||||
}
|
||||
|
||||
def _discover_external_dependencies(self):
|
||||
"""Discover external package dependencies."""
|
||||
pyproject_path = self.project_root / "pyproject.toml"
|
||||
if not pyproject_path.exists():
|
||||
return
|
||||
|
||||
# Basic parsing of dependencies (could be enhanced with toml library)
|
||||
with open(pyproject_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Extract key dependencies
|
||||
key_deps = ['click', 'pytest', 'sqlalchemy', 'requests']
|
||||
for dep in key_deps:
|
||||
if dep in content:
|
||||
self.capabilities[f"external/{dep}"] = {
|
||||
'type': 'external',
|
||||
'name': dep,
|
||||
'path': f"external/{dep}",
|
||||
'status': 'package_dependency'
|
||||
}
|
||||
|
||||
def _check_submodule_status(self, path: str) -> str:
|
||||
"""Check if submodule is properly initialized."""
|
||||
submodule_path = self.project_root / path
|
||||
|
||||
if not submodule_path.exists():
|
||||
return 'missing'
|
||||
|
||||
# Check if it's an empty directory
|
||||
if submodule_path.is_dir() and not any(submodule_path.iterdir()):
|
||||
return 'uninitialized'
|
||||
|
||||
return 'available'
|
||||
|
||||
def get_capability_info(self, name: str) -> Optional[Dict]:
|
||||
"""Get information about a specific capability."""
|
||||
for cap_path, info in self.capabilities.items():
|
||||
if info['name'] == name or cap_path == name:
|
||||
return info
|
||||
return None
|
||||
|
||||
def search_functionality(self, search_term: str) -> List[Tuple[str, str]]:
|
||||
"""Search for functionality across capabilities."""
|
||||
results = []
|
||||
|
||||
for cap_path, info in self.capabilities.items():
|
||||
if info['type'] == 'submodule' and info['status'] == 'available':
|
||||
results.extend(self._search_in_submodule(cap_path, search_term))
|
||||
elif info['type'] == 'local':
|
||||
results.extend(self._search_in_local_capability(cap_path, search_term))
|
||||
|
||||
return results
|
||||
|
||||
def _search_in_submodule(self, path: str, search_term: str) -> List[Tuple[str, str]]:
|
||||
"""Search for functionality in a submodule."""
|
||||
results = []
|
||||
submodule_path = self.project_root / path
|
||||
|
||||
if not submodule_path.exists():
|
||||
return results
|
||||
|
||||
# Search README files
|
||||
for readme in submodule_path.glob("**/README.md"):
|
||||
try:
|
||||
with open(readme, 'r') as f:
|
||||
content = f.read().lower()
|
||||
if search_term.lower() in content:
|
||||
results.append((path, f"README: {readme.relative_to(submodule_path)}"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Search Python files for functions/classes
|
||||
for py_file in submodule_path.glob("**/*.py"):
|
||||
try:
|
||||
with open(py_file, 'r') as f:
|
||||
content = f.read()
|
||||
if search_term in content:
|
||||
results.append((path, f"Code: {py_file.relative_to(submodule_path)}"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return results
|
||||
|
||||
def _search_in_local_capability(self, path: str, search_term: str) -> List[Tuple[str, str]]:
|
||||
"""Search for functionality in a local capability."""
|
||||
results = []
|
||||
cap_path = self.project_root / path
|
||||
|
||||
if not cap_path.exists():
|
||||
return results
|
||||
|
||||
# Search Python files
|
||||
for py_file in cap_path.glob("**/*.py"):
|
||||
try:
|
||||
with open(py_file, 'r') as f:
|
||||
content = f.read()
|
||||
if search_term in content:
|
||||
results.append((path, f"Code: {py_file.relative_to(cap_path)}"))
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
return results
|
||||
|
||||
def generate_report(self) -> str:
|
||||
"""Generate a capability discovery report."""
|
||||
report = ["# Capability Discovery Report", ""]
|
||||
|
||||
# Summary
|
||||
total_caps = len(self.capabilities)
|
||||
submodules = len([c for c in self.capabilities.values() if c['type'] == 'submodule'])
|
||||
local = len([c for c in self.capabilities.values() if c['type'] == 'local'])
|
||||
external = len([c for c in self.capabilities.values() if c['type'] == 'external'])
|
||||
|
||||
report.extend([
|
||||
f"**Total Capabilities**: {total_caps}",
|
||||
f"- Submodules: {submodules}",
|
||||
f"- Local: {local}",
|
||||
f"- External: {external}",
|
||||
""
|
||||
])
|
||||
|
||||
# Details by type
|
||||
for cap_type in ['submodule', 'local', 'external']:
|
||||
caps_of_type = {k: v for k, v in self.capabilities.items() if v['type'] == cap_type}
|
||||
if caps_of_type:
|
||||
report.append(f"## {cap_type.title()} Capabilities")
|
||||
for path, info in caps_of_type.items():
|
||||
status_emoji = "✅" if info['status'] == 'available' else "❌"
|
||||
report.append(f"- {status_emoji} **{info['name']}** (`{path}`) - {info['status']}")
|
||||
report.append("")
|
||||
|
||||
return '\n'.join(report)
|
||||
|
||||
def validate_capability_usage(self, file_path: str) -> List[str]:
|
||||
"""Validate that a file properly uses existing capabilities."""
|
||||
warnings = []
|
||||
|
||||
if not Path(file_path).exists():
|
||||
return ["File not found"]
|
||||
|
||||
with open(file_path, 'r') as f:
|
||||
content = f.read()
|
||||
|
||||
# Check for potential duplication
|
||||
duplication_patterns = {
|
||||
'issue management': ['create_issue', 'list_issues', 'close_issue'],
|
||||
'content parsing': ['parse_markdown', 'extract_content', 'ContentParser'],
|
||||
'utilities': ['helper_function', 'utility_function']
|
||||
}
|
||||
|
||||
for capability, patterns in duplication_patterns.items():
|
||||
for pattern in patterns:
|
||||
if pattern in content:
|
||||
# Check if proper capability import is used
|
||||
if capability == 'issue management' and 'issue-facade' not in content:
|
||||
warnings.append(f"Potential issue management duplication: {pattern} found but no issue-facade usage")
|
||||
elif capability == 'content parsing' and 'markitect_content' not in content:
|
||||
warnings.append(f"Potential content parsing duplication: {pattern} found but no markitect-content usage")
|
||||
|
||||
return warnings
|
||||
|
||||
|
||||
def main():
|
||||
"""CLI interface for capability discovery."""
|
||||
import sys
|
||||
|
||||
discovery = CapabilityDiscovery()
|
||||
|
||||
if len(sys.argv) < 2:
|
||||
print("Usage: capability_discovery.py [report|search|validate] [args...]")
|
||||
return
|
||||
|
||||
command = sys.argv[1]
|
||||
|
||||
if command == "report":
|
||||
print(discovery.generate_report())
|
||||
|
||||
elif command == "search" and len(sys.argv) > 2:
|
||||
search_term = sys.argv[2]
|
||||
results = discovery.search_functionality(search_term)
|
||||
if results:
|
||||
print(f"Found '{search_term}' in:")
|
||||
for cap, location in results:
|
||||
print(f" - {cap}: {location}")
|
||||
else:
|
||||
print(f"No results found for '{search_term}'")
|
||||
|
||||
elif command == "validate" and len(sys.argv) > 2:
|
||||
file_path = sys.argv[2]
|
||||
warnings = discovery.validate_capability_usage(file_path)
|
||||
if warnings:
|
||||
print("Validation warnings:")
|
||||
for warning in warnings:
|
||||
print(f" ⚠️ {warning}")
|
||||
else:
|
||||
print("✅ No capability usage issues found")
|
||||
|
||||
else:
|
||||
print("Invalid command or missing arguments")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user