Skip to content

About

Install, verify, repair and uninstall Windows audio plugins in an ableton-linux Wine prefix (VST3/VST2/AAX) - CLI + Qt GUI

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Latest commit

 

History

37 Commits

Folders and files

Repository files navigation

Absolute

Wine Plugin Toolkit (wpt)

release licence python platform

WPT is a Linux-side manager for supported Neural DSP Windows plugins. It installs, inventories, repairs and removes plugin files in an ableton-linux Wine prefix, and can launch installed standalone apps.

Developed on CachyOS with the ableton-linux stack. The GUI can save and switch between Wine and prefix profiles. Set up PipeASIO separately through ableton-linux; WPT does not configure audio routing. The 0.6.5 file-manifest, install-plan and uninstall paths have synthetic-prefix tests only. The profile-based standalone launcher has fake-Wine tests only. Neither has live-prefix validation. See verification limits.

The Download tab, dark mode

Contents

Install

Choose your distro below. The release includes a ready-to-install package for Arch-based systems. Other distributions install from the verified source archive in an isolated Python environment.

These commands install WPT. wpt doctor reports missing system tools but does not install them. The Arch updater can install a WPT update with pacman when you choose it. Before using WPT, set up the ableton-linux Wine prefix and staged Wine tree. Configure PipeASIO separately if you need audio. Back up the prefix before install, repair or uninstall operations. These steps do not install Neural DSP plugins or Wine.

Arch / CachyOS (recommended)
  1. Download the wine-plugin-toolkit package and matching .sha256 file from the latest release.

  2. In the download folder, verify and install the exact package you downloaded. Replace the version and package revision below if the release is newer:

    cd ~/Downloads
    VERSION=0.6.5
    PKGREL=1
    PACKAGE="wine-plugin-toolkit-${VERSION}-${PKGREL}-any.pkg.tar.zst"
    sha256sum -c "${PACKAGE}.sha256"
    sudo pacman -U "$PACKAGE"

    Pacman installs the required Python and msitools dependencies. For the GUI, also install the optional pyside6 package with sudo pacman -S pyside6.

  3. Run wpt doctor. Launch the window with wpt-gui.

Build the Arch package from source instead

Install base-devel, then download the source archive and checksum from the release page. Verify and extract the exact archive before building:

sudo pacman -S base-devel
cd ~/Downloads
VERSION=0.6.5
SOURCE_TARBALL="wpt-${VERSION}.tar.gz"
sha256sum -c "${SOURCE_TARBALL}.sha256"
tar xzf "$SOURCE_TARBALL"
cd "wine-plugin-toolkit-${VERSION}"
SRCDEST="$HOME/Downloads" makepkg -si
Debian / Ubuntu and derivatives
  1. Install the system requirements. WPT needs Python 3.11 or newer; some older distro releases ship an older default, so check the version first.

    python3 --version
    sudo apt install python3 python3-venv msitools

    If the distro's python3 is older than 3.11, install a supported Python version and its matching venv package. In step 3, use that interpreter in place of python3 (for example, python3.11).

  2. Download the wpt-<version>.tar.gz archive and matching checksum from the latest release, then verify and extract it. Replace 0.6.5 with the release version you downloaded.

    cd ~/Downloads
    VERSION=0.6.5
    SOURCE_TARBALL="wpt-${VERSION}.tar.gz"
    sha256sum -c "${SOURCE_TARBALL}.sha256"
    tar xzf "$SOURCE_TARBALL"
    cd "wine-plugin-toolkit-${VERSION}"
  3. Install into a stable virtual environment and check the setup. The command includes the GUI extra.

    python3 -m venv "$HOME/.local/share/wpt/venv"  # create once, reuse for updates
    "$HOME/.local/share/wpt/venv/bin/python" -m pip install --upgrade '.[gui]'
    "$HOME/.local/share/wpt/venv/bin/wpt" doctor

    For CLI-only use, replace '.[gui]' with . in the install command. To open the GUI:

    "$HOME/.local/share/wpt/venv/bin/wpt-gui"
Fedora
  1. Install the system requirements. WPT needs Python 3.11 or newer.

    python3 --version
    sudo dnf install python3 python3-pip msitools
  2. Download the wpt-<version>.tar.gz archive and matching checksum from the latest release, then verify and extract it. Replace 0.6.5 with the release version you downloaded.

    cd ~/Downloads
    VERSION=0.6.5
    SOURCE_TARBALL="wpt-${VERSION}.tar.gz"
    sha256sum -c "${SOURCE_TARBALL}.sha256"
    tar xzf "$SOURCE_TARBALL"
    cd "wine-plugin-toolkit-${VERSION}"
  3. Install into a stable virtual environment and check the setup. The command includes the GUI extra.

    python3 -m venv "$HOME/.local/share/wpt/venv"  # create once, reuse for updates
    "$HOME/.local/share/wpt/venv/bin/python" -m pip install --upgrade '.[gui]'
    "$HOME/.local/share/wpt/venv/bin/wpt" doctor

    For CLI-only use, replace '.[gui]' with . in the install command. To open the GUI:

    "$HOME/.local/share/wpt/venv/bin/wpt-gui"
