Description
Seekmodo Search replaces the built-in WordPress site search (and the
WooCommerce product search, when WooCommerce is active) with an AI-powered
search experience served by the Seekmodo platform at mcp.seekmodo.com.
One plugin, two activatable verticals:
- Content vertical — WordPress core search via
pre_get_posts+
posts_pre_query. Auto-detects public Custom Post Types so blog posts,
pages, docs, and your custom CPTs all participate in the same ranked
result set. - Commerce vertical — WooCommerce product search via
woocommerce_product_query +posts_search. Indexes products plus
variations, stock state, price, SKU, and attributes. Auto-on when
WooCommerce is detected; dormant otherwise.
What you get:
- AI search out of the box — vector recall + commerce-aware reranking
on top of Typesense, with no relevance tuning required to start. - Typo tolerance, partial-word matching, and prefix-matched typeahead
via a single REST endpoint your theme can hit from any autocomplete
widget. - Click-through telemetry feeds a self-tuning learn-to-rank pipeline.
Relevance gets better as your shoppers interact. - Always-on safety net — every gateway-talking entry point falls
through to nativeWP_Query(orWC_Queryfor products) inside the
same request when the platform is unreachable. Visitors never see an
empty results page. A per-tenant circuit breaker prevents repeated
timeouts from compounding. - Multi-environment safe — Seekmodo locks each tenant to a canonical
storefront host. Staging / dev clones are auto-detected and return
no-op from every gateway entry, so your production index is never
polluted by a non-production deploy. - Settings tunable remotely — flip search mode, adjust ranking knobs,
and toggle the “Powered by Seekmodo” badge from
https://admin.seekmodo.com; the connector picks the change up on
the next 5-min cadence.
External service dependency. Seekmodo Search is the WordPress
connector for the Seekmodo AI search platform. The platform is a
hosted service operated by Numinix Technology Inc. at
https://mcp.seekmodo.com and https://admin.seekmodo.com. The
plugin connects your site to a Seekmodo tenant via an HMAC-signed
pairing flow; once paired, the plugin sends indexable post / product
data to mcp.seekmodo.com and queries it for search results, typeahead
suggestions, and click telemetry.
Free trial. Every Seekmodo plan ships with a 14-day free trial at
$0 — full features, unlimited searches, no card required upfront.
Cancel before day 14 and you pay nothing. After the trial, plans
start at $29/month. Pricing details, including how the plan auto-sizes
to your real traffic during the trial: https://seekmodo.com/pricing.
What happens if you stop paying. The plugin does not break your
site. If the gateway is unreachable, your subscription lapses, or
you simply uninstall the plugin, every search entry point falls back
to native WordPress / WooCommerce search inside the same request. No
white screens, no fatal errors, no broken search box.
Privacy + data handling.
https://seekmodo.com/legal/privacy lays out the full picture, but
in short: searchable post / product content you choose to index is
sent to mcp.seekmodo.com; visitor search queries and clicks are sent
to mcp.seekmodo.com as telemetry; no personal data about your
visitors leaves your site unless you opt in to additional
analytics integrations from the Seekmodo admin. The plugin
self-checks for stale indexes, configuration drift, and update
availability — all such phone-home requests are vanilla HTTPS GETs
that carry no tenant ID and no site-identifying data; they’re
static-cacheable from our perspective.
Screenshots



