mirror of
https://github.com/SuperClaude-Org/SuperClaude_Framework.git
synced 2025-12-29 16:16:08 +00:00
Implement dynamic file discovery for components (PR #133)
Replace hardcoded file arrays with dynamic discovery system: - CoreComponent: Auto-discovers framework .md files in Core directory - CommandsComponent: Auto-discovers command .md files in Commands directory - Eliminates manual maintenance of file lists - Maintains backward compatibility and error handling - Adds comprehensive logging and validation Key changes: - Added _discover_framework_files() and _discover_command_files() methods - Added shared _discover_files_in_directory() utility - Replaced hardcoded arrays with dynamic discovery calls - Includes filtering, sorting, and error handling - Validates 9 framework files and 16 command files correctly - Clean up documentation formatting Resolves maintenance burden described in PR #133 while preserving all existing functionality and security validation. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,11 +1,5 @@
|
||||
# COMMANDS.md - SuperClaude Command Execution Framework
|
||||
|
||||
---
|
||||
framework: "SuperClaude v3.0"
|
||||
execution-engine: "Claude Code"
|
||||
wave-compatibility: "Full"
|
||||
---
|
||||
|
||||
Command execution framework for Claude Code SuperClaude integration.
|
||||
|
||||
## Command System Architecture
|
||||
|
||||
@@ -531,8 +531,3 @@ orchestrator_config:
|
||||
|
||||
### Custom Routing Rules
|
||||
Users can add custom routing patterns via YAML configuration files.
|
||||
|
||||
|
||||
---
|
||||
|
||||
|
||||
|
||||
@@ -22,25 +22,8 @@ class CommandsComponent(Component):
|
||||
self.file_manager = FileManager()
|
||||
self.settings_manager = SettingsManager(self.install_dir)
|
||||
|
||||
# Define command files to install
|
||||
self.command_files = [
|
||||
"analyze.md",
|
||||
"build.md",
|
||||
"implement.md",
|
||||
"cleanup.md",
|
||||
"design.md",
|
||||
"document.md",
|
||||
"estimate.md",
|
||||
"explain.md",
|
||||
"git.md",
|
||||
"improve.md",
|
||||
"index.md",
|
||||
"load.md",
|
||||
"spawn.md",
|
||||
"task.md",
|
||||
"test.md",
|
||||
"troubleshoot.md"
|
||||
]
|
||||
# Dynamically discover command files to install
|
||||
self.command_files = self._discover_command_files()
|
||||
|
||||
def get_metadata(self) -> Dict[str, str]:
|
||||
"""Get component metadata"""
|
||||
@@ -343,6 +326,68 @@ class CommandsComponent(Component):
|
||||
|
||||
return len(errors) == 0, errors
|
||||
|
||||
def _discover_command_files(self) -> List[str]:
|
||||
"""
|
||||
Dynamically discover command .md files in the Commands directory
|
||||
|
||||
Returns:
|
||||
List of command filenames (e.g., ['analyze.md', 'build.md', ...])
|
||||
"""
|
||||
return self._discover_files_in_directory(
|
||||
self._get_source_dir(),
|
||||
extension='.md',
|
||||
exclude_patterns=['README.md', 'CHANGELOG.md', 'LICENSE.md']
|
||||
)
|
||||
|
||||
def _discover_files_in_directory(self, directory: Path, extension: str = '.md',
|
||||
exclude_patterns: List[str] = None) -> List[str]:
|
||||
"""
|
||||
Shared utility for discovering files in a directory
|
||||
|
||||
Args:
|
||||
directory: Directory to scan
|
||||
extension: File extension to look for (default: '.md')
|
||||
exclude_patterns: List of filename patterns to exclude
|
||||
|
||||
Returns:
|
||||
List of filenames found in the directory
|
||||
"""
|
||||
if exclude_patterns is None:
|
||||
exclude_patterns = []
|
||||
|
||||
try:
|
||||
if not directory.exists():
|
||||
self.logger.warning(f"Source directory not found: {directory}")
|
||||
return []
|
||||
|
||||
if not directory.is_dir():
|
||||
self.logger.warning(f"Source path is not a directory: {directory}")
|
||||
return []
|
||||
|
||||
# Discover files with the specified extension
|
||||
files = []
|
||||
for file_path in directory.iterdir():
|
||||
if (file_path.is_file() and
|
||||
file_path.suffix.lower() == extension.lower() and
|
||||
file_path.name not in exclude_patterns):
|
||||
files.append(file_path.name)
|
||||
|
||||
# Sort for consistent ordering
|
||||
files.sort()
|
||||
|
||||
self.logger.debug(f"Discovered {len(files)} {extension} files in {directory}")
|
||||
if files:
|
||||
self.logger.debug(f"Files found: {files}")
|
||||
|
||||
return files
|
||||
|
||||
except PermissionError:
|
||||
self.logger.error(f"Permission denied accessing directory: {directory}")
|
||||
return []
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error discovering files in {directory}: {e}")
|
||||
return []
|
||||
|
||||
def _get_source_dir(self) -> Path:
|
||||
"""Get source directory for command files"""
|
||||
# Assume we're in SuperClaude/setup/components/commands.py
|
||||
|
||||
@@ -24,18 +24,8 @@ class CoreComponent(Component):
|
||||
self.file_manager = FileManager()
|
||||
self.settings_manager = SettingsManager(self.install_dir)
|
||||
|
||||
# Define framework files to install
|
||||
self.framework_files = [
|
||||
"CLAUDE.md",
|
||||
"COMMANDS.md",
|
||||
"FLAGS.md",
|
||||
"PRINCIPLES.md",
|
||||
"RULES.md",
|
||||
"MCP.md",
|
||||
"PERSONAS.md",
|
||||
"ORCHESTRATOR.md",
|
||||
"MODES.md"
|
||||
]
|
||||
# Dynamically discover framework files to install
|
||||
self.framework_files = self._discover_framework_files()
|
||||
|
||||
def get_metadata(self) -> Dict[str, str]:
|
||||
"""Get component metadata"""
|
||||
@@ -323,6 +313,68 @@ class CoreComponent(Component):
|
||||
|
||||
return len(errors) == 0, errors
|
||||
|
||||
def _discover_framework_files(self) -> List[str]:
|
||||
"""
|
||||
Dynamically discover framework .md files in the Core directory
|
||||
|
||||
Returns:
|
||||
List of framework filenames (e.g., ['CLAUDE.md', 'COMMANDS.md', ...])
|
||||
"""
|
||||
return self._discover_files_in_directory(
|
||||
self._get_source_dir(),
|
||||
extension='.md',
|
||||
exclude_patterns=['README.md', 'CHANGELOG.md', 'LICENSE.md']
|
||||
)
|
||||
|
||||
def _discover_files_in_directory(self, directory: Path, extension: str = '.md',
|
||||
exclude_patterns: List[str] = None) -> List[str]:
|
||||
"""
|
||||
Shared utility for discovering files in a directory
|
||||
|
||||
Args:
|
||||
directory: Directory to scan
|
||||
extension: File extension to look for (default: '.md')
|
||||
exclude_patterns: List of filename patterns to exclude
|
||||
|
||||
Returns:
|
||||
List of filenames found in the directory
|
||||
"""
|
||||
if exclude_patterns is None:
|
||||
exclude_patterns = []
|
||||
|
||||
try:
|
||||
if not directory.exists():
|
||||
self.logger.warning(f"Source directory not found: {directory}")
|
||||
return []
|
||||
|
||||
if not directory.is_dir():
|
||||
self.logger.warning(f"Source path is not a directory: {directory}")
|
||||
return []
|
||||
|
||||
# Discover files with the specified extension
|
||||
files = []
|
||||
for file_path in directory.iterdir():
|
||||
if (file_path.is_file() and
|
||||
file_path.suffix.lower() == extension.lower() and
|
||||
file_path.name not in exclude_patterns):
|
||||
files.append(file_path.name)
|
||||
|
||||
# Sort for consistent ordering
|
||||
files.sort()
|
||||
|
||||
self.logger.debug(f"Discovered {len(files)} {extension} files in {directory}")
|
||||
if files:
|
||||
self.logger.debug(f"Files found: {files}")
|
||||
|
||||
return files
|
||||
|
||||
except PermissionError:
|
||||
self.logger.error(f"Permission denied accessing directory: {directory}")
|
||||
return []
|
||||
except Exception as e:
|
||||
self.logger.error(f"Error discovering files in {directory}: {e}")
|
||||
return []
|
||||
|
||||
def _get_source_dir(self) -> Path:
|
||||
"""Get source directory for framework files"""
|
||||
# Assume we're in SuperClaude/setup/components/core.py
|
||||
|
||||
Reference in New Issue
Block a user