Other Linux distributions

Install Python 3.11 or newer, its venv support, and msitools using your distro's package manager. Then follow the source-install steps above. GUI installs use the .[gui] extra; the optional wrapper unpackers may improve support for wrapped installers; package names vary by distro.

For later terminal sessions, activate the source-installed environment before using the commands below:

. "$HOME/.local/share/wpt/venv/bin/activate"

To remove a source install, remove only its venv directory. The sibling presets directory may contain rescued user data.

Requirements

  • Linux x86-64 and Python 3.11 or newer. On Debian/Ubuntu, check python3 --version because the distro default may not meet this requirement.
  • msitools for reading and unpacking MSI packages.
  • A prepared ableton-linux Wine prefix with drive_c (default ~/.wine-ableton), plus a staged tree under ~/.local/opt/wine-d2d1-nspa-<version> containing bin/wine.
  • PySide6 is optional and needed only for the GUI. Source installs include it with the .[gui] extra.
  • The GUI can save and switch between profiles that select a Wine tree and prefix. WPT does not bundle the Wine runtime, install or configure PipeASIO, select audio devices or route audio. Configure PipeASIO through ableton-linux before expecting audio. Run in Standalone, installer fallbacks that require Windows code, a registered uninstall, and registry removal with --purge need the selected tree's working bin/wine. MSI metadata and supported file operations can use msitools without launching Wine. WPT selects the newest matching staged tree and does not promise every Wine build or patch set works with every plugin.

For non-default paths, set WINEPREFIX or pass the global --prefix and --tree options before the subcommand. --home is a discovery override, not a general HOME override; it changes the home used for Wine-tree/product discovery and the rescue-store check in wpt doctor. It does not change the Wine prefix or redirect the preset store used by presets and uninstall, update cache/config or Downloads search. Those use the current $HOME/XDG locations. When --home differs from $HOME, doctor may inspect a different rescue store from the one uninstall writes to.

After installation, start with:

wpt doctor
wpt env
wpt list

doctor reports missing tools and the suggested fix. To point it at a non-default stack, put the global options before the subcommand. Replace 11.13 with your installed tree version:

wpt --prefix "$HOME/.wine-ableton" --tree "$HOME/.local/opt/wine-d2d1-nspa-11.13" doctor

Source installs are separate from the Arch package. wpt update updates Arch packages only; update a source install by installing the newer source release into its virtual environment.

What it does

  • Installs a plugin from the vendor's MSI, or from the vendor's .exe installer, by unpacking it with msitools and placing the payload itself.
  • Checks each selected MSI File row at its full destination path, including bundle internals, against its declared byte size. This is not a content-hash or component-state audit (see verification limits).
  • Attempts repair of missing or wrong-sized File-table files from a cached MSI; preset no-clobber rules can leave a mismatch unresolved, and a same-size edit is not detectable.
  • Uninstalls stage/read the MSI before the default registered removal route. That route attempts preset rescue before Wine's msiexec /x. A failed rescue stops the job whenever rescue is required by the selected route. The toolkit's direct remover preserves modified files, no-clobber files, known cross-product paths, and files whose MSI component state is uncertain. Registered uninstalls stop before vendor removal when the payload is unavailable, the cached-MSI ownership scan is incomplete, or another cached product claims a planned path. --files-only skips Wine on the CLI. Wine's vendor uninstall can still remove other files; back up your data (see uninstall limits).
  • Inventories what is installed, and finds installs that registered but never copied their files.
  • Hides and restores a plugin from your DAW's scanner with a reversible rename.
  • Attempts Linux extraction first for recognised 7-Zip, Inno, InstallShield, NSIS, Burn and CAB wrapper families when the corresponding unpacker is installed. This is not a promise that every vendor installer works without Wine; Advanced Installer (including Neural DSP) needs Wine.

Why this exists

Some vendor MSIs assume Windows behavior Wine does not provide on these paths:

  1. a bootstrapper-only launch condition, like SETUPEXEDIR OR (REMOVE="ALL"), so msiexec /i cannot succeed (error 1603);
  2. JScript custom actions built on Scripting.FileSystemObject and WScript.Shell: Wine's stubs answer Object doesn't support this action, the install copies nothing (error 103) and still registers the product as installed;
  3. an invisible maintenance dialog on some upgrade paths, which Wine may not paint, leaving the installer waiting until the process is stopped.

