Skip to content

Releases: xenroth/xen-ai

v1.3.3 - Stable Release

Choose a tag to compare

@xenroth xenroth released this 28 May 06:04

[1.3.3] — 2026-05-28

Bug Fixes

  • License activation — "invalid token" error resolvedvalidate_token() in class-license.php was unconditionally re-computing the HMAC signature using the local placeholder secret, which never matched the server's private signing key, causing every activation attempt to fail with "The server returned an invalid token. Contact support." even though the server had already stored the record correctly. HMAC verification is now conditional: it only runs when a real secret is available (per-activation stored secret → XEN_AI_HMAC_SECRET constant → xen_ai_hmac_secret option). When none of those are present it falls through to payload-level checks (domain binding, product name, key match) which are sufficient for tamper detection.
  • Per-activation HMAC secret handshake — on a successful activation the server now returns hmac_secret alongside the token. The plugin stores it (encrypted) in the license record and uses it automatically for all subsequent is_active() checks. Clients never need to touch wp-config.php.

v1.3.2 - Release

Choose a tag to compare

@xenroth xenroth released this 28 May 04:36

[1.3.2] — 2026-05-28

Improvements

  • Removed "Coming Soon" badge from Pro card — all four Pro features (Proactive Visitor Questioning, KB Topic Insights, Purchase Guide, Topic Quick-Menu) are fully implemented and activate automatically upon license activation. The badge has been removed to accurately reflect availability.

[1.3.1] — 2026-05-29

Branding

  • Official plugin icon addedassets/icon-128x128.png and assets/icon-256x256.png added to the repository for display on WordPress.org plugin listing pages.
  • Plugin list iconclass-updater.php now returns icons (1x/2x) in both the update transient and plugin_information response, so the XEN AI logo appears in the WordPress admin Plugins list and Updates screen for self-hosted installs.
  • Banner addedassets/banner-772x250.png added for the WordPress.org plugin header banner.

[1.3.0] — 2026-05-28

WordPress Repository Compliance

  • All echo statements properly escaped — every echo in the admin view files (dashboard.php, leads.php, license.php) now wraps output in esc_html() or esc_attr() as appropriate. Values going into HTML attributes use esc_attr(); values going into HTML content use esc_html(). This eliminates the most common reason for WP.org plugin review rejection.
  • External services disclosure completed in readme.txt — added the three previously undisclosed external calls: ip-api.com (geo-IP in Leads dashboard), api.xenroth.com (Pro license validation), and Cloudflare Turnstile (challenges.cloudflare.com, optional bot challenge). WP.org requires every external HTTP call to be disclosed.

v1.3.1 - Release

Choose a tag to compare

@xenroth xenroth released this 28 May 04:33

[1.3.1] — 2026-05-29

Branding

  • Official plugin icon addedassets/icon-128x128.png and assets/icon-256x256.png added to the repository for display on WordPress.org plugin listing pages.
  • Plugin list iconclass-updater.php now returns icons (1x/2x) in both the update transient and plugin_information response, so the XEN AI logo appears in the WordPress admin Plugins list and Updates screen for self-hosted installs.
  • Banner addedassets/banner-772x250.png added for the WordPress.org plugin header banner.

[1.3.0] — 2026-05-28

WordPress Repository Compliance

  • All echo statements properly escaped — every echo in the admin view files (dashboard.php, leads.php, license.php) now wraps output in esc_html() or esc_attr() as appropriate. Values going into HTML attributes use esc_attr(); values going into HTML content use esc_html(). This eliminates the most common reason for WP.org plugin review rejection.
  • External services disclosure completed in readme.txt — added the three previously undisclosed external calls: ip-api.com (geo-IP in Leads dashboard), api.xenroth.com (Pro license validation), and Cloudflare Turnstile (challenges.cloudflare.com, optional bot challenge). WP.org requires every external HTTP call to be disclosed.

v.1.2.9 - Release

Choose a tag to compare

@xenroth xenroth released this 28 May 04:10

[1.2.9] — 2026-05-28

Improvements

  • Announcement bar spacing — added bottom margin below the version announcement bar so the stats cards no longer stick to its bottom edge.

v1.2.8 - Release

Choose a tag to compare

@xenroth xenroth released this 28 May 03:57

[1.2.8] — 2026-05-28

New Features

  • Version announcement bar on dashboard — a persistent dark-slate banner now appears on the dashboard for both free and pro users, celebrating the current release with key highlights and a direct invite to join the LINE community. Previously the community bar was accidentally commented out and only the free-tier promo banner contained a LINE invite (meaning pro users never saw it after activating).

WordPress Repository

  • readme.txt created — added the WP.org-required readme.txt with proper format: plugin header block, full feature descriptions, installation steps, FAQ, external services disclosure (OpenAI, GitHub Models, QR API), screenshot list, and full changelog.
  • Author URI corrected — changed from mailto:me@xenroth.com (invalid for WP.org) to https://github.com/xenroth.

v1.2.7 - Release

Choose a tag to compare

@xenroth xenroth released this 28 May 03:09

[1.2.7] — 2026-05-28

