fix: unify metadata location and improve installer UX

## Changes

### Unified Metadata Location
- All components now use `~/.claude/.superclaude-metadata.json`
- Previously split between root and superclaude subdirectory
- Automatic migration from old location on first load
- Eliminates confusion from duplicate metadata files

### Improved Installation Messages
- Changed WARNING to INFO for existing installations
- Message now clearly states "will be updated" instead of implying problem
- Reduces user confusion during reinstalls/updates

### Updated Makefile
- `make install`: Development mode (uv, local source, editable)
- `make install-release`: Production mode (pipx, from PyPI)
- `make dev`: Alias for install
- Improved help output with categorized commands

## Technical Details

**Metadata Unification** (setup/services/settings.py):
- SettingsService now always uses `~/.claude/.superclaude-metadata.json`
- Added `_migrate_old_metadata()` for automatic migration
- Deep merge strategy preserves existing data
- Old file backed up as `.superclaude-metadata.json.migrated`

**User File Protection**:
- Verified: User-created files preserved during updates
- Only SuperClaude-managed files (tracked in metadata) are updated
- Obsolete framework files automatically removed

## Migration Path

Existing installations automatically migrate on next `make install`:
1. Old metadata detected at `~/.claude/superclaude/.superclaude-metadata.json`
2. Merged into `~/.claude/.superclaude-metadata.json`
3. Old file backed up
4. No user action required

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
kazuki
2025-10-20 03:49:13 +09:00
parent f592aad633
commit 328a0a016b
3 changed files with 80 additions and 22 deletions

View File

@@ -720,8 +720,8 @@ def run(args: argparse.Namespace) -> int:
# Check for existing installation
if args.install_dir.exists() and not args.force:
if not args.dry_run:
logger.warning(
f"Installation directory already exists: {args.install_dir}"
logger.info(
f"Existing installation found: {args.install_dir} (will be updated)"
)
if not args.yes and not confirm(
"Continue and update existing installation?", default=False