mirror of
https://github.com/SuperClaude-Org/SuperClaude_Framework.git
synced 2025-12-17 17:56:46 +00:00
fix: Address invalid JSON field in installation suite
- Separate SuperClaude metadata from Claude Code settings.json - Create .superclaude-metadata.json for framework-specific data - Fix JSON validation issues with settings management - Update all components to use proper metadata storage - Maintain compatibility with Claude Code settings format - Add migration support for existing installations 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
6425be82eb
commit
625088df64
@ -217,7 +217,7 @@ class Installer:
|
|||||||
|
|
||||||
if success:
|
if success:
|
||||||
self.installed_components.add(component_name)
|
self.installed_components.add(component_name)
|
||||||
self._update_settings_registry(component)
|
# Component handles its own metadata registration
|
||||||
else:
|
else:
|
||||||
self.failed_components.add(component_name)
|
self.failed_components.add(component_name)
|
||||||
|
|
||||||
@ -296,8 +296,7 @@ class Installer:
|
|||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
success = component.uninstall()
|
success = component.uninstall()
|
||||||
if success:
|
# Component handles its own metadata removal
|
||||||
self._remove_from_settings_registry(component_name)
|
|
||||||
return success
|
return success
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"Error uninstalling {component_name}: {e}")
|
print(f"Error uninstalling {component_name}: {e}")
|
||||||
|
|||||||
@ -97,8 +97,8 @@ class CommandsComponent(Component):
|
|||||||
|
|
||||||
return files
|
return files
|
||||||
|
|
||||||
def get_settings_modifications(self) -> Dict[str, Any]:
|
def get_metadata_modifications(self) -> Dict[str, Any]:
|
||||||
"""Get settings modifications"""
|
"""Get metadata modifications for commands component"""
|
||||||
return {
|
return {
|
||||||
"components": {
|
"components": {
|
||||||
"commands": {
|
"commands": {
|
||||||
@ -109,6 +109,11 @@ class CommandsComponent(Component):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_settings_modifications(self) -> Dict[str, Any]:
|
||||||
|
"""Get settings.json modifications (now only Claude Code compatible settings)"""
|
||||||
|
# Return empty dict as we don't modify Claude Code settings
|
||||||
|
return {}
|
||||||
|
|
||||||
def install(self, config: Dict[str, Any]) -> bool:
|
def install(self, config: Dict[str, Any]) -> bool:
|
||||||
"""Install commands component"""
|
"""Install commands component"""
|
||||||
try:
|
try:
|
||||||
@ -155,13 +160,17 @@ class CommandsComponent(Component):
|
|||||||
self.logger.error(f"Only {success_count}/{len(files_to_install)} command files copied successfully")
|
self.logger.error(f"Only {success_count}/{len(files_to_install)} command files copied successfully")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Update settings.json
|
# Update metadata
|
||||||
try:
|
try:
|
||||||
settings_mods = self.get_settings_modifications()
|
# Add component registration to metadata
|
||||||
self.settings_manager.update_settings(settings_mods)
|
self.settings_manager.add_component_registration("commands", {
|
||||||
self.logger.info("Updated settings.json with commands component registration")
|
"version": "3.0.0",
|
||||||
|
"category": "commands",
|
||||||
|
"files_count": len(self.command_files)
|
||||||
|
})
|
||||||
|
self.logger.info("Updated metadata with commands component registration")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Failed to update settings.json: {e}")
|
self.logger.error(f"Failed to update metadata: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.logger.success(f"Commands component installed successfully ({success_count} command files)")
|
self.logger.success(f"Commands component installed successfully ({success_count} command files)")
|
||||||
@ -198,13 +207,13 @@ class CommandsComponent(Component):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.warning(f"Could not remove commands directory: {e}")
|
self.logger.warning(f"Could not remove commands directory: {e}")
|
||||||
|
|
||||||
# Update settings.json to remove commands component
|
# Update metadata to remove commands component
|
||||||
try:
|
try:
|
||||||
if self.settings_manager.is_component_installed("commands"):
|
if self.settings_manager.is_component_installed("commands"):
|
||||||
self.settings_manager.remove_component_registration("commands")
|
self.settings_manager.remove_component_registration("commands")
|
||||||
self.logger.info("Removed commands component from settings.json")
|
self.logger.info("Removed commands component from metadata")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.warning(f"Could not update settings.json: {e}")
|
self.logger.warning(f"Could not update metadata: {e}")
|
||||||
|
|
||||||
self.logger.success(f"Commands component uninstalled ({removed_count} files removed)")
|
self.logger.success(f"Commands component uninstalled ({removed_count} files removed)")
|
||||||
return True
|
return True
|
||||||
@ -292,9 +301,9 @@ class CommandsComponent(Component):
|
|||||||
elif not file_path.is_file():
|
elif not file_path.is_file():
|
||||||
errors.append(f"Command file is not a regular file: {filename}")
|
errors.append(f"Command file is not a regular file: {filename}")
|
||||||
|
|
||||||
# Check settings.json registration
|
# Check metadata registration
|
||||||
if not self.settings_manager.is_component_installed("commands"):
|
if not self.settings_manager.is_component_installed("commands"):
|
||||||
errors.append("Commands component not registered in settings.json")
|
errors.append("Commands component not registered in metadata")
|
||||||
else:
|
else:
|
||||||
# Check version matches
|
# Check version matches
|
||||||
installed_version = self.settings_manager.get_component_version("commands")
|
installed_version = self.settings_manager.get_component_version("commands")
|
||||||
|
|||||||
@ -92,8 +92,8 @@ class CoreComponent(Component):
|
|||||||
|
|
||||||
return files
|
return files
|
||||||
|
|
||||||
def get_settings_modifications(self) -> Dict[str, Any]:
|
def get_metadata_modifications(self) -> Dict[str, Any]:
|
||||||
"""Get settings.json modifications"""
|
"""Get metadata modifications for SuperClaude"""
|
||||||
return {
|
return {
|
||||||
"framework": {
|
"framework": {
|
||||||
"version": "3.0.0",
|
"version": "3.0.0",
|
||||||
@ -110,6 +110,11 @@ class CoreComponent(Component):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_settings_modifications(self) -> Dict[str, Any]:
|
||||||
|
"""Get settings.json modifications (now only Claude Code compatible settings)"""
|
||||||
|
# Return empty dict as we don't modify Claude Code settings
|
||||||
|
return {}
|
||||||
|
|
||||||
def install(self, config: Dict[str, Any]) -> bool:
|
def install(self, config: Dict[str, Any]) -> bool:
|
||||||
"""Install core component"""
|
"""Install core component"""
|
||||||
try:
|
try:
|
||||||
@ -155,13 +160,20 @@ class CoreComponent(Component):
|
|||||||
self.logger.error(f"Only {success_count}/{len(files_to_install)} files copied successfully")
|
self.logger.error(f"Only {success_count}/{len(files_to_install)} files copied successfully")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Create or update settings.json
|
# Create or update metadata
|
||||||
try:
|
try:
|
||||||
settings_mods = self.get_settings_modifications()
|
metadata_mods = self.get_metadata_modifications()
|
||||||
self.settings_manager.update_settings(settings_mods)
|
# Update metadata directly
|
||||||
self.logger.info("Updated settings.json with framework configuration")
|
existing_metadata = self.settings_manager.load_metadata()
|
||||||
|
merged_metadata = self.settings_manager._deep_merge(existing_metadata, metadata_mods)
|
||||||
|
self.settings_manager.save_metadata(merged_metadata)
|
||||||
|
self.logger.info("Updated metadata with framework configuration")
|
||||||
|
|
||||||
|
# Migrate any existing SuperClaude data from settings.json
|
||||||
|
if self.settings_manager.migrate_superclaude_data():
|
||||||
|
self.logger.info("Migrated existing SuperClaude data from settings.json")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Failed to update settings.json: {e}")
|
self.logger.error(f"Failed to update metadata: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Create additional directories for other components
|
# Create additional directories for other components
|
||||||
@ -193,13 +205,13 @@ class CoreComponent(Component):
|
|||||||
else:
|
else:
|
||||||
self.logger.warning(f"Could not remove {filename}")
|
self.logger.warning(f"Could not remove {filename}")
|
||||||
|
|
||||||
# Update settings.json to remove core component
|
# Update metadata to remove core component
|
||||||
try:
|
try:
|
||||||
if self.settings_manager.is_component_installed("core"):
|
if self.settings_manager.is_component_installed("core"):
|
||||||
self.settings_manager.remove_component_registration("core")
|
self.settings_manager.remove_component_registration("core")
|
||||||
self.logger.info("Removed core component from settings.json")
|
self.logger.info("Removed core component from metadata")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.warning(f"Could not update settings.json: {e}")
|
self.logger.warning(f"Could not update metadata: {e}")
|
||||||
|
|
||||||
self.logger.success(f"Core component uninstalled ({removed_count} files removed)")
|
self.logger.success(f"Core component uninstalled ({removed_count} files removed)")
|
||||||
return True
|
return True
|
||||||
@ -278,9 +290,9 @@ class CoreComponent(Component):
|
|||||||
elif not file_path.is_file():
|
elif not file_path.is_file():
|
||||||
errors.append(f"Framework file is not a regular file: {filename}")
|
errors.append(f"Framework file is not a regular file: {filename}")
|
||||||
|
|
||||||
# Check settings.json registration
|
# Check metadata registration
|
||||||
if not self.settings_manager.is_component_installed("core"):
|
if not self.settings_manager.is_component_installed("core"):
|
||||||
errors.append("Core component not registered in settings.json")
|
errors.append("Core component not registered in metadata")
|
||||||
else:
|
else:
|
||||||
# Check version matches
|
# Check version matches
|
||||||
installed_version = self.settings_manager.get_component_version("core")
|
installed_version = self.settings_manager.get_component_version("core")
|
||||||
@ -288,18 +300,18 @@ class CoreComponent(Component):
|
|||||||
if installed_version != expected_version:
|
if installed_version != expected_version:
|
||||||
errors.append(f"Version mismatch: installed {installed_version}, expected {expected_version}")
|
errors.append(f"Version mismatch: installed {installed_version}, expected {expected_version}")
|
||||||
|
|
||||||
# Check settings.json structure
|
# Check metadata structure
|
||||||
try:
|
try:
|
||||||
framework_config = self.settings_manager.get_setting("framework")
|
framework_config = self.settings_manager.get_metadata_setting("framework")
|
||||||
if not framework_config:
|
if not framework_config:
|
||||||
errors.append("Missing framework configuration in settings.json")
|
errors.append("Missing framework configuration in metadata")
|
||||||
else:
|
else:
|
||||||
required_keys = ["version", "name", "description"]
|
required_keys = ["version", "name", "description"]
|
||||||
for key in required_keys:
|
for key in required_keys:
|
||||||
if key not in framework_config:
|
if key not in framework_config:
|
||||||
errors.append(f"Missing framework.{key} in settings.json")
|
errors.append(f"Missing framework.{key} in metadata")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
errors.append(f"Could not validate settings.json: {e}")
|
errors.append(f"Could not validate metadata: {e}")
|
||||||
|
|
||||||
return len(errors) == 0, errors
|
return len(errors) == 0, errors
|
||||||
|
|
||||||
|
|||||||
@ -131,8 +131,8 @@ class MCPComponent(Component):
|
|||||||
"""Get files to install (none for MCP component)"""
|
"""Get files to install (none for MCP component)"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def get_settings_modifications(self) -> Dict[str, Any]:
|
def get_metadata_modifications(self) -> Dict[str, Any]:
|
||||||
"""Get settings modifications"""
|
"""Get metadata modifications for MCP component"""
|
||||||
return {
|
return {
|
||||||
"components": {
|
"components": {
|
||||||
"mcp": {
|
"mcp": {
|
||||||
@ -148,6 +148,11 @@ class MCPComponent(Component):
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def get_settings_modifications(self) -> Dict[str, Any]:
|
||||||
|
"""Get settings.json modifications (now only Claude Code compatible settings)"""
|
||||||
|
# Return empty dict as we don't modify Claude Code settings
|
||||||
|
return {}
|
||||||
|
|
||||||
def _check_mcp_server_installed(self, server_name: str) -> bool:
|
def _check_mcp_server_installed(self, server_name: str) -> bool:
|
||||||
"""Check if MCP server is already installed"""
|
"""Check if MCP server is already installed"""
|
||||||
try:
|
try:
|
||||||
@ -292,13 +297,27 @@ class MCPComponent(Component):
|
|||||||
self.logger.error(f"Required MCP server {server_name} failed to install")
|
self.logger.error(f"Required MCP server {server_name} failed to install")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Update settings.json
|
# Update metadata
|
||||||
try:
|
try:
|
||||||
settings_mods = self.get_settings_modifications()
|
# Add component registration to metadata
|
||||||
self.settings_manager.update_settings(settings_mods)
|
self.settings_manager.add_component_registration("mcp", {
|
||||||
self.logger.info("Updated settings.json with MCP component registration")
|
"version": "3.0.0",
|
||||||
|
"category": "integration",
|
||||||
|
"servers_count": len(self.mcp_servers)
|
||||||
|
})
|
||||||
|
|
||||||
|
# Add MCP configuration to metadata
|
||||||
|
metadata = self.settings_manager.load_metadata()
|
||||||
|
metadata["mcp"] = {
|
||||||
|
"enabled": True,
|
||||||
|
"servers": list(self.mcp_servers.keys()),
|
||||||
|
"auto_update": False
|
||||||
|
}
|
||||||
|
self.settings_manager.save_metadata(metadata)
|
||||||
|
|
||||||
|
self.logger.info("Updated metadata with MCP component registration")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.error(f"Failed to update settings.json: {e}")
|
self.logger.error(f"Failed to update metadata: {e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
# Verify installation
|
# Verify installation
|
||||||
@ -347,13 +366,18 @@ class MCPComponent(Component):
|
|||||||
if self._uninstall_mcp_server(server_name):
|
if self._uninstall_mcp_server(server_name):
|
||||||
uninstalled_count += 1
|
uninstalled_count += 1
|
||||||
|
|
||||||
# Update settings.json to remove MCP component
|
# Update metadata to remove MCP component
|
||||||
try:
|
try:
|
||||||
if self.settings_manager.is_component_installed("mcp"):
|
if self.settings_manager.is_component_installed("mcp"):
|
||||||
self.settings_manager.remove_component_registration("mcp")
|
self.settings_manager.remove_component_registration("mcp")
|
||||||
self.logger.info("Removed MCP component from settings.json")
|
# Also remove MCP configuration from metadata
|
||||||
|
metadata = self.settings_manager.load_metadata()
|
||||||
|
if "mcp" in metadata:
|
||||||
|
del metadata["mcp"]
|
||||||
|
self.settings_manager.save_metadata(metadata)
|
||||||
|
self.logger.info("Removed MCP component from metadata")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.warning(f"Could not update settings.json: {e}")
|
self.logger.warning(f"Could not update metadata: {e}")
|
||||||
|
|
||||||
self.logger.success(f"MCP component uninstalled ({uninstalled_count} servers removed)")
|
self.logger.success(f"MCP component uninstalled ({uninstalled_count} servers removed)")
|
||||||
return True
|
return True
|
||||||
@ -401,12 +425,18 @@ class MCPComponent(Component):
|
|||||||
self.logger.error(f"Error updating MCP server {server_name}: {e}")
|
self.logger.error(f"Error updating MCP server {server_name}: {e}")
|
||||||
failed_servers.append(server_name)
|
failed_servers.append(server_name)
|
||||||
|
|
||||||
# Update settings
|
# Update metadata
|
||||||
try:
|
try:
|
||||||
settings_mods = self.get_settings_modifications()
|
# Update component version in metadata
|
||||||
self.settings_manager.update_settings(settings_mods)
|
metadata = self.settings_manager.load_metadata()
|
||||||
|
if "components" in metadata and "mcp" in metadata["components"]:
|
||||||
|
metadata["components"]["mcp"]["version"] = target_version
|
||||||
|
metadata["components"]["mcp"]["servers_count"] = len(self.mcp_servers)
|
||||||
|
if "mcp" in metadata:
|
||||||
|
metadata["mcp"]["servers"] = list(self.mcp_servers.keys())
|
||||||
|
self.settings_manager.save_metadata(metadata)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.warning(f"Could not update settings.json: {e}")
|
self.logger.warning(f"Could not update metadata: {e}")
|
||||||
|
|
||||||
if failed_servers:
|
if failed_servers:
|
||||||
self.logger.warning(f"Some MCP servers failed to update: {failed_servers}")
|
self.logger.warning(f"Some MCP servers failed to update: {failed_servers}")
|
||||||
@ -423,9 +453,9 @@ class MCPComponent(Component):
|
|||||||
"""Validate MCP component installation"""
|
"""Validate MCP component installation"""
|
||||||
errors = []
|
errors = []
|
||||||
|
|
||||||
# Check settings.json registration
|
# Check metadata registration
|
||||||
if not self.settings_manager.is_component_installed("mcp"):
|
if not self.settings_manager.is_component_installed("mcp"):
|
||||||
errors.append("MCP component not registered in settings.json")
|
errors.append("MCP component not registered in metadata")
|
||||||
return False, errors
|
return False, errors
|
||||||
|
|
||||||
# Check version matches
|
# Check version matches
|
||||||
|
|||||||
@ -23,6 +23,7 @@ class SettingsManager:
|
|||||||
"""
|
"""
|
||||||
self.install_dir = install_dir
|
self.install_dir = install_dir
|
||||||
self.settings_file = install_dir / "settings.json"
|
self.settings_file = install_dir / "settings.json"
|
||||||
|
self.metadata_file = install_dir / ".superclaude-metadata.json"
|
||||||
self.backup_dir = install_dir / "backups" / "settings"
|
self.backup_dir = install_dir / "backups" / "settings"
|
||||||
|
|
||||||
def load_settings(self) -> Dict[str, Any]:
|
def load_settings(self) -> Dict[str, Any]:
|
||||||
@ -63,6 +64,77 @@ class SettingsManager:
|
|||||||
except IOError as e:
|
except IOError as e:
|
||||||
raise ValueError(f"Could not save settings to {self.settings_file}: {e}")
|
raise ValueError(f"Could not save settings to {self.settings_file}: {e}")
|
||||||
|
|
||||||
|
def load_metadata(self) -> Dict[str, Any]:
|
||||||
|
"""
|
||||||
|
Load SuperClaude metadata from .superclaude-metadata.json
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Metadata dict (empty if file doesn't exist)
|
||||||
|
"""
|
||||||
|
if not self.metadata_file.exists():
|
||||||
|
return {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(self.metadata_file, 'r', encoding='utf-8') as f:
|
||||||
|
return json.load(f)
|
||||||
|
except (json.JSONDecodeError, IOError) as e:
|
||||||
|
raise ValueError(f"Could not load metadata from {self.metadata_file}: {e}")
|
||||||
|
|
||||||
|
def save_metadata(self, metadata: Dict[str, Any]) -> None:
|
||||||
|
"""
|
||||||
|
Save SuperClaude metadata to .superclaude-metadata.json
|
||||||
|
|
||||||
|
Args:
|
||||||
|
metadata: Metadata dict to save
|
||||||
|
"""
|
||||||
|
# Ensure directory exists
|
||||||
|
self.metadata_file.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
|
# Save with pretty formatting
|
||||||
|
try:
|
||||||
|
with open(self.metadata_file, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(metadata, f, indent=2, ensure_ascii=False, sort_keys=True)
|
||||||
|
except IOError as e:
|
||||||
|
raise ValueError(f"Could not save metadata to {self.metadata_file}: {e}")
|
||||||
|
|
||||||
|
def migrate_superclaude_data(self) -> bool:
|
||||||
|
"""
|
||||||
|
Migrate SuperClaude-specific data from settings.json to metadata file
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
True if migration occurred, False if no data to migrate
|
||||||
|
"""
|
||||||
|
settings = self.load_settings()
|
||||||
|
|
||||||
|
# SuperClaude-specific fields to migrate
|
||||||
|
superclaude_fields = ["components", "framework", "superclaude", "mcp"]
|
||||||
|
data_to_migrate = {}
|
||||||
|
fields_found = False
|
||||||
|
|
||||||
|
# Extract SuperClaude data
|
||||||
|
for field in superclaude_fields:
|
||||||
|
if field in settings:
|
||||||
|
data_to_migrate[field] = settings[field]
|
||||||
|
fields_found = True
|
||||||
|
|
||||||
|
if not fields_found:
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Load existing metadata (if any) and merge
|
||||||
|
existing_metadata = self.load_metadata()
|
||||||
|
merged_metadata = self._deep_merge(existing_metadata, data_to_migrate)
|
||||||
|
|
||||||
|
# Save to metadata file
|
||||||
|
self.save_metadata(merged_metadata)
|
||||||
|
|
||||||
|
# Remove SuperClaude fields from settings
|
||||||
|
clean_settings = {k: v for k, v in settings.items() if k not in superclaude_fields}
|
||||||
|
|
||||||
|
# Save cleaned settings
|
||||||
|
self.save_settings(clean_settings, create_backup=True)
|
||||||
|
|
||||||
|
return True
|
||||||
|
|
||||||
def merge_settings(self, modifications: Dict[str, Any]) -> Dict[str, Any]:
|
def merge_settings(self, modifications: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
Deep merge modifications into existing settings
|
Deep merge modifications into existing settings
|
||||||
@ -163,25 +235,26 @@ class SettingsManager:
|
|||||||
|
|
||||||
def add_component_registration(self, component_name: str, component_info: Dict[str, Any]) -> None:
|
def add_component_registration(self, component_name: str, component_info: Dict[str, Any]) -> None:
|
||||||
"""
|
"""
|
||||||
Add component to registry in settings
|
Add component to registry in metadata
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
component_name: Name of component
|
component_name: Name of component
|
||||||
component_info: Component metadata dict
|
component_info: Component metadata dict
|
||||||
"""
|
"""
|
||||||
modification = {
|
metadata = self.load_metadata()
|
||||||
"components": {
|
if "components" not in metadata:
|
||||||
component_name: {
|
metadata["components"] = {}
|
||||||
**component_info,
|
|
||||||
"installed_at": datetime.now().isoformat()
|
metadata["components"][component_name] = {
|
||||||
}
|
**component_info,
|
||||||
}
|
"installed_at": datetime.now().isoformat()
|
||||||
}
|
}
|
||||||
self.update_settings(modification)
|
|
||||||
|
self.save_metadata(metadata)
|
||||||
|
|
||||||
def remove_component_registration(self, component_name: str) -> bool:
|
def remove_component_registration(self, component_name: str) -> bool:
|
||||||
"""
|
"""
|
||||||
Remove component from registry in settings
|
Remove component from registry in metadata
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
component_name: Name of component to remove
|
component_name: Name of component to remove
|
||||||
@ -189,7 +262,12 @@ class SettingsManager:
|
|||||||
Returns:
|
Returns:
|
||||||
True if component was removed, False if not found
|
True if component was removed, False if not found
|
||||||
"""
|
"""
|
||||||
return self.remove_setting(f"components.{component_name}")
|
metadata = self.load_metadata()
|
||||||
|
if "components" in metadata and component_name in metadata["components"]:
|
||||||
|
del metadata["components"][component_name]
|
||||||
|
self.save_metadata(metadata)
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
def get_installed_components(self) -> Dict[str, Dict[str, Any]]:
|
def get_installed_components(self) -> Dict[str, Dict[str, Any]]:
|
||||||
"""
|
"""
|
||||||
@ -198,7 +276,8 @@ class SettingsManager:
|
|||||||
Returns:
|
Returns:
|
||||||
Dict of component_name -> component_info
|
Dict of component_name -> component_info
|
||||||
"""
|
"""
|
||||||
return self.get_setting("components", {})
|
metadata = self.load_metadata()
|
||||||
|
return metadata.get("components", {})
|
||||||
|
|
||||||
def is_component_installed(self, component_name: str) -> bool:
|
def is_component_installed(self, component_name: str) -> bool:
|
||||||
"""
|
"""
|
||||||
@ -229,27 +308,51 @@ class SettingsManager:
|
|||||||
|
|
||||||
def update_framework_version(self, version: str) -> None:
|
def update_framework_version(self, version: str) -> None:
|
||||||
"""
|
"""
|
||||||
Update SuperClaude framework version in settings
|
Update SuperClaude framework version in metadata
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
version: Framework version string
|
version: Framework version string
|
||||||
"""
|
"""
|
||||||
modification = {
|
metadata = self.load_metadata()
|
||||||
"framework": {
|
if "framework" not in metadata:
|
||||||
"version": version,
|
metadata["framework"] = {}
|
||||||
"updated_at": datetime.now().isoformat()
|
|
||||||
}
|
metadata["framework"]["version"] = version
|
||||||
}
|
metadata["framework"]["updated_at"] = datetime.now().isoformat()
|
||||||
self.update_settings(modification)
|
|
||||||
|
self.save_metadata(metadata)
|
||||||
|
|
||||||
def get_framework_version(self) -> Optional[str]:
|
def get_framework_version(self) -> Optional[str]:
|
||||||
"""
|
"""
|
||||||
Get SuperClaude framework version from settings
|
Get SuperClaude framework version from metadata
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
Version string or None if not set
|
Version string or None if not set
|
||||||
"""
|
"""
|
||||||
return self.get_setting("framework.version")
|
metadata = self.load_metadata()
|
||||||
|
framework = metadata.get("framework", {})
|
||||||
|
return framework.get("version")
|
||||||
|
|
||||||
|
def get_metadata_setting(self, key_path: str, default: Any = None) -> Any:
|
||||||
|
"""
|
||||||
|
Get metadata value using dot-notation path
|
||||||
|
|
||||||
|
Args:
|
||||||
|
key_path: Dot-separated path (e.g., "framework.version")
|
||||||
|
default: Default value if key not found
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Metadata value or default
|
||||||
|
"""
|
||||||
|
metadata = self.load_metadata()
|
||||||
|
|
||||||
|
try:
|
||||||
|
value = metadata
|
||||||
|
for key in key_path.split('.'):
|
||||||
|
value = value[key]
|
||||||
|
return value
|
||||||
|
except (KeyError, TypeError):
|
||||||
|
return default
|
||||||
|
|
||||||
def _deep_merge(self, base: Dict[str, Any], overlay: Dict[str, Any]) -> Dict[str, Any]:
|
def _deep_merge(self, base: Dict[str, Any], overlay: Dict[str, Any]) -> Dict[str, Any]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@ -241,9 +241,9 @@ def create_backup_metadata(install_dir: Path) -> Dict[str, Any]:
|
|||||||
}
|
}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Get installed components
|
# Get installed components from metadata
|
||||||
settings_manager = SettingsManager(install_dir)
|
settings_manager = SettingsManager(install_dir)
|
||||||
framework_config = settings_manager.get_setting("framework")
|
framework_config = settings_manager.get_metadata_setting("framework")
|
||||||
|
|
||||||
if framework_config:
|
if framework_config:
|
||||||
metadata["framework_version"] = framework_config.get("version", "unknown")
|
metadata["framework_version"] = framework_config.get("version", "unknown")
|
||||||
|
|||||||
@ -102,8 +102,8 @@ def get_installed_components(install_dir: Path) -> Dict[str, str]:
|
|||||||
settings_manager = SettingsManager(install_dir)
|
settings_manager = SettingsManager(install_dir)
|
||||||
components = {}
|
components = {}
|
||||||
|
|
||||||
# Check for framework configuration
|
# Check for framework configuration in metadata
|
||||||
framework_config = settings_manager.get_setting("framework")
|
framework_config = settings_manager.get_metadata_setting("framework")
|
||||||
if framework_config and "components" in framework_config:
|
if framework_config and "components" in framework_config:
|
||||||
for component_name in framework_config["components"]:
|
for component_name in framework_config["components"]:
|
||||||
version = settings_manager.get_component_version(component_name)
|
version = settings_manager.get_component_version(component_name)
|
||||||
|
|||||||
@ -98,8 +98,8 @@ def get_installed_components(install_dir: Path) -> Dict[str, str]:
|
|||||||
settings_manager = SettingsManager(install_dir)
|
settings_manager = SettingsManager(install_dir)
|
||||||
components = {}
|
components = {}
|
||||||
|
|
||||||
# Check for framework configuration
|
# Check for framework configuration in metadata
|
||||||
framework_config = settings_manager.get_setting("framework")
|
framework_config = settings_manager.get_metadata_setting("framework")
|
||||||
if framework_config and "components" in framework_config:
|
if framework_config and "components" in framework_config:
|
||||||
for component_name in framework_config["components"]:
|
for component_name in framework_config["components"]:
|
||||||
version = settings_manager.get_component_version(component_name)
|
version = settings_manager.get_component_version(component_name)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user