For supported packages, msitools can read and unpack the MSI on Linux. This tool uses that route to place selected payload files and check them afterwards; package-specific behavior still needs validation. The case that started it: an Archetype plugin upgrade where the wrapper hung at "Starting install" with an empty progress bar, msiexec failed twice, and the prefix claimed the product was installed while not one plugin file existed on disk.

Coming from Windows

Licensing and files. Removing plugin files does not free or transfer an iLok activation; handle activation separately through the vendor or iLok. WPT writes plugin files inside the prefix and may also use scratch space, preset-rescue storage and exports outside it. Wine's own uninstall can affect host paths mapped into the prefix, so back up important data first.

What you need first. Prepare the prefix and staged Wine tree using the ableton-linux project. WPT works with that configured stack; it does not replace the runtime setup or guarantee every vendor installer will work. For supported packages, WPT can extract and verify MSI payloads on Linux. Installers that require Windows code run through the selected Wine tree.

Your plugin installers. Move the .exe and .msi files you downloaded on Windows into ~/Downloads on Linux (a USB stick or your network drive is fine). Then:

wpt pending         # what installers are sitting there, and are they installed already
wpt install ~/Downloads/ArchetypeNollyXv1.0.2.exe

pending guesses the product and version from the file name, and says whether that version is already in the prefix. install reads the installer and shows planned destinations (a directory may contain more files than the preview lists) before writing them. It refuses to create a second destination whose spelling differs only by case. Add --dry-run to preview prefix writes without placing plugin files; staging/extraction can still write to scratch.

Your own presets, sounds and MIDI maps. These are the one thing a reinstall cycle cannot bring back. Copy them off the Windows machine (usually Documents\Neural DSP\..., or wherever you saved your own sounds) into the prefix, or keep them somewhere safe on this machine, then:

wpt presets                                     # what is in the prefix now
wpt presets --export ~/Documents/my-presets     # copy it all out to a plain folder

Factory and artist presets come back with a reinstall. Yours do not, so back them up before you uninstall anything. wpt uninstall rescues recognised presets and attempts to copy regular files it can enumerate under planned no-clobber paths before Wine; a detected symlink or failed copy stops removal. When WPT has a readable File-table plan, the CLI and GUI refuse an uninstall before rescue or msiexec if a planned prefix path is symlinked or case-insensitively ambiguous. WPT cannot prove that every user file was discovered; Wine may delete originals, and other personal files may not be identified. Keep your own backup. --no-rescue skips the CLI backup; --files-only avoids msiexec on the CLI. --no-files skips the plan/preflight and still delegates to Wine, so its file effects are not bounded by WPT.

Activation and iLok. Some vendors use iLok (PACE) or an account-based licence. The toolkit does not touch licensing, and deleting plugin files never returns a licence slot. If a plugin was activated on a prefix you are retiring, deactivate it in iLok License Manager first. If that location is already broken or unreachable, use Report as Unusable there so the slot comes back. This trips people up, so it is repeated in the uninstall warning.

Things that will not work here.

  • Drivers. Some downloads are drivers or helper applications, not plugins: Neural DSP's Nano Cortex package is a Windows USB driver plus a control panel. Those are refused by default, with the reason and the folder their files wanted. Placing a driver's files by hand does not install it because drivers need their INF and service registration.
  • Linux-native plugins. This manages Windows plugins inside a Wine prefix. A Linux VST3 or CLAP belongs in your normal Linux plugin directories and has nothing to do with this.
  • macOS and Windows prefixes. Out of scope.

Command line

All of it is one CLI. Every command has --help, and list and pending take --json when you want to paste machine-readable state into a bug report.

wpt doctor                  # check everything it needs, and say what is wrong
wpt env                     # tree, prefix, Windows user, every plugin directory
wpt list                    # inventory: what is installed, and is each file intact
wpt scan                    # installs that registered but never copied their files
wpt products                # triage every product in every Wine prefix on this machine
wpt pending                 # installers downloaded but not installed yet
wpt find-msi                # vendor MSIs already unpacked inside the prefix
wpt inspect <msi>           # identity, install targets, launch conditions, payload
wpt plan <msi>              # extract and show planned destinations
wpt install <msi> --dry-run # preview prefix writes; extraction still uses scratch
wpt install <msi>           # do it, then run the current (limited) size checks
wpt install ~/Downloads/VendorSetup.exe   # or point it straight at the vendor's .exe
wpt repair --product Rabea  # attempt to re-place missing/detected wrong-sized files
wpt disable Nolly           # hide a plugin from the DAW scanner (a plain rename)
wpt enable Nolly            # bring it back
wpt uninstall --product X   # see the uninstall limits below before running for real
wpt wrappers                # identify every .exe installer around, and its route to an MSI
wpt presets                 # your presets and downloaded packs, and what has been rescued