Blocks
This plugin provides 5 blocks.
- Seekmodo Chat Conversational AI shopping assistant. Supports policy/shipping RAG when configured.
- Seekmodo Ask AI Single-turn Ask AI Q&A over your indexed catalog and policies.
- Seekmodo Search Box AI-powered search input that emits seekmodo:search events. Pairs with <seekmodo-results> on the same page or links to a search-results URL.
- Seekmodo Recommendations Renders a horizontal strip of related/popular/similar products. Backed by the Seekmodo recommendation algorithms.
- Seekmodo Quiz AI shopping quiz / product finder. Reads a quiz definition and surfaces a personalized result set.
Installation
Either:
- In WordPress admin, go to Plugins Add New and search for “Seekmodo”.
- Click Install Now on “Seekmodo Search”, then Activate.
Or upload manually:
- Download the latest zip from https://seekmodo.com/plugins/wordpress.
- Upload via Plugins Add New Upload Plugin choose the zip Install Now Activate.
Then in either case:
- Go to Settings Seekmodo Search Connect to Seekmodo.
- Click Start free trial / sign in and approve the pairing on seekmodo.com.
- (Optional) Run
wp seekmodo index --fullto seed your tenant immediately. (The plugin will otherwise reindex incrementally on its own.) - Flip search mode from
shadowtoactivein the connector settings once you’ve spot-checked a few searches.
Headless / CI install:
wp plugin install seekmodo --activate
wp seekmodo connect --tenant=<tenant_id> --secret=<shared_secret>
wp seekmodo index --full
wp option update seekmodo_wp_mode shadow
FAQ
-
Do I need a Seekmodo account?
-
Yes. Seekmodo Search is the WordPress connector for the Seekmodo
hosted AI search platform; the plugin itself is free and GPLv2, but
it needs a paired Seekmodo tenant to do its job. Every plan ships
with a 14-day free trial at $0 with full features and unlimited
searches. After the trial, plans start at $29/month. Pricing details:
https://seekmodo.com/pricing. -
Do I need WooCommerce?
-
No. The content vertical works on any WordPress site (posts,
pages, public custom post types). The commerce vertical activates
automatically when WooCommerce is detected, and idles otherwise. -
What happens if the gateway is down?
-
Every gateway-talking entry point falls through to native
WP_Query
(orWC_Queryfor products) inside the same request. Visitors never
see an empty results page. A per-tenant circuit breaker prevents
repeated timeouts from compounding, and Seekmodo health metrics
auto-demote the connector back to native search if our gateway is
unhealthy. -
What happens if I stop paying / cancel my subscription?
-
Same as the previous answer. The plugin stays installed, the
gateway-talking entry points start returning “no results” (since the
tenant is gated), and every entry point falls back to native search
in the same request. Your site keeps working; you just stop getting
AI relevance. Re-pairing with a paid tenant restores full
functionality. -
Will this work on a staging clone?
-
Yes — Seekmodo locks each tenant to a canonical storefront host.
Staging / dev hosts are auto-detected and return no-op from every
gateway-talking entry point, so your production search index is never
overwritten by a non-production deploy. -
Where are my credentials stored?
-
In
wp_options(seekmodo_wp_tenant_id,seekmodo_wp_shared_secret).
wp seekmodo connect can be re-run any time to rotate the pair. -
Where does the plugin send data?
-
Indexable post / product content goes to
mcp.seekmodo.com(the
gateway). Visitor search queries and clicks go tomcp.seekmodo.com
as telemetry. The update check (12 h cadence) goes to
seekmodo.com/api/plugins/seekmodo. Configuration pull (5 min
cadence) goes tomcp.seekmodo.com/v1/tenant/snapshot. All
gateway-bound requests carry an HMAC signature derived from the
pairing secret. Full details in
https://seekmodo.com/legal/privacy. -
Does the plugin support translations?
-
The admin UI is localised via the
seekmodotext domain
and/languages/directory. We ship English (en_US) as the source
locale; contributions for other locales are welcome. -
How do I get help?
-
- Support email: support@seekmodo.com
- Docs: https://seekmodo.com/docs/wordpress
- WordPress.org support forum (replies within ~1 business day during
weekdays)
-
Where is the human-readable source for the Suggest JavaScript?
-
The production Suggest bundle
(assets/suggest/seekmodo-suggest.global.js) is a minified IIFE built
from@seekmodo/web-components. Readable TypeScript for that bundle
(and for the Ask IIFE / full web-components ESM) ships inside the
plugin atassets/suggest/src/. Seeassets/suggest/SOURCE.mdfor
the entry file map, rebuild steps (npm install+npm run build
in the web-components package), and notes on the inlined SDK copy
underassets/suggest/src/vendor/seekmodo-sdk/. Ask and full ESM
pointers:assets/ask/SOURCE.md,assets/web-components/README.md.
Reviews
Contributors & Developers
“Seekmodo Search” is open source software. The following people have contributed to this plugin.
ContributorsTranslate “Seekmodo Search” into your language.
Interested in development?
Browse the code, check out the SVN repository, or subscribe to the development log by RSS.
Changelog
0.11.62
- Improvement: “Build index now” no longer runs the full rebuild inside the admin page load — it queues a resumable WP-Cron build that runs in bounded background slices, so large catalogs no longer hit proxy/Cloudflare timeout error pages while PHP keeps working. The settings panel shows live progress, and wp-cli
wp seekmodo local_index buildremains synchronous for operators.
0.11.61
- New: wordpress.org review prompts — a dismissible admin banner shown 14 days after pairing, a “Rate it” link in the Plugins table row, and a footer line on the Seekmodo settings page. “No thanks” dismisses permanently; “Maybe later” snoozes for 14 days.
- Chore: removed a stray internal debug file from the shipped package.
0.11.60
- New: search-suggestions dropdown is now enabled by default on fresh installs and upgrades where the setting was never touched. Sites that previously turned it off keep it off; themes can still force-off via the seekmodo_enqueue_typeahead / seekmodo_enqueue_suggest filters.
- Fix: bulk index pushes (/v1/index) now use a 30s timeout instead of the shopper-facing 250ms-2s search cap. Large batches no longer abort client-side and report phantom “failed” counts while still importing server-side.
0.11.59
- Security: All $_SERVER inputs are properly sanitized through ServerInput helper class per WordPress.org Plugin Review requirements (DOCUMENT_ROOT, HTTP_REFERER, REQUEST_METHOD, etc.). uninstall.php cleanup uses only ABSPATH and no longer reads $_SERVER directly.
- wordpress.org review: GET
/seekmodo/v1/imagesis intentional public read-only image hydrate; removemark_dirty(no unauthenticated post meta writes). Dirty reindex remains via product-save hooks and gatewaypending_image_refresh_ids.
0.11.58
- wordpress.org review: GET
/seekmodo/v1/imagesis intentional public read-only image hydrate; removemark_dirty(no unauthenticated post meta writes). Dirty reindex remains via product-save hooks and gatewaypending_image_refresh_ids.
0.11.57
- Fix: commerce typeahead falls back to WooCommerce products (not blog posts) when cloud/Enhanced Native returns no rows; shared native-fallback filter keeps content rows for vertical=content.
0.11.56
- wordpress.org review: remove remaining uninstall.php DOCUMENT_ROOT $_SERVER read (ABSPATH-only .well-known cleanup). Discovery/runtime already use ServerInput since 0.11.52; cited WellKnownWriter/ShopperContext/McpDiscovery snippets were pre-0.11.52.
0.11.55
- Fix: EventsQueue::ensureTable() on boot and before push() so click beacons are not silently dropped; Options::bustOptionsCache() after pairing/mode so Redis alloptions cannot stay stale.
0.11.54
- Broken suggest image heal: filesystem-aware ProductImage, REST
/seekmodo/v1/images, Suggestimages-hydrate-url, schedule commerce index cron, drain gatewaypending_image_refresh_ids.
0.11.52
- wordpress.org review: sanitize/validate
$_SERVER(and related) inputs early viaServerInputhelper; DOCUMENT_ROOT path guards; SearchSwap GET numeric casts sanitized.
0.11.51
- wordpress.org review:
Tested up toin readme.txt only; ship Suggest/Ask TS underassets/suggest/src/; remove static ABSPATH.well-knownwrites (PHP discovery only). - Fix: clear stale PreferLocal
over_quotasticky while trial is still active.
0.11.50
- wordpress.org review: exclude/remove .map files (no jsDelivr strings), JWKS fetch via wp_remote_get only, nonce on cloud-suggest-denied, JSON_HEX_* for Suggest inline config, wp_kses for recommendation placeholders.
0.11.49
- Plugin Check i18n: SuggestLabels uses literal __() text/domain (no variables).
0.11.46
- Fix: sticky unpaid/over-quota Suggest skips metered /v1/suggest (prefer-local) and still fills EN rows when img-ver is set.
0.11.45
- Fix: unpaid/over-quota Suggest fallback keeps the Seekmodo-styled suggest box (EN via typeahead-fallback-url) instead of switching to the plain TypeaheadUI product list.
0.11.44
- Fix: homepage suggestions when Suggest JS is delayed/blocked — autoboot on token-guard, typeahead skip while Suggest owns the input, watchdog flip to Enhanced Native typeahead.
0.11.41
- Suggest: paint thumbnail_url for content posts; hide price_range on content vertical.
0.11.38
- Fix: Multilingual Suggest sends serp_passthrough filter_by lang:=slug, over-fetches suggest limit to 48 for client i18n_filter, and keeps cloud products when typeahead returns only posts.
0.11.37
- Fix: Polylang language-switch SERP no longer empties when gateway cache ignores lang (localize IDs + per-lang fetch buckets).
0.11.36
- Fix: Suggest “View all” SERP href uses Polylang/WPML language path prefix (e.g. /fr/?s={q}&post_type=product).
0.11.35
- Suggest chrome i18n: inject locale label packs into seekmodo-suggest (labels attr + SeekmodoSuggestLabels); vendor web-components 0.4.5 suggest bundle.
0.11.34
- WordPress.org review follow-ups: enqueue Health/ModeBadge CSS and beacon seid via wp_add_inline_*; sanitize shopper UA/IP/referer and search keywords; rest_url() for pairing callback; shadow logs under uploads/seekmodo/; remove load_plugin_textdomain; static .well-known writes opt-in; exclude release-signing-keys from release zip.
0.11.33
- Plugin Check: remove HEREDOC/NOWDOC from shipped PHP; Tested up to 7.1; release compliance gate.
0.11.22
- Fix: Relevanssi-compat hydration re-applies post__in score order after get_posts so theme date sorting cannot reshuffle SERPs.
0.11.21
- Improve: stronger ordered title-phrase boost so exact publication titles outrank long body TF matches.
0.11.20
- Improve: Enhanced Native exact whole-word hits outrank prefix/partial matches; unquoted multi-word queries boost adjacent ordered title/excerpt phrases.
0.11.18
- Fix: commerce-only tenants (
enabled_verticals=commerce) now claim unscoped/?s=/post_type=anymain searches so search_event_id reaches the click beacon.
0.11.17
- Fix: content SERP (
/?s=without post_type=product) now stamps search_event_id so click beacons are accepted; also supports Rank Math/search/{q}/keyword detection.
0.11.16
- Fix: WooCommerce add-to-cart and purchase events now register even when WooCommerce is not visible at plugins_loaded, flush in the same cron tick as clicks (instead of starving behind SERP click traffic), and no longer drop silent TypeErrors when quantity is a decimal.
0.11.15
- Fix: the events-queue flush cron (clicks, add-to-cart / purchase conversions) never actually ran on any install.
wp_schedule_event()was called with a recurrence name that was never registered via thecron_schedulesfilter, so WordPress silently refused to schedule it while searches kept working fine — the underlying cause of fleet monitoring flagging sites with real traffic but zero recorded clicks. Registering the plugin now also self-heals existing installs immediately (no need to deactivate/reactivate).
0.11.14
- Daily unpaid-recovery: the existing 5-minute tenant.snapshot pull now clears a stuck trial_expired / paused / closed sticky as soon as the gateway reports the account active again, so a resubscribe or trial extension restores cloud suggest within one pull instead of waiting out the 1-hour sticky TTL. An over_quota sticky is left to clear on its own (TTL or next successful search) since an active subscription can still be over this period’s quota.
0.11.13
- Search suggestions box now supports full CSS custom-property theming (accent color, header, CTA pill, row accent bar, rail background) so you can brand the dropdown to match your site without a child plugin. No visual changes if you don’t set any of the new properties.
0.11.10
- Stamp search_event_id on add_to_cart / purchase for LTR last-touch linkage.
0.11.9
- Shopper-context parity for typeahead + conversion events (session_id / ua / referer).
0.11.8
- Document HMAC auth_fail / signature_mismatch contract: Gateway\Client returns null (native WP/Woo fallback) during secret drift; optional WP_DEBUG log.
0.11.7
- Text domain seekmodo; removed Update URI / WporgUpdateClient for Directory updates.
- Suggest branding defaults off; privacy guide mentions IP/UA/referer.
- Plugin Check ERROR cleanups (escaping, SQL prepare, ABSPATH, packaging excludes).
0.11.6
- WordPress.org submission readiness: vendored full
@seekmodo/web-components ESM underassets/web-components/(no
default CDN load; override viaseekmodo_web_components_src). - Complete uninstall cleanup (options, local-index tables, crons,
transients). Tested up to: 7.0. Health dashboard widget requires
manage_options. Suggested privacy-policy guide text added.- Cart cascade ranks multi-line carts by
support_countacross up
to 10 anchors.
0.11.5
- PDP/cart recommendation cascades (
pdp-cascade,cart) via
/wp-json/seekmodo/v1/recommendations with cross-section de-dupe and
in-cartexclude_doc_ids, matching the AKS cascade contract. - Auto-injects placeholders on WooCommerce PDP/cart templates and
refreshes after cart fragments; enqueues@seekmodo/web-components
on those templates even without Gutenberg blocks.
0.11.4
- Stop requiring REQUEST fingerprints for add_to_cart mirrors (theme/custom AJAX was dropping all ATCs). Session-restore skip remains the spam guard.
- Also emit purchases on woocommerce_payment_complete (deduped) when thankyou never renders.
0.11.3
- Events flush uses an 8s timeout and smaller batches (clicks first) so ATC attribution no longer wedges the queue.
- Skips cart-session restore add_to_cart mirrors; only intentional shopper adds are queued.
- Persists sm_seid cookie for SERP click attribution when footer beacon localization races.
0.11.2
- Stamps per-shopper session_id + visitor IP/UA on search and click events for bot-check and fleet linkage.
- Drops unlinked SERP beacon clicks (missing search_event_id) that were polluting LTR / fleet health.
0.8.9
- Shared thumbnail resolver for content typeahead and indexing (featured
image, inline content image, seekmodo_thumbnail_url filter).
0.8.8
- Content typeahead unions gateway hits with native WP rows and applies
post-type priority so pages surface before posts (trek.ca parity with SERP). - Suggest widget always merges the REST typeahead fallback when configured.
0.8.7
- Fixes WooCommerce SERP showing product categories instead of ranked
gateway products after the search swap. - Suggest dropdown merges REST typeahead fallback when gateway suggest
returns no product rows (content sites like trek.ca).
0.8.6
- Fixes WooCommerce SERP titles showing
Search results: ""after the
gateway search swap clears the querysvar.
0.8.4
- Fixes mobile split-rail draggable divider (both panels resize again).
- Refreshes the vendored
@seekmodo/web-componentssuggest bundle.
0.8.3
- Typeahead product-row clicks thread
search_event_idfrom/v1/suggest
meta for LTR click attribution. - Refreshes the vendored
@seekmodo/web-componentssuggest bundle (split-rail
mobile divider, native title tooltips, anchor performance fixes).
0.8.2
- Fixes typeahead and search-swap click attribution (rank/surface metadata).
- Refreshes suggest bundle with split-rail scroll and thumb scaling fixes.
0.8.1
- CORS-block UX when gateway script loads or suggest fetches are blocked.
- Refreshes suggest bundle to v0.2.2.
0.8.0
- Enhanced Native search layer (Tier 1 + Tier 2) for unpaired installs.
0.6.0
- SM-606 Universal Suggest Widget: when the operator-facing
“Enable connector typeahead UI” toggle is on, v0.6.0 enqueues the
new<seekmodo-suggest>custom element (~7 KB gzip, lives at
assets/suggest/seekmodo-suggest.global.js) instead of the legacy
flat-row dropdown. The web component renders the rich/v1/suggest
envelope from the gateway (WS-2): recent + trending + keywords +
products + categories + did-you-mean + “View all N results” CTA,
all from one server round-trip. UX is shared 1:1 with the
BigCommerce / Zen Cart / AKS / WordPress connectors so a tenant
with multiple storefronts gets one suggestions UI everywhere. - Opt-out flag: new
seekmodo_wp_suggest_legacyper-site option
(Settings Seekmodo “Use legacy flat-row typeahead instead of the
universal suggest widget”) flips back to the v0.5.x dropdown for one
major-version cycle. The two surfaces are mutually exclusive —
Frontend\TypeaheadUI::isEnabled() returns false when the flag is
off, preventing double-attaching dropdowns to the same input. - Browser-token refresh: new public
POST /wp-json/seekmodo/v1/browser-token
route returns{token, expires_at, session_id}so the in-bundle SDK
can refresh a 5-min JWT without a full page reload. Cached behind
the existing per-tenant transient inGateway\BrowserTokenso a
long-running tab amounts to ~one mint per ~4 min regardless of how
many keystrokes the shopper triggers. - Customization surface (theme-side):
seekmodo_suggest_selectors— CSS-selector list the autoboot
walks (defaultinput[type="search"],input[name="s"],
input[data-seekmodo-suggest],input[data-seekmodo-typeahead]).seekmodo_suggest_blocks— CSV of blocks the widget should
render in order (defaultrecent,did_you_mean,keywords,trending,). Drop any block by leaving it out.
products,categoriesseekmodo_suggest_view_all_href— URL template for the CTA.
Default/?s={q}(or/?s={q}&post_type=producton Woo sites).seekmodo_suggest_extra_attrs— assoc map of additional
attributes (e.g.min-length,debounce-ms,limit,
cache-size,lang) forwarded to every spawned element.seekmodo_suggest_config— last-resort filter on the localized
JS config.- Shadow-DOM CSS Custom Properties (
--seekmodo-suggest-bg,
–seekmodo-suggest-row-hover,--seekmodo-suggest-thumb-size,
etc.) so child themes can theme the dropdown without forking
its markup. <slot name="recent|keywords|trending|products|categories|empty|lets a theme drop bespoke HTML inside an
header|footer">
element and override any one block’s rendering wholesale.
- Performance: matches the AKS-3801e baseline (sub-300 ms p95
cold cache, <16 ms warm-cache render) via the bundle’s built-in
150 ms keystroke debounce, AbortController cancel-on-next-keystroke,
32-entry LRU cache, and single rAF-batched render. Skeleton loader
masks the first-render latency on a cold cache.
0.5.3
- Operator UX:
wp seekmodo index --fullnow reindexes every
gateway-enabled vertical for the tenant (content + commerce, in
series), and accepts a new--vertical=content|commerce|allflag
for surgical per-vertical reindexes. Pre-0.5.3 the command only
invokedContent/Indexer::reindexFull(); commerce-only operators
(and dual-vertical operators chasing a stale product index) had to
drop intowp eval '\Numinix\SeekmodoWordPress\Commerce\Indexer::reindexFull();'.
Verticals the gateway hasn’t enabled for this tenant — or whose
runtime dependency is missing (e.g. WooCommerce inactive) — are
skipped silently with an info-level log line; the command reports
the per-vertical totals separately so the operator can tell at a
glance whether each vertical actually executed. - Safety: stricter write-side host-lock gate, exposed as
DomainLock::canIndex() and surfaced inwp seekmodo health/
wp seekmodo diagnose as a newcan_indexrow. Used by every
gateway-mutating helper (numinix_seekmodo_run_bulk_upsert,
numinix_seekmodo_mirror_click) plus the cron-tick early-out in
bothContent/Indexer::tick()andCommerce/Indexer::tick().
Failure modes the new gate catches that the looser
DomainLock::matches() did NOT:- Self-referential lock on a non-prod host.
dev.example.com
seeds itsseekmodo_wp_storefront_hostto its own home_url() at
activation;matches()returns true (current==locked); pre-0.5.3
indexer cron would happily push every product save to the prod
tenant’s Typesense collection, withdev.example.comURLs
poisoning the customer-visible search results. Exact PM-303
regression. - Unset lock on a non-prod host. A freshly-installed dev clone
that hasn’t completed its first 5-mintenant.snapshotpull yet:
pre-0.5.3matches()returned true (no lock tentative allow).
0.5.3 fails closed.
- Self-referential lock on a non-prod host.
- Safety: read paths (typeahead, search-swap, click-beacon
enqueue) keep gating onnuminix_seekmodo_enabled()so an
operator smoke-testing search behavior on a staging clone still
gets results — only writes are tightened. - Safety: two override filters, intentionally separated so a
read-side bypass doesn’t accidentally also unlock writes:seekmodo_disable_storefront_host_lock(existing, since v0.1.0)
— read AND write; bypasses every check. Used by blue/green CDN
setups where the request reaches WP under a different Host
header than the visitor sees.seekmodo_allow_nonprod_indexing(NEW, v0.5.3) — write only;
consenting non-prod indexer for installs paired to a separate
*-dev tenant. Defaults false.
- Operator UX:
wp seekmodo healthnow printscurrent_host,
locked_host,host_lock_match,can_index, and
looks_like_nonprod instead of the older singlehost_lock_match
row, so an operator chasing “why isn’t dev indexing?” can see
every input the gate consults at a glance.
0.5.1
- Reliability: deploy-channel-agnostic version-bump detector. The
connector now compares the on-diskSEEKMODO_WP_VERSIONconstant
to the last-seen value stored inwp_optionson every request,
and on a mismatch fans out cache invalidations to every page-cache
/ minify / object-cache / OPCache plugin we know about. Closes the
“I rsync’d v0.5.0 onto the server but visitors still load v0.4.0”
regression that surfaced on POCO after the v0.5.0 push: WP Rocket
was serving the cached v0.4.0 minified JS for 1 year because it
only invalidates onupgrader_process_complete(which rsync
deploys never fire). - Reliability: explicit OPCache reset on version bump. Hosts
withopcache.validate_timestamps=0(typical on shared hosting
for performance) silently kept executing the old PHP class
bytecode after rsync. The reset is wrapped in a function-exists
guard so PHP builds without OPCache compiled in stay safe. - Reliability: browser-token transient explicitly invalidated
on version bump so the next typeahead keystroke re-mints a token
signed against whatever the new gateway expects, instead of
inheriting a payload-shape from the prior connector version. - Maintenance: fan-out is gated behind a one-shot atomic option
write so two concurrent first-bump requests don’t double-fire the
cache flush. Hosts running bespoke cache infra can suppress the
fan-out entirely with the newseekmodo_skip_upgrade_flush
filter, or extend it with extra do_action keys via
seekmodo_upgrade_flush_actions. - No new operator-facing settings; mass-deployable as a no-op
update on every connector site.
0.5.0
- Performance: typeahead now POSTs
mcp.seekmodo.com/v1/typeahead
directly from the storefront browser using a short-lived browser
token minted server-side at page render. Skips the WordPress REST
hop (and the ~1.5–2 s WordPress full-stack boot it pays on a heavy
WooCommerce + Wordfence install) on every keystroke.
Per-keystroke latency on POCO observed dropping from ~2,250 ms to
~80–150 ms. - Performance: 32-entry client-side LRU cache keyed on the
normalized(vertical, max, q)prefix. Backspace + retype on a
previously-fetched prefix renders synchronously from in-memory
cache, no network round-trip. Cache size is operator-tunable via
theseekmodo_typeahead_configfilter. - Performance: server-side
Cache-Control: public, s-maxage=30,+
must-revalidateVary: X-Seekmodo-Tenanton gateway typeahead
responses lets Cloudflare / Varnish absorb keystroke storms on
hot prefixes without leaking rows across tenants. - Performance: per-FPM-process APCu micro-cache (10 s TTL) on
the gateway side defends Typesense from a hot prefix when the
edge cache is cold. - Added:
seekmodo_typeahead_gateway_directfilter. Defaults
true. Site can__return_falseto force every typeahead call
back to the WordPress REST endpoint — useful for incident-response
/ debugging without a connector update. - Added:
Gateway/BrowserToken.php— caches the per-tenant
browser-token mint in a WordPress transient (refresh window
honored, hard-cap 240 s). The mint failure mode silently falls
back to the REST hop, so the typeahead never breaks regardless
of token availability. - Fixed: pre-existing regression where
Client::typeahead()
POSTed/v1/typeaheadagainst the gateway, the gateway returned
404 tool_not_found, and the connector fell back to a native
WP_Query LIKE search on every keystroke (~2.3 s on POCO,
~1.1 s on Trek.ca). The new gateway-sideTypeaheadTool(SM-602
on the platform side) is what makes the gateway-direct path
return real Typesense rows in ~80 ms.
0.4.0
- Added: front-end typeahead dropdown UI. The connector now ships
assets/typeahead/seekmodo-typeahead.{js,css} plus
src/Frontend/TypeaheadUI.php — a vanilla-JS dropdown that
auto-binds to common search inputs (input[type="search"],
input[name=”s”],input[data-seekmodo-typeahead]), debounces
input at 150ms, and renders rows from the existing
/wp-json/seekmodo/v1/typeahead REST endpoint. Two row shapes:
content rows (title + post-type meta + excerpt + thumbnail) and
commerce rows (product card with price / sale / stock badges). - Added: optional “Powered by Seekmodo” footer in the dropdown,
driven by the existingseekmodo_show_brandingfilter +
OPT_SHOW_BRANDING option. Default OFF — partner sites flip it on
via the Settings page or have it pushed down by the gateway’s
tenant-snapshot config pull. White-label by default. - Added: per-site “Enable typeahead” + “Show branding” toggles
on Settings Seekmodo Search Typeahead dropdown. The enable
toggle defaults OFF so an upgrade on a site that already has its
own theme-level typeahead (e.g. trek.ca’s
inc/seekmodo-search.php) doesn’t double-render. - Added:
seekmodo_enqueue_typeahead,
seekmodo_typeahead_selectors, andseekmodo_typeahead_config
filters so themes can suppress or customise the connector UI
without forking the JS. - Compat: existing
assets/typeahead/seekmodo-beacon.jsclick
attribution picks updata-seekmodo-id/data-seekmodo-pos/
data-seekmodo-surface=”typeahead” attributes the new dropdown
emits — no second beacon, no separate REST endpoint, click-through
data flows through the same EventsQueue pipeline.
0.3.4
- Added: editorial post-type ranking priority. After the gateway
scores results by textual relevance, hits whose post type appears
earlier in the configured priority list are bucket-sorted to the
top. Within each tier the gateway’s relevance order is preserved
— we don’t re-score textual relevance, just bucket-sort by post
type. Configurable via the newSearch ranking priorityfield on
Settings Seekmodo Search, or by setting the
seekmodo_wp_post_type_priority option directly. The
seekmodo_post_type_priority filter overrides for site-specific
mu-plugins. Default is empty — no re-rank, gateway order flows
through untouched. Fixes the trek.ca complaint where blog posts
dominated?s=PPCwhile the high-intent/services/pages got
buried below the fold.
0.3.3
- Fixed: the v0.3.2 pair-callback REST route at
/wp-json/seekmodo/v1/connect/callback was registered behind
Bootstrap::boot()’sis_admin()gate, so the route never
appeared on the server-to-server POST from seekmodo.com (REST API
requests are not “admin” in WordPress’s classification). The
admin-side Connect button worked, but the JWT callback POST
silently 404’d and pairing died at the last step. v0.3.3 lifts
ConnectFlow::register() out of theis_admin()block so the
rest_api_init hook always runs. The
admin_post_seekmodo_wp_connect hook stays registered globally
too (harmless — it only fires onadmin-post.phphits).
0.3.2
-
Fixed: the “Connect to Seekmodo” pairing flow has been
rebuilt on the canonicalinstall_token+ signed-JWT protocol
(the same protocol Seekmodo for Zen Cart has used since v1.0.x).
v0.3.0 and v0.3.1 sent legacynonce+return_toquery params
that seekmodo.com rejects with “This link is incomplete” — the
redirect-back side of that protocol was an aspirational design
that was never implemented on the seekmodo.com side. Pairing
through the browser was impossible until this release.Admin\ConnectFlow::initiate()now mints a 32-hex
install_token (10-min TTL) and sends
?install_token=&callback= to seekmodo.com/connect.- The new
Admin\ConnectFlow::handleCallback()is registered as a
public REST endpoint at
wp-json/seekmodo/v1/connect/callback. seekmodo.com POSTs
{token, install_token} to that URL with the
X-Seekmodo-Install-Token header. - The new
Connect\Pairingclass verifies the EdDSA-signed JWT
againsthttps://seekmodo.com/.well-known/jwks.json, validates
the standard claims (iss/aud/exp/install_token), and persists
tenant_id +shared_secret+mcp_url.
-
Removed:
Gateway\Client::verifyClaimToken()and the matching
wp seekmodo connect –token=<…> CLI flag. They both round-tripped
through a/v1/connect/verifyendpoint that the gateway never
implemented; users hitting that path were getting silent failures.
The CLI pair still works via--tenant=--secret=for
headless / CI installs. -
Required: PHP
sodiumextension (ext-sodium) — needed for the
JWT signature verify. It’s part of core PHP since 7.2 and shipped
on default cPanel/EasyApache builds, but if it’s not loaded the
pair-callback surfaces a cPanel-specific install hint
(yum install -y ea-php82-php-sodium).
0.3.1
- Fixed:
Admin\ConnectFlow::initiate()called
wp_safe_redirect(‘https://seekmodo.com/connect?…’) without
whitelisting the connect host. WP’s redirect validator silently
rewrote the destination back to the site root, landing the
operator on the WP admin homepage instead of the connect page —
pairing was impossible via the browser flow. Thewp seekmodoCLI path was unaffected. Now registers a one-shot
connect
allowed_redirect_hosts filter for the connect host (overridable
via the existingseekmodo_connect_base_urlfilter) for the
duration of the redirect call only.
0.3.0
- Changed: Commerce vertical doc shape realigned to the gateway
Typesense schema.Commerce\ProductFields::buildDoc()now emits
gateway-canonical field names —name,url,in_stock(bool),
category_id[],category_breadcrumbs[],image_url,
description (combined excerpt + content_plain, HTML-stripped, 4
KB cap),last_indexed_at, plus optionalon_sale,sale_price,
currency. Removes pre-v0.3.0 WP-shaped names (title,
permalink,stock_statusstring,regular_price,excerpt,
content_plain,attributes,variations[],categories,
post_type,extra) that the gateway’s strict-schema Typesense
was rejecting on every upsert. - Changed: Commerce schema version split out from the content
schema version so a commerce-only realignment doesn’t trigger an
unnecessary content-side full reindex. New
Options::OPT_COMMERCE_SCHEMA_VERSION (commerce_schema_version
in wp_options) is consulted byCommerce\Indexer::tick()and
triggers a one-shot full reindex on upgrade — same trick as the
v0.1.1 content-side bump. - Added: Self-service “Promote dev production” card on the
Seekmodo Search settings page. Surfaces when the connector’s
current host looks like a non-prod environment
(dev|staging|stage|test|qa|preview|sandbox) and the canonical
lock matches that host. One-click POST to the gateway’s new
tenant.domain.promote MCP tool flipslocked_domainto the
selected production host. Within 5 min the dev plugin’s next
tenant.snapshot pull sees the new lock and goes silent
(DomainLock mismatch), so dev / staging mirrors stop polluting
production search analytics automatically. Closes the operator
round-trip the v0.2.x flow required. - Added:
Gateway\Client::promoteCanonicalDomain()thin HTTP
helper for the new tool. Same HMAC envelope as every other
gateway call. - Added: Admin-app mirror —
tenant-settings-form.tsxnow shows
a “Promote dev to production” hint band + one-click action when
the tenant is locked to a non-prod host and a prod-looking
connector has authenticated. Pre-fills the locked-domain field
with the most-recently-seen prod host; operator clicks Save to
apply.
0.1.4
- Added: WordPress.org Plugin Directory submission readiness.
Plugin headerUpdate URI: https://seekmodo.com/plugins/seekmodo
(WP 5.8+) routes update checks to our marketing-site endpoint, so
the plugin lists at https://wordpress.org/plugins/seekmodo/ for
initial install + searchability while all subsequent
version-checks and zip downloads happen against seekmodo.com. - Added:
Numinix\SeekmodoWordPress\Updates\WporgUpdateClient—
hooksupdate_plugins_seekmodo.com(the filter key WP core
synthesises from ourUpdate URIheader) and the
plugins_api plugin_information “View details” modal. Reads
fromhttps://seekmodo.com/api/plugins/seekmodo, cached 12 h on
success and 5 min on failure. Endpoint is filterable via
seekmodo_wporg_update_endpoint for staging. - Changed: Plugin name shortened from “Seekmodo Search for
WordPress” to “Seekmodo Search” (w.org plugin-review guideline:
the “for WordPress” suffix is discouraged when the plugin is
listed there). - Changed: Plugin description rewritten for w.org’s plugin-card
preview, with explicit SaaS-dependency disclosure and free-trial
note matching the Mailchimp / Algolia / Akismet pattern. - Changed:
Tested up to: 6.6added to plugin header + readme so
the WP-admin compatibility filter and the w.org directory listing
reflect the latest tested WordPress release. - Fixed:
tools/build_release.py --auto-prnow writes a manifest
entry whose schema matches the liveplatforms.zen_cartentry
exactly (sha256/sig/sig_kid/signed_at/signed_with
/released_at/release_notes_url) instead of the orphan
sha256_url /signature_url/released_at_utcshape it
produced before. Also replaces a Unix-only
subprocess.check_output([“date”, …]) with portable
datetime.now(timezone.utc).
0.1.3
- Add: per-tenant “Powered by Seekmodo” branding toggle. Off by default;
operators turn it on from the admin.seekmodo.com tenant settings page
for partner / specific-deal sites. New helpers
numinix_seekmodo_show_branding() andnuminix_seekmodo_brand_url()
for themes, withseekmodo_show_brandingandseekmodo_brand_url
filters.
0.1.2
- Fix:
AutoPromotersubstate FSM is now actually wired up. Previous
versions never advanced theactive+shadow → active+enforce
substate, and the SearchSwaps consulted the headline mode instead
of the effective mode, soauto_promote=truewas decorative.
MODE=active now correctly bakes into enforce on healthy metrics
and demotes back to shadow on a breach. - Fix:
MODE=active+auto_promote=falsenow correctly collapses
to a hard enforce (operator opt-out of the safety hop).
0.1.1
- Fix: Content indexer doc shape aligned with the gateway’s strict
Typesensecontentcollection schema. Previous releases would
have 400’d on everyindex.upsert. - Bumped
Options::SCHEMA_VERSIONto force a full reindex on
upgrade.
0.1.0
- Initial release. Sprints 0-5 shipped: content + commerce verticals,
mode FSM with auto-promoter, shadow-mode diff logger, typeahead,
click beacon, events queue, health widget, signed-zip release
pipeline.
