mirror of
https://github.com/SuperClaude-Org/SuperClaude_Framework.git
synced 2025-12-29 16:16:08 +00:00
622 lines
21 KiB
Markdown
622 lines
21 KiB
Markdown
|
|
# yaml_loader.py - Unified Configuration Management System
|
||
|
|
|
||
|
|
## Overview
|
||
|
|
|
||
|
|
The `yaml_loader.py` module provides unified configuration loading with support for both JSON and YAML formats, featuring intelligent caching, hot-reload capabilities, and comprehensive error handling. It serves as the central configuration management system for all SuperClaude hooks, supporting Claude Code settings.json, SuperClaude superclaude-config.json, and YAML configuration files.
|
||
|
|
|
||
|
|
## Purpose and Responsibilities
|
||
|
|
|
||
|
|
### Primary Functions
|
||
|
|
- **Dual-Format Support**: JSON (Claude Code + SuperClaude) and YAML configuration handling
|
||
|
|
- **Intelligent Caching**: Sub-10ms configuration access with file modification detection
|
||
|
|
- **Hot-Reload Capability**: Automatic detection and reload of configuration changes
|
||
|
|
- **Environment Interpolation**: ${VAR} and ${VAR:default} syntax support for dynamic configuration
|
||
|
|
- **Modular Configuration**: Include/merge support for complex deployment scenarios
|
||
|
|
|
||
|
|
### Performance Characteristics
|
||
|
|
- **Sub-10ms Access**: Cached configuration retrieval for optimal hook performance
|
||
|
|
- **<50ms Reload**: Configuration file reload when changes detected
|
||
|
|
- **1-Second Check Interval**: Rate-limited file modification checks for efficiency
|
||
|
|
- **Comprehensive Error Handling**: Graceful degradation with fallback configurations
|
||
|
|
|
||
|
|
## Core Architecture
|
||
|
|
|
||
|
|
### UnifiedConfigLoader Class
|
||
|
|
```python
|
||
|
|
class UnifiedConfigLoader:
|
||
|
|
"""
|
||
|
|
Intelligent configuration loader with support for JSON and YAML formats.
|
||
|
|
|
||
|
|
Features:
|
||
|
|
- Dual-configuration support (Claude Code + SuperClaude)
|
||
|
|
- File modification detection for hot-reload
|
||
|
|
- In-memory caching for performance (<10ms access)
|
||
|
|
- Comprehensive error handling and validation
|
||
|
|
- Environment variable interpolation
|
||
|
|
- Include/merge support for modular configs
|
||
|
|
- Unified configuration interface
|
||
|
|
"""
|
||
|
|
```
|
||
|
|
|
||
|
|
### Configuration Source Registry
|
||
|
|
```python
|
||
|
|
def __init__(self, project_root: Union[str, Path]):
|
||
|
|
self.project_root = Path(project_root)
|
||
|
|
self.config_dir = self.project_root / "config"
|
||
|
|
|
||
|
|
# Configuration file paths
|
||
|
|
self.claude_settings_path = self.project_root / "settings.json"
|
||
|
|
self.superclaude_config_path = self.project_root / "superclaude-config.json"
|
||
|
|
|
||
|
|
# Configuration source registry
|
||
|
|
self._config_sources = {
|
||
|
|
'claude_settings': self.claude_settings_path,
|
||
|
|
'superclaude_config': self.superclaude_config_path
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
**Supported Configuration Sources**:
|
||
|
|
- **claude_settings**: Claude Code settings.json file
|
||
|
|
- **superclaude_config**: SuperClaude superclaude-config.json file
|
||
|
|
- **YAML Files**: config/*.yaml files for modular configuration
|
||
|
|
|
||
|
|
## Intelligent Caching System
|
||
|
|
|
||
|
|
### Cache Structure
|
||
|
|
```python
|
||
|
|
# Cache for all configuration sources
|
||
|
|
self._cache: Dict[str, Dict[str, Any]] = {}
|
||
|
|
self._file_hashes: Dict[str, str] = {}
|
||
|
|
self._last_check: Dict[str, float] = {}
|
||
|
|
self.check_interval = 1.0 # Check files every 1 second max
|
||
|
|
```
|
||
|
|
|
||
|
|
### Cache Validation
|
||
|
|
```python
|
||
|
|
def _should_use_cache(self, config_name: str, config_path: Path) -> bool:
|
||
|
|
if config_name not in self._cache:
|
||
|
|
return False
|
||
|
|
|
||
|
|
# Rate limit file checks
|
||
|
|
now = time.time()
|
||
|
|
if now - self._last_check.get(config_name, 0) < self.check_interval:
|
||
|
|
return True
|
||
|
|
|
||
|
|
# Check if file changed
|
||
|
|
current_hash = self._compute_hash(config_path)
|
||
|
|
return current_hash == self._file_hashes.get(config_name)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Cache Invalidation Strategy**:
|
||
|
|
1. **Rate Limiting**: File checks limited to once per second per configuration
|
||
|
|
2. **Hash-Based Detection**: File modification detection using mtime and size hash
|
||
|
|
3. **Automatic Reload**: Cache invalidation triggers automatic configuration reload
|
||
|
|
4. **Memory Optimization**: Only cache active configurations to minimize memory usage
|
||
|
|
|
||
|
|
### File Change Detection
|
||
|
|
```python
|
||
|
|
def _compute_hash(self, file_path: Path) -> str:
|
||
|
|
"""Compute file hash for change detection."""
|
||
|
|
stat = file_path.stat()
|
||
|
|
return hashlib.md5(f"{stat.st_mtime}:{stat.st_size}".encode()).hexdigest()
|
||
|
|
```
|
||
|
|
|
||
|
|
**Hash Components**:
|
||
|
|
- **Modification Time**: File system mtime for change detection
|
||
|
|
- **File Size**: Content size changes for additional validation
|
||
|
|
- **MD5 Hash**: Combined hash for efficient comparison
|
||
|
|
|
||
|
|
## Configuration Loading Interface
|
||
|
|
|
||
|
|
### Primary Loading Method
|
||
|
|
```python
|
||
|
|
def load_config(self, config_name: str, force_reload: bool = False) -> Dict[str, Any]:
|
||
|
|
"""
|
||
|
|
Load configuration with intelligent caching (supports JSON and YAML).
|
||
|
|
|
||
|
|
Args:
|
||
|
|
config_name: Name of config file or special config identifier
|
||
|
|
- For YAML: config file name without .yaml extension
|
||
|
|
- For JSON: 'claude_settings' or 'superclaude_config'
|
||
|
|
force_reload: Force reload even if cached
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Parsed configuration dictionary
|
||
|
|
|
||
|
|
Raises:
|
||
|
|
FileNotFoundError: If config file doesn't exist
|
||
|
|
ValueError: If config parsing fails
|
||
|
|
"""
|
||
|
|
```
|
||
|
|
|
||
|
|
**Loading Logic**:
|
||
|
|
1. **Source Identification**: Determine if request is for JSON or YAML configuration
|
||
|
|
2. **Cache Validation**: Check if cached version is still valid
|
||
|
|
3. **File Loading**: Read and parse configuration file if reload needed
|
||
|
|
4. **Environment Interpolation**: Process ${VAR} and ${VAR:default} syntax
|
||
|
|
5. **Include Processing**: Handle __include__ directives for modular configuration
|
||
|
|
6. **Cache Update**: Store parsed configuration with metadata
|
||
|
|
|
||
|
|
### Specialized Access Methods
|
||
|
|
|
||
|
|
#### Section Access with Dot Notation
|
||
|
|
```python
|
||
|
|
def get_section(self, config_name: str, section_path: str, default: Any = None) -> Any:
|
||
|
|
"""
|
||
|
|
Get specific section from configuration using dot notation.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
config_name: Configuration file name or identifier
|
||
|
|
section_path: Dot-separated path (e.g., 'routing.ui_components')
|
||
|
|
default: Default value if section not found
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Configuration section value or default
|
||
|
|
"""
|
||
|
|
config = self.load_config(config_name)
|
||
|
|
|
||
|
|
try:
|
||
|
|
result = config
|
||
|
|
for key in section_path.split('.'):
|
||
|
|
result = result[key]
|
||
|
|
return result
|
||
|
|
except (KeyError, TypeError):
|
||
|
|
return default
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Hook-Specific Configuration
|
||
|
|
```python
|
||
|
|
def get_hook_config(self, hook_name: str, section_path: str = None, default: Any = None) -> Any:
|
||
|
|
"""
|
||
|
|
Get hook-specific configuration from SuperClaude config.
|
||
|
|
|
||
|
|
Args:
|
||
|
|
hook_name: Hook name (e.g., 'session_start', 'pre_tool_use')
|
||
|
|
section_path: Optional dot-separated path within hook config
|
||
|
|
default: Default value if not found
|
||
|
|
|
||
|
|
Returns:
|
||
|
|
Hook configuration or specific section
|
||
|
|
"""
|
||
|
|
base_path = f"hook_configurations.{hook_name}"
|
||
|
|
if section_path:
|
||
|
|
full_path = f"{base_path}.{section_path}"
|
||
|
|
else:
|
||
|
|
full_path = base_path
|
||
|
|
|
||
|
|
return self.get_section('superclaude_config', full_path, default)
|
||
|
|
```
|
||
|
|
|
||
|
|
#### Claude Code Integration
|
||
|
|
```python
|
||
|
|
def get_claude_hooks(self) -> Dict[str, Any]:
|
||
|
|
"""Get Claude Code hook definitions from settings.json."""
|
||
|
|
return self.get_section('claude_settings', 'hooks', {})
|
||
|
|
|
||
|
|
def get_superclaude_config(self, section_path: str = None, default: Any = None) -> Any:
|
||
|
|
"""Get SuperClaude framework configuration."""
|
||
|
|
if section_path:
|
||
|
|
return self.get_section('superclaude_config', section_path, default)
|
||
|
|
else:
|
||
|
|
return self.load_config('superclaude_config')
|
||
|
|
```
|
||
|
|
|
||
|
|
#### MCP Server Configuration
|
||
|
|
```python
|
||
|
|
def get_mcp_server_config(self, server_name: str = None) -> Dict[str, Any]:
|
||
|
|
"""Get MCP server configuration."""
|
||
|
|
if server_name:
|
||
|
|
return self.get_section('superclaude_config', f'mcp_server_integration.servers.{server_name}', {})
|
||
|
|
else:
|
||
|
|
return self.get_section('superclaude_config', 'mcp_server_integration', {})
|
||
|
|
|
||
|
|
def get_performance_targets(self) -> Dict[str, Any]:
|
||
|
|
"""Get performance targets for all components."""
|
||
|
|
return self.get_section('superclaude_config', 'global_configuration.performance_monitoring', {})
|
||
|
|
```
|
||
|
|
|
||
|
|
## Environment Variable Interpolation
|
||
|
|
|
||
|
|
### Interpolation Processing
|
||
|
|
```python
|
||
|
|
def _interpolate_env_vars(self, content: str) -> str:
|
||
|
|
"""Replace environment variables in YAML content."""
|
||
|
|
import re
|
||
|
|
|
||
|
|
def replace_env_var(match):
|
||
|
|
var_name = match.group(1)
|
||
|
|
default_value = match.group(2) if match.group(2) else ""
|
||
|
|
return os.getenv(var_name, default_value)
|
||
|
|
|
||
|
|
# Support ${VAR} and ${VAR:default} syntax
|
||
|
|
pattern = r'\$\{([^}:]+)(?::([^}]*))?\}'
|
||
|
|
return re.sub(pattern, replace_env_var, content)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Supported Syntax**:
|
||
|
|
- **${VAR_NAME}**: Replace with environment variable value or empty string
|
||
|
|
- **${VAR_NAME:default_value}**: Replace with environment variable or default value
|
||
|
|
- **Nested Variables**: Support for complex environment variable combinations
|
||
|
|
|
||
|
|
### Usage Examples
|
||
|
|
```yaml
|
||
|
|
# Configuration with environment interpolation
|
||
|
|
database:
|
||
|
|
host: ${DB_HOST:localhost}
|
||
|
|
port: ${DB_PORT:5432}
|
||
|
|
username: ${DB_USER}
|
||
|
|
password: ${DB_PASS:}
|
||
|
|
|
||
|
|
logging:
|
||
|
|
level: ${LOG_LEVEL:INFO}
|
||
|
|
directory: ${LOG_DIR:./logs}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Modular Configuration Support
|
||
|
|
|
||
|
|
### Include Directive Processing
|
||
|
|
```python
|
||
|
|
def _process_includes(self, config: Dict[str, Any], base_dir: Path) -> Dict[str, Any]:
|
||
|
|
"""Process include directives in configuration."""
|
||
|
|
if not isinstance(config, dict):
|
||
|
|
return config
|
||
|
|
|
||
|
|
# Handle special include key
|
||
|
|
if '__include__' in config:
|
||
|
|
includes = config.pop('__include__')
|
||
|
|
if isinstance(includes, str):
|
||
|
|
includes = [includes]
|
||
|
|
|
||
|
|
for include_file in includes:
|
||
|
|
include_path = base_dir / include_file
|
||
|
|
if include_path.exists():
|
||
|
|
with open(include_path, 'r', encoding='utf-8') as f:
|
||
|
|
included_config = yaml.safe_load(f.read())
|
||
|
|
if isinstance(included_config, dict):
|
||
|
|
# Merge included config (current config takes precedence)
|
||
|
|
included_config.update(config)
|
||
|
|
config = included_config
|
||
|
|
|
||
|
|
return config
|
||
|
|
```
|
||
|
|
|
||
|
|
### Modular Configuration Example
|
||
|
|
```yaml
|
||
|
|
# main.yaml
|
||
|
|
__include__:
|
||
|
|
- "common/logging.yaml"
|
||
|
|
- "environments/production.yaml"
|
||
|
|
|
||
|
|
application:
|
||
|
|
name: "SuperClaude Hooks"
|
||
|
|
version: "1.0.0"
|
||
|
|
|
||
|
|
# Override included values
|
||
|
|
logging:
|
||
|
|
level: "DEBUG" # Overrides value from logging.yaml
|
||
|
|
```
|
||
|
|
|
||
|
|
## JSON Configuration Support
|
||
|
|
|
||
|
|
### JSON Loading with Error Handling
|
||
|
|
```python
|
||
|
|
def _load_json_config(self, config_name: str, force_reload: bool = False) -> Dict[str, Any]:
|
||
|
|
"""Load JSON configuration file."""
|
||
|
|
config_path = self._config_sources[config_name]
|
||
|
|
|
||
|
|
if not config_path.exists():
|
||
|
|
raise FileNotFoundError(f"Configuration file not found: {config_path}")
|
||
|
|
|
||
|
|
# Check if we need to reload
|
||
|
|
if not force_reload and self._should_use_cache(config_name, config_path):
|
||
|
|
return self._cache[config_name]
|
||
|
|
|
||
|
|
# Load and parse the JSON configuration
|
||
|
|
try:
|
||
|
|
with open(config_path, 'r', encoding='utf-8') as f:
|
||
|
|
content = f.read()
|
||
|
|
|
||
|
|
# Environment variable interpolation
|
||
|
|
content = self._interpolate_env_vars(content)
|
||
|
|
|
||
|
|
# Parse JSON
|
||
|
|
config = json.loads(content)
|
||
|
|
|
||
|
|
# Update cache
|
||
|
|
self._cache[config_name] = config
|
||
|
|
self._file_hashes[config_name] = self._compute_hash(config_path)
|
||
|
|
self._last_check[config_name] = time.time()
|
||
|
|
|
||
|
|
return config
|
||
|
|
|
||
|
|
except json.JSONDecodeError as e:
|
||
|
|
raise ValueError(f"JSON parsing error in {config_path}: {e}")
|
||
|
|
except Exception as e:
|
||
|
|
raise RuntimeError(f"Error loading JSON config {config_name}: {e}")
|
||
|
|
```
|
||
|
|
|
||
|
|
**JSON Support Features**:
|
||
|
|
- **Environment Interpolation**: ${VAR} syntax support in JSON files
|
||
|
|
- **Error Handling**: Comprehensive JSON parsing error messages
|
||
|
|
- **Cache Integration**: Same caching behavior as YAML configurations
|
||
|
|
- **Encoding Support**: UTF-8 encoding for international character support
|
||
|
|
|
||
|
|
## Configuration Validation and Error Handling
|
||
|
|
|
||
|
|
### Error Handling Strategy
|
||
|
|
```python
|
||
|
|
def load_config(self, config_name: str, force_reload: bool = False) -> Dict[str, Any]:
|
||
|
|
try:
|
||
|
|
# Configuration loading logic
|
||
|
|
pass
|
||
|
|
except yaml.YAMLError as e:
|
||
|
|
raise ValueError(f"YAML parsing error in {config_path}: {e}")
|
||
|
|
except json.JSONDecodeError as e:
|
||
|
|
raise ValueError(f"JSON parsing error in {config_path}: {e}")
|
||
|
|
except FileNotFoundError as e:
|
||
|
|
raise FileNotFoundError(f"Configuration file not found: {config_path}")
|
||
|
|
except Exception as e:
|
||
|
|
raise RuntimeError(f"Error loading config {config_name}: {e}")
|
||
|
|
```
|
||
|
|
|
||
|
|
**Error Categories**:
|
||
|
|
- **File Not Found**: Configuration file missing or inaccessible
|
||
|
|
- **Parsing Errors**: YAML or JSON syntax errors with detailed messages
|
||
|
|
- **Permission Errors**: File system permission issues
|
||
|
|
- **General Errors**: Unexpected errors with full context
|
||
|
|
|
||
|
|
### Graceful Degradation
|
||
|
|
```python
|
||
|
|
def get_section(self, config_name: str, section_path: str, default: Any = None) -> Any:
|
||
|
|
try:
|
||
|
|
result = config
|
||
|
|
for key in section_path.split('.'):
|
||
|
|
result = result[key]
|
||
|
|
return result
|
||
|
|
except (KeyError, TypeError):
|
||
|
|
return default # Graceful fallback to default value
|
||
|
|
```
|
||
|
|
|
||
|
|
## Performance Optimization
|
||
|
|
|
||
|
|
### Cache Reload Management
|
||
|
|
```python
|
||
|
|
def reload_all(self) -> None:
|
||
|
|
"""Force reload of all cached configurations."""
|
||
|
|
for config_name in list(self._cache.keys()):
|
||
|
|
self.load_config(config_name, force_reload=True)
|
||
|
|
```
|
||
|
|
|
||
|
|
### Hook Status Checking
|
||
|
|
```python
|
||
|
|
def is_hook_enabled(self, hook_name: str) -> bool:
|
||
|
|
"""Check if a specific hook is enabled."""
|
||
|
|
return self.get_hook_config(hook_name, 'enabled', False)
|
||
|
|
```
|
||
|
|
|
||
|
|
**Performance Optimizations**:
|
||
|
|
- **Selective Reloading**: Only reload changed configurations
|
||
|
|
- **Rate-Limited Checks**: File modification checks limited to once per second
|
||
|
|
- **Memory Efficient**: Cache only active configurations
|
||
|
|
- **Batch Operations**: Multiple configuration accesses use cached versions
|
||
|
|
|
||
|
|
## Integration with Hooks
|
||
|
|
|
||
|
|
### Global Instance
|
||
|
|
```python
|
||
|
|
# Global instance for shared use across hooks
|
||
|
|
config_loader = UnifiedConfigLoader(".")
|
||
|
|
```
|
||
|
|
|
||
|
|
### Hook Usage Pattern
|
||
|
|
```python
|
||
|
|
from shared.yaml_loader import config_loader
|
||
|
|
|
||
|
|
# Load hook-specific configuration
|
||
|
|
hook_config = config_loader.get_hook_config('pre_tool_use')
|
||
|
|
performance_target = config_loader.get_hook_config('pre_tool_use', 'performance_target_ms', 200)
|
||
|
|
|
||
|
|
# Load MCP server configuration
|
||
|
|
mcp_config = config_loader.get_mcp_server_config('sequential')
|
||
|
|
all_mcp_servers = config_loader.get_mcp_server_config()
|
||
|
|
|
||
|
|
# Load global performance targets
|
||
|
|
performance_targets = config_loader.get_performance_targets()
|
||
|
|
|
||
|
|
# Check if hook is enabled
|
||
|
|
if config_loader.is_hook_enabled('pre_tool_use'):
|
||
|
|
# Execute hook logic
|
||
|
|
pass
|
||
|
|
```
|
||
|
|
|
||
|
|
### Configuration Structure Examples
|
||
|
|
|
||
|
|
#### SuperClaude Configuration (superclaude-config.json)
|
||
|
|
```json
|
||
|
|
{
|
||
|
|
"hook_configurations": {
|
||
|
|
"session_start": {
|
||
|
|
"enabled": true,
|
||
|
|
"performance_target_ms": 50,
|
||
|
|
"initialization_timeout_ms": 1000
|
||
|
|
},
|
||
|
|
"pre_tool_use": {
|
||
|
|
"enabled": true,
|
||
|
|
"performance_target_ms": 200,
|
||
|
|
"pattern_detection_enabled": true,
|
||
|
|
"mcp_intelligence_enabled": true
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"mcp_server_integration": {
|
||
|
|
"servers": {
|
||
|
|
"sequential": {
|
||
|
|
"enabled": true,
|
||
|
|
"activation_cost_ms": 200,
|
||
|
|
"performance_profile": "intensive"
|
||
|
|
},
|
||
|
|
"context7": {
|
||
|
|
"enabled": true,
|
||
|
|
"activation_cost_ms": 150,
|
||
|
|
"performance_profile": "standard"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"global_configuration": {
|
||
|
|
"performance_monitoring": {
|
||
|
|
"enabled": true,
|
||
|
|
"target_percentile": 95,
|
||
|
|
"alert_threshold_ms": 500
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
#### YAML Configuration (config/logging.yaml)
|
||
|
|
```yaml
|
||
|
|
logging:
|
||
|
|
enabled: true
|
||
|
|
level: ${LOG_LEVEL:INFO}
|
||
|
|
|
||
|
|
file_settings:
|
||
|
|
log_directory: ${LOG_DIR:cache/logs}
|
||
|
|
retention_days: ${LOG_RETENTION:30}
|
||
|
|
max_file_size_mb: 10
|
||
|
|
|
||
|
|
hook_logging:
|
||
|
|
log_lifecycle: true
|
||
|
|
log_decisions: true
|
||
|
|
log_errors: true
|
||
|
|
log_performance: true
|
||
|
|
|
||
|
|
# Include common configuration
|
||
|
|
__include__:
|
||
|
|
- "common/base.yaml"
|
||
|
|
```
|
||
|
|
|
||
|
|
## Performance Characteristics
|
||
|
|
|
||
|
|
### Access Performance
|
||
|
|
- **Cached Access**: <10ms average for configuration retrieval
|
||
|
|
- **Initial Load**: <50ms for typical configuration files
|
||
|
|
- **Hot Reload**: <75ms for configuration file changes
|
||
|
|
- **Bulk Access**: <5ms per additional section access from cached config
|
||
|
|
|
||
|
|
### Memory Efficiency
|
||
|
|
- **Configuration Cache**: ~1-5KB per cached configuration file
|
||
|
|
- **File Hash Cache**: ~50B per tracked configuration file
|
||
|
|
- **Include Processing**: Dynamic memory usage based on included file sizes
|
||
|
|
- **Memory Cleanup**: Automatic cleanup of unused cached configurations
|
||
|
|
|
||
|
|
### File System Optimization
|
||
|
|
- **Rate-Limited Checks**: Maximum one file system check per second per configuration
|
||
|
|
- **Efficient Hashing**: mtime + size based change detection
|
||
|
|
- **Batch Processing**: Multiple configuration accesses use single file check
|
||
|
|
- **Error Caching**: Failed configuration loads cached to prevent repeated failures
|
||
|
|
|
||
|
|
## Error Handling and Recovery
|
||
|
|
|
||
|
|
### Configuration Loading Failures
|
||
|
|
```python
|
||
|
|
# Graceful degradation for missing configurations
|
||
|
|
try:
|
||
|
|
config = config_loader.load_config('optional_config')
|
||
|
|
except FileNotFoundError:
|
||
|
|
config = {} # Use empty configuration
|
||
|
|
except ValueError as e:
|
||
|
|
logger.log_error("config_loader", f"Configuration parsing failed: {e}")
|
||
|
|
config = {} # Use empty configuration with error logging
|
||
|
|
```
|
||
|
|
|
||
|
|
### Cache Corruption Recovery
|
||
|
|
- **Hash Mismatch**: Automatic cache invalidation and reload
|
||
|
|
- **Memory Corruption**: Cache clearing and fresh reload
|
||
|
|
- **File Permission Changes**: Graceful fallback to default values
|
||
|
|
- **Network File System Issues**: Retry logic with exponential backoff
|
||
|
|
|
||
|
|
### Environment Variable Issues
|
||
|
|
- **Missing Variables**: Use default values or empty strings as specified
|
||
|
|
- **Invalid Syntax**: Log warning and use literal value
|
||
|
|
- **Circular References**: Detection and prevention of infinite loops
|
||
|
|
|
||
|
|
## Configuration Best Practices
|
||
|
|
|
||
|
|
### File Organization
|
||
|
|
```
|
||
|
|
project_root/
|
||
|
|
├── settings.json # Claude Code settings
|
||
|
|
├── superclaude-config.json # SuperClaude framework config
|
||
|
|
└── config/
|
||
|
|
├── logging.yaml # Logging configuration
|
||
|
|
├── orchestrator.yaml # MCP server routing
|
||
|
|
├── modes.yaml # Mode detection patterns
|
||
|
|
└── common/
|
||
|
|
└── base.yaml # Shared configuration elements
|
||
|
|
```
|
||
|
|
|
||
|
|
### Configuration Conventions
|
||
|
|
- **JSON for Integration**: Use JSON for Claude Code and SuperClaude integration configs
|
||
|
|
- **YAML for Modularity**: Use YAML for complex, hierarchical configurations
|
||
|
|
- **Environment Variables**: Use ${VAR} syntax for deployment-specific values
|
||
|
|
- **Include Files**: Use __include__ for shared configuration elements
|
||
|
|
|
||
|
|
## Usage Examples
|
||
|
|
|
||
|
|
### Basic Configuration Loading
|
||
|
|
```python
|
||
|
|
from shared.yaml_loader import config_loader
|
||
|
|
|
||
|
|
# Load hook configuration
|
||
|
|
hook_config = config_loader.get_hook_config('pre_tool_use')
|
||
|
|
print(f"Hook enabled: {hook_config.get('enabled', False)}")
|
||
|
|
print(f"Performance target: {hook_config.get('performance_target_ms', 200)}ms")
|
||
|
|
|
||
|
|
# Load MCP server configuration
|
||
|
|
sequential_config = config_loader.get_mcp_server_config('sequential')
|
||
|
|
print(f"Sequential activation cost: {sequential_config.get('activation_cost_ms', 200)}ms")
|
||
|
|
```
|
||
|
|
|
||
|
|
### Advanced Configuration Access
|
||
|
|
```python
|
||
|
|
# Get nested configuration with dot notation
|
||
|
|
logging_level = config_loader.get_section('logging', 'file_settings.log_level', 'INFO')
|
||
|
|
performance_target = config_loader.get_section('superclaude_config', 'hook_configurations.pre_tool_use.performance_target_ms', 200)
|
||
|
|
|
||
|
|
# Check hook status
|
||
|
|
if config_loader.is_hook_enabled('mcp_intelligence'):
|
||
|
|
# Initialize MCP intelligence
|
||
|
|
pass
|
||
|
|
|
||
|
|
# Force reload all configurations
|
||
|
|
config_loader.reload_all()
|
||
|
|
```
|
||
|
|
|
||
|
|
### Environment Variable Integration
|
||
|
|
```python
|
||
|
|
# Configuration automatically processes environment variables
|
||
|
|
# In config/database.yaml:
|
||
|
|
# database:
|
||
|
|
# host: ${DB_HOST:localhost}
|
||
|
|
# port: ${DB_PORT:5432}
|
||
|
|
|
||
|
|
db_config = config_loader.get_section('database', 'host') # Uses DB_HOST env var or 'localhost'
|
||
|
|
```
|
||
|
|
|
||
|
|
## Dependencies and Relationships
|
||
|
|
|
||
|
|
### Internal Dependencies
|
||
|
|
- **Standard Libraries**: os, json, yaml, time, hashlib, pathlib, re
|
||
|
|
- **No External Dependencies**: Self-contained configuration management system
|
||
|
|
|
||
|
|
### Framework Integration
|
||
|
|
- **Hook Configuration**: Centralized configuration for all 7 SuperClaude hooks
|
||
|
|
- **MCP Server Integration**: Configuration management for MCP server coordination
|
||
|
|
- **Performance Monitoring**: Configuration-driven performance target management
|
||
|
|
|
||
|
|
### Global Availability
|
||
|
|
- **Shared Instance**: config_loader global instance available to all hooks
|
||
|
|
- **Consistent Interface**: Standardized configuration access across all modules
|
||
|
|
- **Hot-Reload Support**: Dynamic configuration updates without hook restart
|
||
|
|
|
||
|
|
---
|
||
|
|
|
||
|
|
*This module serves as the foundational configuration management system for the entire SuperClaude framework, providing high-performance, flexible, and reliable configuration loading with comprehensive error handling and hot-reload capabilities.*
|