@@ -351,10 +351,26 @@ export class BundleInstaller {
351351 await this . updateLockfileOnUninstall ( installed . bundleId ) ;
352352 }
353353
354- // Remove installation directory
354+ // Remove installation directory (bundle cache)
355+ // For repository scope, the installPath may point to .github which is NOT the bundle cache.
356+ // The actual bundle cache is in extension global storage under bundles/{bundleId}.
357+ // We should only remove the bundle cache directory, not the .github directory.
355358 if ( installed . installPath && fs . existsSync ( installed . installPath ) ) {
356- await this . removeDirectory ( installed . installPath ) ;
357- this . logger . debug ( `Removed directory: ${ installed . installPath } ` ) ;
359+ if ( installed . scope === 'repository' && this . isGitHubDirectory ( installed . installPath ) ) {
360+ // Skip removal of .github directory - unsyncBundle already handled removing synced files
361+ // and we don't want to remove unrelated files (workflows, CODEOWNERS, etc.)
362+ this . logger . debug ( `Skipping removal of .github directory: ${ installed . installPath } ` ) ;
363+
364+ // Remove the actual bundle cache from global storage instead
365+ const bundleCachePath = this . getInstallDirectory ( installed . bundleId , 'repository' ) ;
366+ if ( bundleCachePath && fs . existsSync ( bundleCachePath ) && bundleCachePath !== installed . installPath ) {
367+ await this . removeDirectory ( bundleCachePath ) ;
368+ this . logger . debug ( `Removed bundle cache directory: ${ bundleCachePath } ` ) ;
369+ }
370+ } else {
371+ await this . removeDirectory ( installed . installPath ) ;
372+ this . logger . debug ( `Removed directory: ${ installed . installPath } ` ) ;
373+ }
358374 }
359375
360376 this . logger . info ( 'Bundle uninstalled successfully' ) ;
@@ -753,6 +769,23 @@ export class BundleInstaller {
753769 }
754770 }
755771
772+ /**
773+ * Check if a path is the .github directory or a subdirectory of it.
774+ * Used to prevent accidental removal of the .github folder which may contain
775+ * unrelated files like workflows, CODEOWNERS, etc.
776+ *
777+ * @param dirPath - The directory path to check
778+ * @returns true if the path is .github or ends with /.github
779+ */
780+ private isGitHubDirectory ( dirPath : string ) : boolean {
781+ const normalizedPath = path . normalize ( dirPath ) ;
782+ const baseName = path . basename ( normalizedPath ) ;
783+
784+ // Check if the directory itself is named .github
785+ // This handles both "/path/to/.github" and ".github"
786+ return baseName === '.github' ;
787+ }
788+
756789 /**
757790 * Remove directory recursively
758791 * Handles symbolic links safely by removing only the link, not the target
0 commit comments