list and scan are complementary. list walks the plugin directories and answers "what is there". scan walks the prefix registry and answers "what do the installers claim is there". A plugin in neither is not installed. A plugin that shows in scan but not list is the failure this tool was written for: registered, with the files missing.

Useful options. Global flags must come before the subcommand (for example, wpt --prefix PREFIX --tree TREE list); operation flags follow the command:

flag why
--product <substring> pick an MSI from the prefix without typing the path (--product Rabea)
--dry-run preview planned destinations without applying prefix changes; MSI staging/extraction still writes to scratch. A directory is one row even if it contains other files; external Wine effects are not predicted.
--no-vst2 / --no-standalone / --no-presets skip parts you do not want
--aax include the AAX plugin (Pro Tools only, off by default)
--scratch <dir> where the payload is extracted (default /tmp/wpt-extract)
--home <dir>, --prefix <dir>, --tree <dir>, --user <name> global: set discovery home, Wine prefix/tree or Windows user; place before the subcommand. See the home-scope note above.
--json machine-readable output, for a bug report

Most CLI exit codes: 0 ok · 1 verification, scan or system error · 2 bad input · 3 environment not found · 4 msitools error, external-tool timeout or uninstall preflight read/safety failure · 5 catalogue error · 130 interrupted.

For uninstall, 1 includes rescue, msiexec (including timeout), post-msiexec verification, file removal or registry purge failures; unexpected system errors also return 1. Missing MSI or ProductCode input is 2. 4 covers an MSI/plan preflight read failure or safety refusal. wpt doctor uses 0/1/2 for clean/warning/failure, as described below.

The vendor's .exe, and the MSI inside it

Vendors ship a .exe whose real payload is an MSI, which is all this tool can read. wpt install takes either, and gets from one to the other by the cheapest route that works:

  1. it is already an MSI: use it;
  2. the wrapper has been run before, so its MSI is already cached in the prefix: use that, run nothing;
  3. an unpacker that suits the wrapper's format can pull an MSI out of it: done, no Wine;
  4. otherwise it runs the vendor installer under Wine once (--run-wrapper, or the GUI asks first) and picks up the MSI that lands in the prefix.

The wrapper's format decides which tool is tried, and saying what a file is comes before spending minutes on it:

wpt wrappers                              # every .exe installer around, and its route
wpt wrappers --file ~/Downloads/X.exe     # one file in detail
wpt wrappers --file ~/Downloads/X.exe --unpack   # actually unpack it and report
family how it is recognised route
Advanced Installer (LZMA) Caphyon / Advanced Installer Wine only: no Linux tool reads it
NSIS \xEF\xBE\xAD\xDE at offset 0 7z, then cabextract
Inno Setup Inno Setup Setup Data, JR.Inno.Setup innoextract, then 7z
InstallShield InstallShield, setup.inx, data1.cab unshield, 7z, cabextract
WiX Burn bundle WixBundle / wixburn 7z, then cabextract (the payload is an appended cabinet)
7-Zip self-extractor the 7z signature 7z
IExpress / CAB self-extractor IExpress, MSCF cabextract, then 7z
anything unrecognised nothing matches every installed unpacker, in turn

Two details that make this work on real files rather than tidy ones:

  • containers are found by content, not by name. A Burn bundle hands its payload over as members called a0 to a13, and a self-extractor as [0], so *.cab and *.msi are not the search: the cabinet magic (MSCF) and the MSI magic (an OLE compound document) are. Verified on vc_redist.x64.exe, whose a10 is read by msitools as Microsoft Visual C++ 2022 X64 Additional Runtime.
  • architecture is chosen deliberately. Wrappers that carry every architecture (arm64/, x86/, x64/, same file name inside each) default to x64, and a wrapper named ...-win-x86 never resolves to the bigger x64 MSI just because it is bigger. Where a wrapper holds several MSIs, the one used is named and the rest are reported.

Neural DSP wrappers are Advanced Installer packages whose payload is an AI LZMA stream, which no Linux tool can unpack (7z lists the PE and hands you a blob it cannot open). For those the Wine step is what actually works, and the tool says so instead of leaving you guessing: a wrapper identified as that family is refused immediately, with the reason.

Not every vendor download is a plugin. Drivers and helper applications are refused by default, with the reason and the destination their files wanted:

