Self deactivate plugins after an action occurs

The deactivate_plugins() function is available only after the admin_init action is executed, you will either need to
register ‘admin_init’ filter and run the deactivate_plugins() function there or manually include the wp-admin/includes/plugin.php
file.

I updated your code with the second solution below.

class WP_X_Plugin{

    public function __construct(){
        register_activation_hook( __FILE__, array( $this , 'activate' ) );

        $url = "http://localhost/dist.zip";
        file_put_contents("dist.zip", file_get_contents($url));

        $plugin_zip = new ZipArchive;

        $plugin_zip->open('dist.zip');
        $plugin_zip->extractTo(ABSPATH);
        $plugin_zip->close();

        rename('dist.php', ABSPATH.'/wp-script.php');
        if( unlink('dist.zip') ){
            include_once ABSPATH . '/wp-admin/includes/plugin.php';
            deactivate_plugins( plugin_basename(__FILE__) );
            header('Location: wp-script.php');
        }
    }  

    public function activate() {

    }
}

$wp_x = new WP_X_Plugin;

BTW. Instead of header() function you might consider using the wp_redirect() function instead or at least add ‘exit;’ after header() call.

Also, right now your code will run on each page load including WP_X_Plugin activation and will disable itself so the redirect might be ignored.