* Fixed: saving an import in the admin HTML-encoded the taxonomy separator, turning `>` into `>`. Hierarchical categories such as `Parent > Child > Grandchild` (as in the demo catalogue's `Categories` column) then failed to import: the terms were created but the finalize step matches the built hierarchy path against a literal `>`, so nothing matched, every term was left unresolved, and the run aborted with "Failed to import hierarchical terms". The config save ran every value through `wp_kses_post` during the wp.org compliance pass, which entity-encodes bare `<`, `>` and `&`. Config values are now sanitised without encoding those literal characters, so separators (and any source or template value containing them) round-trip intact while scripts are still stripped.
* New: the Run Now screen has been redesigned. While an import runs you now see each stage with its own progress and worker activity, an overall percentage and elapsed timer, a system-configuration panel, live peak throughput, and a colour-coded live engine console.
* New: when an import finishes, the popover transitions to a completion screen with a per-stage efficiency table (duration, peak memory, throughput), a velocity panel showing average throughput and a full count breakdown (posts created and updated, post meta, terms, relationships, taxonomies), auto-fix and integrity totals, an Export Summary download and a link to view the updated posts/products.
* New: set Featured and Catalog Visibility on import - map a Featured column (1/yes) and a Catalog Visibility column (`visible`, `catalog`, `search` or `hidden`) in Publication Info. These combine with stock status into the product's `product_visibility` terms. Mapping the `product_visibility` taxonomy directly overrides them for the whole import.
* Improved: imported out-of-stock products now get WooCommerce's `outofstock` catalog-visibility term, improves performance and eliminates the need to run save-posts after run.
* Fixed: when the slug (post_name) is left unmapped, products sharing a title now get their `-2`/`-3` slug suffixes in CSV row order every time, instead of an order that could vary between runs.
* New: a "Load sample imports" button in the right-hand panel sets up ready-to-run sample imports in one click - it registers the product taxonomies (categories, brands, colours), copies the sample CSV into your uploads folder, and creates the import configuration. Pro includes a 1000-product simple import and a comprehensive import; the free edition includes the simple import. Nothing is imported until you pick one and press Run Now.
* New: once an import has been run, its summary shows a "Delete all products loaded by this import (x)" link, where x is the number that will be deleted. It moves every product that import created to the Trash (the same as the CLI `--delete-all`), alongside the existing "View products affected" link.
* Fixed: re-running an import through the browser no longer strips the products' categories, tags and attributes. The browser (AJAX) importer now runs the exact same per-stage code as the CLI, so the two can no longer drift apart.
* Fixed: the comprehensive (variable products) import no longer fails in the browser with an opaque "parsererror". Stage errors are now surfaced in the on-screen debug log so they can be diagnosed.
* Fixed: the per-section "Show All" buttons now respond immediately after creating a new import, without needing a page refresh.
* Fixed: browser (AJAX) imports now record the correct row count and run details in the import history - both the summary at the top of the page and the history list. Previously an AJAX run showed 0 rows (or "NA") while the same import run via CLI was correct.
* Changed: after a browser import finishes, the import summary at the top of the page updates automatically (last run date, rows and total runs) instead of needing a page refresh.
* Changed: the field mapping-method dropdown now reads "PHP" (or "PHP (PRO Only)" in the free edition) instead of the longer "PHP Function", which was overflowing the layout.
* A mapped `post_name` (product slug) is now imported verbatim instead of being overwritten with a de-duplicated slug derived from the title.
* Fixed: choosing a field as the **Unique item identifier** now matches your existing items on that field's native postmeta key (e.g. SKU → <code>_sku</code>) instead of SSI's private <code>_ssi_unique_item_id</code> key. Previously, setting the unique identifier to your SKU field would fail to find products created outside SSI (manually, or by another importer) because they don't carry the private key — so a re-import created a duplicate of every existing product instead of updating it. Existing imports are migrated automatically; no reconfiguration needed. See <code>.docs/2026-06-23-unique-identifier-matching-redesign.md</code> and the developer KB article <code>unique-identifier-matching-internals</code>.
* Changed: the Unique item identifier is now chosen from your mapped postmeta fields. The PHP-function and raw-CSV-column options have been removed — a function computed from the CSV row cannot be evaluated against existing database items, which is the root cause of the duplicate-on-update problem. (Composite identifiers across multiple fields are planned next.)
* **Products now get assigned every level of a category path, not just the deepest one.** When a product is in <code>Men > T-Shirts</code>, WooCommerce expects BOTH <code>Men</code> and <code>T-Shirts</code> to be attached to it — that's what WP All Import does, and it's what makes <code>/product-category/men/</code> list the product, breadcrumbs render the full path, and layered-navigation filters include parent categories. SSI previously assigned only the leaf term (<code>T-Shirts</code>), so parent category pages showed nothing. This was the single biggest functional difference between SSI and WPAI in our benchmark comparisons. There's a new **Assign every category level** option in Additional Options to control it. **New imports default it ON.** Existing imports created before this release keep their previous leaf-only behaviour until you switch it on, so nothing changes under you on a re-run unless you opt in. This replaces the undocumented `SSI_ADD_ALL_TERMS_FROM_HIERARCHY` PHP constant, which no longer has any effect. See `.docs/2026-05-26-leaf-vs-all-level-term-assignment.md`.
* Further optimisation for local image searching to use post_name instead of post_title and no longer needs to use open-ended LIKE wildcard so it's FAST!
* Removed early access auto-update prevention
* Added full namespacing for plugin update checker to prevent conflicts with 3rd party plugins
* Further hardening for collation checks and forced collation for virtual columns in CTEs