Improvements

  • Proactive email capture after the 4th reply — the bot now asks for the visitor's email address on its 4th reply (after 3 exchanges), making the ask feel like a privilege rather than a data grab. The AI frames it wittily — something like "I don't do this for everyone, but you've been such a pleasure to chat with — would you mind sharing your email? I'll make sure you're first to hear about any exclusive offers. Zero spam!" — then never asks again. Before the 4th reply the bot stays focused on helping; after the ask it only captures email if the visitor volunteers it naturally.

    Technically: reply_count is now tracked per session (counted from the in-memory message history) and passed to the system prompt builder. Three reply-count branches drive distinct instructions: too-early (don't ask), on-the-dot (ask wittily), already-asked (don't push).


[1.2.6] — 2026-05-28

Improvements

  • System Status: Test Connection button — a new "🔌 Test Connection" button in the System Status card makes a live API call and immediately tells you whether your key is valid, has no credits, or is failing for another reason. This makes it easy to diagnose why the chatbot shows the fallback message without needing to check error logs.

  • System Status: Fallback Mode indicator with Clear button — when the xen_ai_api_unavailable transient is active (meaning the chatbot is in offline/fallback mode after a quota or rate-limit error), a clear warning is now shown in the System Status card with a "Clear Now" button to exit fallback mode immediately without waiting the full 5 minutes.

  • System Status card spacing — added bottom margin below the System Status card so subsequent sections on the dashboard are visually separated.

Bug Fixes

  • $is_auth pattern too broad — the previous 'authentication' substring check in map_error_to_friendly() could match incidentally in non-auth error messages (e.g. phrases like "authentication required for additional usage"). Removed the broad match and kept only the specific patterns (incorrect api key, invalid api key, invalid authentication, unauthorized, 401).

v1.2.5 - Release

Choose a tag to compare

@xenroth xenroth released this 28 May 02:43

[1.2.5] — 2026-05-28

Bug Fixes

  • "I'm a little busy" shown on first message after setting a new API key — when an API error (quota, billing, 429) occurs, the plugin sets a xen_ai_api_unavailable transient for 5 minutes that blocks all subsequent requests. Previously, this transient was never cleared when settings were saved, so saving a new valid key would still return the fallback message until the transient expired. Fixed by calling delete_transient('xen_ai_api_unavailable') at the end of every settings save.

  • Invalid API key not distinguished from quota exhaustion — a 401 "Incorrect API key" response from OpenAI hit the catch-all error path ("I'm having trouble responding"), which was confusing and could be mistaken for a temporary issue. Auth/unauthorized responses are now detected separately and routed to the "not fully set up" message, making it clear the key itself is the problem rather than the API being unavailable.


[1.2.4] — 2026-05-28

Improvements

  • System Status moved to top of dashboard — the System Status card now appears as the first section on the dashboard, above the community bar, stats grid, and all other content, so the API connection state and plugin version are immediately visible.

v1.2.3 - Release

Choose a tag to compare

@xenroth xenroth released this 28 May 02:34

[1.2.3] — 2026-05-28

Bug Fixes

  • API key save regression (proper fix) — the 1.2.2 focus/blur mask-clearing approach was fragile: it depended on character-exact comparison between the JavaScript constant and the PHP-rendered value, and silently failed if the user never clicked the field before saving. The architecture has been corrected: all three secret fields (api_key, github_token, turnstile_secret_key) now render with value="" and display the •••••••• indicator only in the placeholder. An empty submission means "keep existing key"; any non-empty submission is treated as a new key. The PHP preserve logic is simplified to a single empty-string check. A one-time DB cleanup also strips any previously corrupted ••••••••-prefixed values that may have been saved before this fix.

v1.2.2 - Release

Choose a tag to compare

@xenroth xenroth released this 28 May 02:19

[1.2.2] — 2026-05-28

Bug Fixes

  • OpenAI API key not saving — the API key (and GitHub token / Turnstile secret) fields displayed a •••••••• mask as their literal value. Typing a new key on top of the mask caused ••••••••new_key to be saved instead of just the new key, making the API call fail silently. Fixed by adding focus/blur handlers in admin.js: the mask is cleared when the user focuses the field so they can type a fresh value; if the field is left empty on blur, the mask is restored so the existing key is preserved on save.

  • Chatbot widget shows double greeting on empty knowledge base — when Pro is active, startSession() appended a page-contextual greeting to the chat messages while the widget was still closed. When the user then opened the chat, open() saw greeted = false and appended the static greeting again, resulting in two opening messages. Fixed by setting XenChat.greeted = true in chat.js when the Pro greeting is received, so open() skips the redundant static greeting.

Improvements

  • Announcement bar update reminder — the Community & Announcements strip on the Dashboard now includes a reminder to check for updates under WordPress → Plugins to ensure the latest version is always installed.

v1.2.1 - Release

Choose a tag to compare

@xenroth xenroth released this 27 May 15:28

[1.2.1] — 2026-05-27

Improved

  • Leads deduplication — the Leads page now groups conversations by visitor name + IP and surfaces one representative row per unique person (prefers the row that captured an email), eliminating repeated entries for multi-session visitors.
  • Leads search / filter — a search bar at the top of the Leads table filters results by name, email, or IP address in real time (form-based GET request, no JS dependency).
  • Sortable columns — Name, Email, IP, Message count, and Date columns are all clickable to sort ascending or descending; active column is highlighted.
  • Geo-IP country detection — the IP Address column now resolves each unique IP to a country flag + name via ip-api.com (client-side, batched, staggered to stay within the free 45 req/min rate limit).
  • CSV export improvements — Export CSV now applies the same deduplication logic and search filter as the on-screen table, and includes a new Country column resolved server-side via ip-api.com. Private/reserved IP ranges are labelled Local/Private without an external call.