@@ -2799,13 +2799,53 @@ def extension_update(
27992799 f"Extension ID mismatch: expected '{ extension_id } ', got '{ zip_extension_id } '"
28002800 )
28012801
2802- # 7. Remove old extension (handles command file cleanup and registry removal)
2802+ # 7. Backup existing config files (if any) before removal
2803+ config_backup_dir = None
2804+ if backup_registry_entry :
2805+ existing_path = backup_registry_entry .get ("path" )
2806+ if existing_path :
2807+ existing_install_dir = Path (existing_path )
2808+ if existing_install_dir .is_dir ():
2809+ # Create a temporary directory to hold backed-up config files
2810+ config_backup_dir = Path (
2811+ tempfile .mkdtemp (prefix = "speckit-ext-config-" )
2812+ )
2813+ for cfg_file in existing_install_dir .glob ("*-config*.yml" ):
2814+ try :
2815+ shutil .copy2 (cfg_file , config_backup_dir / cfg_file .name )
2816+ except OSError :
2817+ # Best-effort backup; skip files that cannot be copied
2818+ pass
2819+
2820+ # 8. Remove old extension (handles command file cleanup and registry removal)
28032821 manager .remove (extension_id , keep_config = True )
28042822
2805- # 8 . Install new version
2823+ # 9 . Install new version
28062824 _ = manager .install_from_zip (zip_path , speckit_version )
28072825
2808- # 9. Restore metadata from backup (installed_at, enabled state)
2826+ # 10. Restore backed-up config files into the new install directory (if any)
2827+ if config_backup_dir is not None :
2828+ new_registry_entry = manager .registry .get (extension_id )
2829+ new_install_dir = None
2830+ if new_registry_entry is not None :
2831+ new_path = new_registry_entry .get ("path" )
2832+ if new_path :
2833+ new_install_dir = Path (new_path )
2834+ if new_install_dir is not None and new_install_dir .is_dir ():
2835+ for cfg_file in config_backup_dir .glob ("*-config*.yml" ):
2836+ try :
2837+ shutil .copy2 (cfg_file , new_install_dir / cfg_file .name )
2838+ except OSError :
2839+ # Best-effort restore; skip files that cannot be copied
2840+ pass
2841+ # Clean up the temporary backup directory
2842+ try :
2843+ shutil .rmtree (config_backup_dir , ignore_errors = True )
2844+ except OSError :
2845+ # Ignore cleanup errors; they do not affect functionality
2846+ pass
2847+
2848+ # 11. Restore metadata from backup (installed_at, enabled state)
28092849 if backup_registry_entry :
28102850 # Copy current registry entry to avoid mutating internal
28112851 # registry state before explicit restore().
0 commit comments