wpt install "~/Downloads/NeuralDSP Nano Cortex v5.74.0.exe"
nothing a DAW can use: this package is an application or a driver, not a plugin.
  PFiles64 payload would go to .../Program Files/NeuralDSP/NeuralDSP Nano Cortex Driver v5.74.0
  Its own installer (or the vendor's .exe under Wine) is what installs it
  properly - drivers need their INF and service registration, which placing
  files by hand does not do. Pass --include-app-files to place them anyway.

Pass --include-app-files to have those placed anyway (subject to the size-check limits above), knowing no DAW will see them. A plugin package is unaffected by this rule: its own standalone app is still installed.

Plugins that come from a download page (Neural DSP)

wpt catalogue                 # every plugin they ship, current version, where it lives
wpt catalogue --open-page      # open their full downloads list, every plugin's page in one view
wpt catalogue --refresh        # re-read their page (otherwise a bundled snapshot is used)
wpt catalogue --open nolly     # open one plugin's download page in your browser
wpt catalogue --download "Cortex Control"   # public CDN links only (hardware and manuals)

Why it opens a page instead of downloading for you: the plugin links are behind a sign-in and are licence-bound, so nothing outside your browser can fetch them. The hardware and manual links are public, and --download does fetch those.

Presets and IRs

wpt presets                                     # yours, the packs, and what has been rescued
wpt presets --export ~/Documents/my-presets     # copy them all out to a plain folder
wpt presets --sources                           # where to get more: repositories, vaults, shops
wpt presets --open "Preset Junkie" --product "Nolly X"

Presets and user files may not be recoverable after an install or uninstall. Back them up first. Factory and artist presets usually come back with a reinstall. Your own (<product>/User/*.xml), downloaded packs (<vendor>/<vendor>/<Pack> Presets/) and hand-made MIDI maps may not. The toolkit attempts to copy presets it recognises to ~/.local/share/wpt/presets/<product>/<timestamp>/ before both Wine's msiexec /x and its own file deletion, without overwriting an existing rescue. A failed rescue copy stops the job. The GUI has no --files-only equivalent. The toolkit now leaves files outside the exact File-table manifest in place, but Wine's msiexec /x can still remove them. Back up your files before uninstalling. --no-rescue skips the toolkit's rescue; it is not a safety option.

The toolkit does not fetch presets from the internet, deliberately: the community repositories want a sign-in, one vault sits behind a bot filter, and the shops want money. What it does is open the right page in your browser, pre-filled with the plugin you are looking at. Where a site's search URL could not be verified, no search parameter is invented: you get the front page.

Updates

wpt update                # query the latest release live; add --cached to reuse a saved result
wpt update --install      # download it, verify it, then print the pacman line
wpt update --install run  # ...and open a terminal to install it, then reopen the app

The GUI checks quietly at startup, keeps the answer for a day, and puts Check for updates in its toolbar. Installing always happens in a visible terminal running sudo pacman -U, which means the app closes first so pacman can replace its own files, then reopens when the install finishes. It never escalates privileges on its own. Downloads are checked against the release's published sha256 when there is one, and refused unless the file really is a pacman package. WPT_NO_UPDATE_CHECK=1 turns the startup check off, and "Skip this version" silences one release.

When something is wrong

wpt doctor              # tree, prefix, permissions, tools, cached MSIs, inventory, GUI
wpt doctor --json       # the same, machine-readable: paste this into a bug report

It checks the things that actually break this kind of tool: a Wine tree that is not the staged one, msitools missing, a plugin directory that is not writable, no cached MSI to verify sizes against, a scratch directory it cannot write to, PySide6 absent. Each check says what to do about it, and the exit code is usable from a script: 2 for something that must be fixed, 1 for optional things missing, 0 for clean.

symptom what it usually means
env cannot find a Wine tree no staged ~/.local/opt/wine-d2d1-nspa-*, or yours is elsewhere: pass --tree
a plugin reads unverified the MSI for it is not cached in the prefix, so there is no size to compare. Repair and uninstall need that MSI
the vendor .exe hangs at "Starting install" expected for Advanced Installer wrappers: it is a Wine limitation, and wpt wrappers --file X.exe will say so before you spend the time
an install reports 0 destinations the package is an application or a driver, not a plugin. The log says which
the GUI will not start pyside6 is not installed (wpt doctor says so), or you are on a headless session
a plugin vanished from your DAW check the Plugins tab for a disabled state, or wpt list: disable is a rename, and wpt enable undoes it

Shell completions

wpt completions fish > ~/.config/fish/completions/wpt.fish
wpt completions bash | sudo tee /usr/share/bash-completion/completions/wpt
wpt completions zsh  | sudo tee /usr/share/zsh/site-functions/_wpt

Generated from the real argument parser, so they cannot drift as commands are added. The Arch package installs all three.

GUI

wpt-gui

Six tabs, in the order you use them, each a thin wrapper over the same core functions as the CLI:

  • Environment: choose Auto-detected or a saved launch profile. Manage profiles… stores a profile name, Wine prefix, custom Wine tree and literal NAME=VALUE environment overrides. The selected prefix/tree are used by WPT operations and Run in Standalone, so inventory and launch stay on the same prefix; environment overrides are passed only to Run in Standalone, not to installs, repairs or uninstalls. They are literal environment variables only: WPT does not load or modify a PipeASIO config file or audio routing. Changing prefix/tree clears prefix-derived lists and reports; refresh those views before acting. Profiles live in ~/.config/wpt/launch_profiles.json (or $XDG_CONFIG_HOME/wpt/launch_profiles.json), with mode 0600; values are plain text, so do not store passwords or tokens. Overrides are literal, not shell commands, and cannot replace Wine's selected prefix/runtime or its user identity. Already-open WPT windows keep their current stack until Re-detect; stale profile writes are refused. Removing the active profile falls back to Auto-detected with a warning. The Environment tab also shows the active tree, prefix, Windows user and plugin directories, and warns if msitools is missing.
  • Plugins: the inventory. Kind, size, and an integrity verdict against the cached MSI (ok, unverified, BROKEN), plus a State column for disabled plugins. The buttons act on the selected row: Repair selected from cached MSI, Disable (hide from DAW) or Enable, Uninstall. Right-click a row for the same actions plus the file's path, preset sites, Browse local files and (when one exact-name .exe exists under this prefix's Program Files) Run in Standalone through the selected profile's custom Wine tree and environment. Unverified MSI ownership is marked in the action; the app may contact its licensing service. Program Files (x86) is not searched. Standalone apps run under the selected Wine profile. WPT does not install or configure PipeASIO, select audio devices or manage routing; configure the audio stack separately through ableton-linux. Within one WPT window, multiple apps can be launched under its active profile; tracked groups block profile changes, prefix writes and update restarts while active. WPT starts each launcher in a separate session and does not signal it when the window closes. Vendor apps may impose their own concurrency limits. Closing with active groups requires Close WPT; don't stop apps; the default and Escape keep WPT open. Closing ends that window's tracking; reopened or separate WPT windows do not rediscover earlier launches. Close those apps, detached helpers and licensing services before using WPT to modify the prefix.
  • Download: Neural DSP's catalogue, with version, release date, whether it is installed here and whether an installer is already in ~/Downloads. Download Selected Plugin opens its page in your browser; the Preset & IR sources row opens preset sites for the plugin you have selected.
  • Pending Install: installers sitting in ~/Downloads or the prefix root that are not installed yet, or are an upgrade. Install selected runs the same extract, place and size checks as the CLI, one plugin at a time. This is the staging step: download on the previous tab, install on this one.
  • Install MSI: pick or browse an MSI, choose VST3 / VST2 / standalone / presets, Preview plan then Install. A results table and a log show the current, limited size checks.
  • Diagnostics: scans the prefix registry for plugin paths that do not exist on disk, lists the products it registers (runtimes hidden), and Triage products in every Wine prefix reports what every prefix on the machine holds and which entries are debris.

Long operations are dispatched to worker threads; this is not a guarantee that no GUI path can block. A disabled plugin stays visible, flagged disabled, so it can be brought back.

How it verifies

The toolkit does not take an installer's exit status as proof of correct file placement. In this version it checks selected File-table paths, but size is not a content hash:

  • the plan maps Directory/Component/File rows to full destination paths. Payload builds reject a missing, extra or wrong-sized extracted file before copying; tables-only plans cannot install;
  • verify_plan compares each selected File-table file's size, including bundle internals and zero-byte files. Two different rows with one case-insensitive destination are refused;
  • BROKEN in list is a size mismatch at a full path; unverified means there is no unique mapped MSI owner; ok means that one file's size agrees with its MSI row. It cannot prove its bytes are unchanged or that every optional MSI component was installed;
  • state is cross-checked two ways: the plugin directories (list) and the prefix registry (scan);
  • GUI Run in Standalone requires one exact-name, non-symlink .exe under the active profile's Program Files; Program Files (x86) is not searched. It uses the selected profile's Wine tree, prefix and standalone-only environment overrides, and refuses a verified executable if its size changed since inventory (refresh to retry). Logs go to absolute $XDG_CACHE_HOME/wpt/standalone/; if it is unset or non-absolute, WPT falls back to ~/.cache/wpt/standalone/. Logs are retained, not auto-pruned. wpt/standalone.py uses start_new_session=True. The GUI test checks two synthetic fake-Wine child process groups survive WPT close; standalone_process_detach_check.py checks a child survives its launcher interpreter exiting. Neither test exercises real Wine, vendor software, licensing or services. Size agreement is not a content hash;
  • wpt doctor checks the surrounding environment. GUI suites exercise tabs offscreen on a machine with PySide6; they do not replace real-desktop checks.

The remaining real-MSI, feature-state and release-artifact acceptance criteria are in the claim ledger and the design review map. Do not interpret an ok result as a complete MSI payload audit.

Scope and limitations

  • Earlier 0.6.4 work exercised Neural DSP installers (Advanced Installer and MSI) against a real Wine prefix. That is historical evidence, not a real-install or live-uninstall validation of the manifest/uninstall changes in 0.6.5. This version has read-only table/listing comparisons and disposable-prefix tests; no real prefix has been modified to test those changes.
  • Wrapper families: the recorded real-wrapper examples cover a 7-Zip self-extractor (a Neural DSP hardware wrapper), WiX Burn bundles (vc_redist and dotnet-runtime) and Advanced Installer (refused as Wine-only). The other named families are code paths, not a claim that a real installer of each family has passed. Known gap: innoextract on a current Arch is older than the newest Inno Setup releases, so a brand-new Inno installer is identified but not opened. The tool says which version it could not read rather than pretending.
  • unshield is used for InstallShield if it is installed, but it is not part of the base install. Without it, InstallShield wrappers fall through to 7z and cabextract, and then to Wine.
  • Only files a plugin MSI describes count as plugins. Wine's own tools (iexplore.exe, wordpad.exe, wmplayer.exe) and other vendors' helpers (Bonjour, iLok) sit in the same directories and are not. They are counted in one line of list output, and shown on request with --all-standalone (the GUI has a show other .exe files box). Same rule for the MSI picker.
  • scan's list of present paths can include a plugin's support dlls (Qt's qwindows.dll and friends live in plugin directories and are legitimate entries). They are not noise to filter blindly, just more entries than the four paths you may be looking for.
  • uninstall reads the MSI before it runs msiexec /x. Windows Installer can delete its cached MSI during removal, and that cache may be the only copy the toolkit can find. The ProductCode and plan are read first, and the MSI is staged out of reach. If it cannot be read, the toolkit stops before prefix removal; scratch staging may already have written temporary files. Once msiexec removes the registration and the cache, no MSI may be left to describe the product: wpt uninstall --product X then says so and lists what the prefix still holds under that name, rather than pretending.
  • Uninstall boundaries. For a registered product, WPT runs msiexec /x only after reading the MSI and passing its payload and cached-owner checks. It refuses the default registered uninstall before vendor removal if payload bytes are unavailable, the selected MSI has an unmapped root, any cached-MSI ownership map is unreadable/unmapped, or another product claims a planned path. Unsafe fallback Manufacturer/ProductName path components also refuse planning. This broad fail-closed scan may block removal because of an unrelated cached MSI. If no product is registered, the CLI and GUI skip msiexec. A non-zero msiexec result, or a zero exit while registration remains or cannot be read, stops subsequent direct file removal and registry purge. In file-only/unregistered cleanup, WPT compares eligible files with the exact MSI payload bytes and declared size, and preserves modified, no-clobber, shared, and component-state-uncertain files as leftovers. It prunes empty parents, not entire directories. Install plans also refuse optional, conditioned, source-only, shared-reference, permanent, transitive, Shared or NeverOverwrite components because component-selection state is unavailable. FeatureComponents/feature-level selection is not modelled. Repair and inventory still use size checks, so same-size edits can remain undetected there. Preset rescue happens before msiexec; WPT uses the selected MSI's Manufacturer when locating its ProgramData tree and strictly attempts to copy regular files under planned no-clobber paths and recognized Roaming/MIDI XML paths. Existing no-clobber files without a successful rescue result, traversal/stat errors, detected symlinks, unsupported file types or copy failures stop the job. Roaming/MIDI XML maps are strictly traversed under inferred paths, but product-name lookup and uninspected custom actions do not prove complete discovery; this is not a complete backup guarantee. Wine may still affect other user files or host-mapped paths (such as Desktop). Back up user data and inspect --dry-run; the GUI has no --files-only route. On the CLI, --files-only skips Wine's registration removal and preserves refused paths. --no-files skips WPT's plan, removal, and rescue, but Wine can still delete files; it also skips shared-file ownership checks, so msiexec /x may remove files another product claims. --no-rescue also bypasses the CLI backup. --purge is gated on successful vendor uninstall and the absence of remaining mapped MSI files; a matching basename or product name alone is not proof. --dry-run lists mapped files and known refusals, not every external Wine effect; staging/extraction may still write to scratch. Purging never frees an activation.
  • Which MSIs the tool can see. Sizes are cross-checked against the MSIs cached inside the prefix: a vendor's own folder (AppData/Roaming/Neural DSP/...), ProgramData/Package Cache, and Wine's Windows Installer cache (drive_c/windows/Installer/). That last one matters, because a product installed by running its vendor wrapper may only leave its MSI there, and without finding it the plugin reads unverified and has nothing to repair or uninstall from. Routine inventory takes only MSIs that declare a plugin payload directory (VST3DIR/VSTDIR/AAXDIR/APPDIR/PREDIR) from that cache, so runtime MSIs do not slow the listing or appear as plugins. The destructive ownership check also considers non-plugin cached MSIs and mapped application/driver roots, because they may own shared files. An unreadable or unmapped cache record stops a registered uninstall; this conservative scan may be slower and may require manual cache repair. MSIs outside the searched cache locations are not proven absent owners.
  • The GUI runs one background job at a time. A running job keeps its reference until it finishes, a second request is declined with a line in the log rather than queued, and closing the window waits for a running job. Each of those is a crash that was hit for real: Qt aborts the process, with no exception and no traceback, when a QThread that is still running loses its last reference.
  • --scratch (where the MSI is unpacked, default /tmp/wpt-extract) is emptied before each extraction, because a plan is built by listing the extracted folders: stale payload from another product would otherwise be copied into the prefix on install, or deleted from it on uninstall. A scratch path that is not empty, was not created by wpt (no .wpt-extract marker) and sits outside the temp dir or ~/.cache is refused rather than wiped.
  • iLok is diagnosed, not automated: scan tells you a plugin is missing files, but licence slots are still checked by hand at https://www.ilok.com, under My Licenses.
  • macOS, Windows, and prefixes that are not the ableton-linux shape are out of scope.

Development

python3 tests/test_core.py                # pure logic, no prefix needed
python3 tests/test_prefix_integration.py  # builds a synthetic prefix and exercises everything
QT_QPA_PLATFORM=offscreen python3 tests/gui_smoke.py       # builds the GUI and runs every tab
QT_QPA_PLATFORM=offscreen python3 tests/gui_buttons_check.py  # clicks every button offscreen
python3 tests/readme_claims_check.py    # parser/tabs/flags/known limitations (not real-MSI proof)

The full runner isolates TMPDIR only. Use disposable HOME, XDG paths and WINEPREFIX as described in TESTING.md; never point the full or GUI suite at a live prefix.

test_core.py covers Wine tree version ordering, .reg value decoding (including UTF-16 str(2) blobs), Windows to Linux path mapping, plugin-path classification, destination resolution from MSI directory properties, and the CLI surface. test_prefix_integration.py builds a fake ~/.wine-ableton with a fake tree, plugin folders and a registry that mixes present and missing paths, then checks detection, the inventory, the diagnostics scan, the repair filter and plan application against each other. Neither needs msitools, a real installer or a real prefix.

wpt/environment.py   locate tree, prefix, user, directories; build the launcher environment
wpt/msi.py           msitools wrappers: identity, LaunchCondition, File table, msiextract
wpt/installer.py     build a copy plan, apply it, verify sizes, repair filter, uninstall, enable/disable
wpt/inventory.py     what is installed: walk plugin directories, cross-check sizes against cached MSIs
wpt/installers.py    what is not installed yet: installer discovery, name and version parsing
wpt/products.py      triage: every prefix walked, product records read, verdicts against the disk
wpt/presets.py       your presets and downloaded packs: list, export, rescue before removal
wpt/scan.py          registry against disk diagnostics, registration lookups for uninstall and purge
wpt/cli.py           argparse front end (every real behaviour lives in the modules above)
wpt/gui.py           PySide6 front end (no logic of its own)
packaging/           launchers, PKGBUILD helpers, desktop entry, icons
tests/               the suites listed above, plus wrapper corpus and GUI layout checks

One design rule holds the whole thing together: no logic in the front ends. If the GUI and the CLI could ever disagree, the bug belongs in a core module.

Before submitting a behaviour claim or code change, see CONTRIBUTING.md and the claim ledger. A code citation is not proof of a real-machine result.

Credits

  • msitools reads and unpacks the vendor MSIs.
  • shibco/ableton-linux is the Wine stack and prefix this target shape comes from.
  • 7z, cabextract, innoextract and unshield unpack the wrapper families listed above.
  • Not affiliated with Ableton, Neural DSP, or any plugin vendor. Plugin names appear only to say what was tested.

MIT licensed. See LICENSE and CHANGELOG.md.

AI Disclosure

Development here is AI-assisted. An agent (Hermes, by Nous Research) uses models through OpenRouter, which can vary by task. The agent helps with diagnosis, reproduction, implementation, test authoring, documentation and release tooling. The maintainer owns release decisions.

The release gate for future changes requires a reproduced defect, a regression check, the full suite from an extracted release tarball, an independent review, and checksum comparison of published artefacts against what was built. The published 0.6.4 release predates the claim ledger; version 0.6.5 retains the verification and uninstall limitations stated above. A passing script alone does not certify every README sentence; see the claim ledger for what is still open.

Contributions: AI-assisted work is welcome if you understand it and can explain the change, and if it comes with evidence: a reproduction, a test, or a reason. We will not accept fully-vibecoded contributions, where nobody can account for the code, because the risk of regression is too high.

About

Install, verify, repair and uninstall Windows audio plugins in an ableton-linux Wine prefix (VST3/VST2/AAX) - CLI + Qt GUI

Topics

Resources

Contributing

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages