It should be possible to carefully adjust the destination path via the upgrader_package_options
filter in WordPress, before the upgrader installs the new version of it.
Here’s a barebone example that appends the plugin’s current directory name to the destination path, if it’s same as WP_PLUGIN_DIR
(see check in core here), when the package url is a github.com
domain:
add_filter( 'upgrader_package_options', function( $options ) {
$destination = $options['destination'] ?? '';
$package = $options['package'] ?? '';
$dirname = isset( $options['hook_extra']['plugin'] )
? dirname( $options['hook_extra']['plugin'] )
: '';
if ( empty( $dirname ) || '.' === $dirname ) {
return $options;
}
if ( 'github.com' !== parse_url( $package, PHP_URL_HOST) ) {
return $options;
}
if ( WP_PLUGIN_DIR === $destination ) {
$options['destination'] = path_join( $destination, $dirname );
}
return $options;
});