=== ChatFlint ===
Contributors: ranakpik
Tags: chatbot, ai, live chat, customer support, knowledge base
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 1.59.0
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

RAG-powered AI customer-service chatbot: your own knowledge base, six AI providers, streaming replies, live human handoff, leads and analytics.

== Description ==

ChatFlint answers your visitors' questions from **your own content** — pages, posts, products, documents, crawled websites and hand-written Q&A — using retrieval-augmented generation (RAG) with hybrid vector + keyword search.

**AI providers (bring your own key)**

* OpenAI, Anthropic Claude, Google Gemini, DeepSeek, Grok (xAI), OpenRouter
* Live model lists per provider, connection testing, optional automatic failover to a second provider
* Embeddings via OpenAI or Voyage AI (free tier), optional Supabase pgvector storage

**Knowledge Base**

* Guided "Add Knowledge" flow: WordPress content, website crawl, sitemap import, PDF/DOCX upload (browser-side extraction, per-page chunks, on-demand OCR), Q&A pairs, and a rich text editor with smart chunking
* Page-builder aware extraction: Elementor, Divi and Gutenberg (including dynamic blocks) sync their real content with headings, lists and tables preserved
* Long pages are stored as grouped, section-labeled chunks ("About us — Pricing"), shown as one expandable item per page in the entries list
* Crawls skip archive/tag/category noise and shop-facet URLs by default; per-URL exclusions; selective per-item sync
* Automatic keep-in-sync for WordPress content and WooCommerce products; unchanged content is never re-embedded (no repeat cost)
* "Preview as the bot sees it" per page, retrieval tester, duplicate/overlap scanner, per-entry usage analytics, knowledge-gap detection

**Website guide**

* The bot doesn't just answer — it links visitors to the right page (contact, services, projects, products) using your menu and the pages behind each answer, and can never invent URLs

**Shopping assistant (WooCommerce)**

* "Suggest me a good chair for computer work" → 3-5 matching products as cards (image, price and sale price, stock, rating, one-line why) with a best pick, plus refinement chips (cheaper, best rated, compare)
* Side-by-side comparison of the products it recommends, on the attributes that actually differ
* Understands budgets, categories, colours/sizes and must-have features, and follow-ups like "the second one" or "show me cheaper options"
* Add to cart from the chat (variations included), a mini-cart with a Checkout button, and "what's in my cart?" — prices and stock always come from your catalog, never from the AI; the bot never adds anything without a confirmation
* Shopping funnel on the Analytics page (saw cards → opened → added → checkout) and per-category exclusions

**Chat widget**

* Modern, fully themeable (light/dark/soft presets, colors, radius, avatar, fonts) with live preview in the admin
* Style-isolated: host-theme CSS cannot restyle the widget — your Design settings apply identically on any site
* Streaming replies with markdown rendering, attachments, quick replies, home screen, proactive teasers
* Calibrated answer length: short answers for simple questions, structured ones only when the question calls for it
* Accessible: screen-reader announcements, keyboard support, reduced-motion aware
* Consent gate, right-to-be-forgotten requests, chat history for returning visitors, email transcripts

**Support workflow**

* Live human handoff with admin inbox, canned replies, business hours + offline messages
* Lead capture (forms, exit intent, keyword triggers) with CSV export
* WhatsApp Cloud API integration, Telegram/email notifications
* Ratings & CSAT, analytics with token usage and estimated cost per provider/model

**Safety & operations**

* Rate limiting (per-session, daily, global), honeypot + timing spam protection
* GDPR tooling: retention cleanup, deletion-request inbox, opt-in full uninstall cleanup
* Translation-ready (text domain `chatflint`, POT included)

== External services ==

This plugin talks to third-party services. Nothing is sent until you enter a key
for that service and enable the feature that uses it. No data is ever sent to the
plugin author.

**AI provider (required — you choose one).** Your visitor's question, the matching
extracts from your knowledge base, recent messages in that conversation and your
system prompt are sent each time the bot answers, so it can write a reply. The
provider you configure is the only one contacted:

* OpenAI — https://openai.com/policies/terms-of-use/ · https://openai.com/policies/privacy-policy/
* Anthropic — https://www.anthropic.com/legal/consumer-terms · https://www.anthropic.com/legal/privacy
* Google Gemini — https://ai.google.dev/gemini-api/terms · https://policies.google.com/privacy
* DeepSeek — https://platform.deepseek.com/downloads/DeepSeek%20Terms%20of%20Use.html · https://platform.deepseek.com/downloads/DeepSeek%20Privacy%20Policy.html
* xAI (Grok) — https://x.ai/legal/terms-of-service · https://x.ai/legal/privacy-policy
* OpenRouter — https://openrouter.ai/terms · https://openrouter.ai/privacy

**Embeddings (required).** Your knowledge-base content is sent once when indexed,
and each visitor question is sent when it is searched, to turn text into vectors:

* OpenAI — links above
* Voyage AI — https://www.voyageai.com/terms-of-service · https://www.voyageai.com/privacy-policy

**Optional, off unless you switch them on:**

* Supabase (pgvector storage, your own project): your knowledge-base text and
  vectors are stored there instead of locally — https://supabase.com/terms · https://supabase.com/privacy
* WhatsApp Cloud API (Meta): messages and phone numbers are exchanged so the bot
  can answer on WhatsApp — https://www.whatsapp.com/legal/business-terms · https://www.whatsapp.com/legal/privacy-policy
* Telegram (owner alerts): the alert text is sent to your own bot and chat —
  https://telegram.org/tos · https://telegram.org/privacy
* Tesseract.js, loaded from the jsDelivr CDN only when you import a scanned PDF
  that needs OCR. The file is fetched in your browser and the document is read
  locally; the document itself is not uploaded — https://www.jsdelivr.com/terms · https://www.jsdelivr.com/privacy-policy

== Installation ==

1. Upload the plugin and activate it.
2. Follow the setup wizard: pick an AI provider, paste your API key, pick a model.
3. Add knowledge: Knowledge Base → Add Knowledge (your WordPress pages are the fastest start).
4. The widget appears on your site immediately — customize it under Settings → Widget Appearance.

== Frequently Asked Questions ==

= Do I need an API key? =
Yes — one key from any supported provider (OpenAI, Anthropic, Google Gemini, DeepSeek, Grok or OpenRouter). Usage is billed by that provider; the plugin shows estimated costs on the Analytics screen.

= Where do answers come from? =
Only from the knowledge you add. When nothing relevant is found, the bot says it doesn't have the information (and can hand off to a human) instead of inventing an answer.

= Does it work on shared hosting? =
Yes. Background jobs are batched and resumable, streaming avoids buffering, and no build tools or exotic extensions are required.

= Does it support multilingual sites (WPML / Polylang)? =
Yes. Synced content is tagged with its language, and the bot answers Dutch visitors from the Dutch pages and English visitors from the English ones — including the page links it recommends. The bot also replies in the visitor's language automatically.

= Does it work on multisite? =
The plugin is built and tested for single-site installs. On multisite it can be activated per site (each site gets its own knowledge base, settings and API keys), but network activation is not supported or tested.

== Changelog ==

= 1.59.0 =
* The chat widget got its 2.0 pass. The header is slimmer and carries a menu, so "new chat", the transcript, the data-deletion request and the privacy panel no longer stack up under the composer — that space goes back to the conversation.
* New: visitors can expand the chat to almost full height for a longer conversation, and collapse it again. The choice is remembered for the visit. Mobile is unchanged: it was already full screen.
* Conversation starters now open as proper cards under the welcome instead of small chips, so a visitor can see at a glance what the chat is for.
* Twelve ready-made looks on the Design screen — Flint, Midnight, Ocean, Forest, Royal, Sunset, Aurora, Coral, Slate, Graphite, Sand and Mint — each a complete palette for a chat window. Pick one to fill in every colour, then change anything: the moment you do, the look becomes "Custom". Your existing colours are untouched until you pick one.
* New header fills: a second colour for a two-tone gradient, and "wash", where the header colour fades down into the conversation instead of stopping at a hard edge.
* The AI disclosure line is shorter and no longer eats a block of the window.
* The default chat window is a little larger (380x560).
* The admin screens are back to blue. It sits better inside wp-admin than the yellow did; the brand yellow stays where it belongs, on the mark and as the widget's default colour.

= 1.58.0 =
* ChatFlint now looks like ChatFlint: the admin screens, the setup wizard and the chat widget all carry the brand from chatflint.com — flint yellow on near-black, with the ChatFlint mark in place of the generic chat icon.
* The widget's default accent colour is the brand yellow for new installs. Nothing changes on a site that already picked its own colour: your saved appearance settings are untouched.
* Text colour on a coloured surface keeps adjusting itself, so a light accent gets dark text and a dark one gets light text — the yellow default reads correctly out of the box.
* Warnings in the admin moved from amber to orange, so a caution is never mistaken for the brand colour.

= 1.57.1 =
* The licence prices the trial screens mention now match the final published pricing (monthly from $6.99).

= 1.57.0 =
* New: a 7-day free trial. Install the plugin and start the trial from the setup wizard or Settings — for seven days the answers run on ChatFlint's own AI with a fair-use budget, so you can try everything before creating any AI provider account. Your content, settings and conversations are kept whatever you decide afterwards.
* During the trial the AI runs through chatflint.com: your visitors' messages are processed there and by OpenAI, and the in-widget AI & Privacy panel discloses exactly that while the trial is active.
* When the trial ends, the floating chat pauses and the dashboard offers the two ways forward — get a licence, or paste your own provider key — and the plugin switches over the moment you do either.
* Pricing on chatflint.com is now in US dollars, with a monthly option alongside the yearly and one-off licences.

= 1.56.1 =
* The update channel has moved to chatflint.com. This release still arrives from the old address and simply teaches your site the new one — nothing to do, and the old address keeps redirecting.

= 1.56.0 =
* Improved: the bot now reads more of your knowledge base before answering. It previously used only two passages per question, no matter how much you had trained it, which is why it could answer "I do not have that information" about something plainly on your site. Answers get noticeably more complete; on the cheapest models the extra context costs around two cents per hundred questions, and repeated questions still come free from the answer cache. Nothing to re-sync.
* Fixed: search quietly trusted words you never typed. A question like "which providers do you support?" was expanded with related words (help, assist, service, team, customer), and because those words were rarer in your content they counted for MORE than the word you actually asked about — so pages about your support team beat the page that answered the question. Your own words now always count for more.
* Improved: page addresses are now part of search. Pages often carry a slogan as their heading while the address names the subject plainly (/features/ai-providers/), and that address was previously invisible to search. Pages whose address matches the question now rank higher.
* Fixed: the Conversations, Leads and Human handoff lists could show the same row on two pages, or skip one between pages, when several arrived within the same second. A captured lead can no longer go missing from the list.
* Fixed: opening the chat on a returning visit announced "New messages" over a conversation that could be days old.
* Fixed: on iPhones, tapping the message box zoomed the whole page in and pushed the chat off the screen.

= 1.55.0 =
* The plugin is now called ChatFlint. The name changes everywhere you see it — the plugins list, the admin menu, emails and the widget — but nothing you have configured or trained changes with it: your settings, knowledge base, conversations, leads and uploaded files all carry over untouched.
* Existing `[ai_chatbot]` and `[ai_chatbot_inline]` shortcodes keep working exactly as before, so pages that embed the chat need no edits. New `[chatflint]` and `[chatflint_inline]` shortcodes do the same thing.
* Note for site owners updating by hand: because the plugin folder is renamed, WordPress treats this as a new plugin. Install and activate ChatFlint, check your settings and knowledge base are intact, then deactivate and delete the old one.

= 1.54.2 =
* Improved: when two entries are so alike that search cannot separate them — a page and last season's copy of it — the more recently updated one now comes first, so an outdated price list stops outranking the current one.
* Fixed: re-embedding the knowledge base (the "Re-embed all" button, or switching embedding model) stamped every entry as freshly updated, even though the content had not changed. That distorted "last updated" in the admin and the freshness signal search now uses.
* Added for developers: an `ai_chatbot_pre_embedding` filter, so a local or custom embedding model can be plugged in without touching the plugin.

= 1.54.1 =
* Fixed: the keyword half of hybrid search bound its query parameters in the wrong order, so a question that expanded to two or more search words only really searched the last one — and scored the matches it did find against the wrong words. Questions phrased around a word that appears in your content could come back with "I do not have that information". Retrieval quality improves on every site; no re-sync or re-embedding is needed.

= 1.54.0 =
* New: Shopping assistant for WooCommerce. When a visitor is looking for a product, the bot recommends 3-5 matching products as cards (image, price, sale, stock, rating), names a best pick, compares them side by side, understands budgets, categories, colours and must-have features, and follows up naturally ("the second one", "show me cheaper options", "compare the ErgoFlex with the AeroSit"). Visitors can add products to the cart from the chat (variations included), see a mini-cart and go straight to the checkout; the bot never adds anything without a confirmation. Prices and stock always come from your catalog.
* New: Design → Widgets → Shopping Assistant card (cards per answer, exclude categories, allow add-to-cart) and a Shopping funnel panel on Analytics (saw cards → opened → added to cart → checkout, most recommended / most added products).
* New: structured product facts next to the product text (price, sale, stock, rating, categories, attributes, variations, image) that stay live on price, stock and sale changes even when auto-sync is off; System Health shows "Products (shopping assistant)".
* Improved: product search is scoped to the catalog and combines semantic matching with real filters (budget, stock, category, attributes), so "chairs under 200" finds the cheap chair too.
* WhatsApp: product recommendations arrive as numbered lines with prices and links.
* Privacy: shopping events are per session and covered by data retention and deletion requests.

= 1.53.0 =
* New: one-click updates. The plugin now ships with its update channel built in — new versions appear on the Plugins screen like any other plugin, and System Health shows which channel a site checks. Sites on 1.52 or older need one last manual upload to get onto it.
* New: Answer voice (Settings → Behavior). Make every reply speak as the business ("we"), as the owner ("I"), or as an assistant that refers to the business by name — no more answers that switch between "I", "we" and the owner's name because pages and Q&A were written differently. The default keeps the previous behaviour.
* Improved: every confirmation and notice in the admin is an in-page dialog instead of a browser pop-up (Enter confirms, Escape cancels; destructive actions default to Cancel).
* Security: requests to the chat and form endpoints from other websites are refused (same-site origin check), and the anti-spam token on visitor forms is now mandatory instead of optional.
* Improved: streaming replies send a keep-alive before the search step so slow retrievals no longer trip proxy time-outs; one database query fewer per answer; the ratings panel on Analytics loads with one query instead of nine.
* Fixed: Analytics insights and trends used the database server's clock instead of the site timezone, so day buckets could shift by the site's UTC offset.
* Fixed: WooCommerce product labels (Price, Stock, Category, SKU, Tags) are indexed in the site language (Dutch included). Non-English shops re-index their products once on the next sync.
* Fixed: starting a content sync while another was mid-batch (a second tab, or cron) wiped the running job's queue; the admin now attaches to the running job instead.

= 1.52.0 =
* Stability release from a full code review. Highlights:
* Fixed: pages synced before 1.50 now pick up the contact-link extraction on the next sync (the fingerprint was not bumped, so unchanged pages were skipped).
* Fixed: the answer cache no longer clears itself on multilingual sites — each language keeps its own cached answers.
* Fixed: a provider outage or bad key no longer shows the raw provider error text in the chat; visitors see a friendly retry message and the error goes to the log.
* Fixed: human handoff can no longer be triggered while the handoff feature is switched off.
* Fixed: the answer safety-net that repairs a dropped "don't" no longer double-negates or flips genuine answers.
* Fixed: answers ending "please contact us" are no longer logged as knowledge gaps or excluded from the cache.
* Fixed: rate limiting behind a reverse proxy (nginx, load balancers) could be bypassed with a forged X-Forwarded-For header.
* Fixed: an agent could not answer a conversation that asked for a human a second time (it showed as resolved).
* Fixed: re-running the setup wizard after rotating an OpenAI key silently restored the old key.
* Fixed: widget — an empty streaming response now falls back to a normal request; closing via the exit-intent form no longer leaves the mobile page unscrollable; the rating prompt no longer reopens the window; handoff polling cannot multiply; requests time out instead of hanging.
* Fixed: WhatsApp — failed sends (expired token, replies outside the 24-hour window) are logged and shown to the agent; duplicate webhook deliveries are answered once; every message in a batch is handled.
* Fixed: background sync and crawl workers can no longer process the same item twice (atomic claims), and the crawler removes pages that return 404/410.
* Fixed: thumbs-down comments were stored under a truncated type and lost; existing rows are repaired.
* Security: API keys, tokens and secrets are no longer echoed into the Settings, Design or Wizard pages (write-only fields with a Clear option); WhatsApp sessions cannot be addressed from the public widget routes.
* Performance: rate-limit counters are now atomic (exact under bursts, including the global daily spend cap); the knowledge-base state fingerprint is computed once per request with a new index; cached answers keep compact packed vectors; Supabase mirror deletes go out in batches; the knowledge-gaps table check no longer runs on every admin page; the Knowledge Base sources table and the Human Handoff inbox (now paginated) no longer rebuild every item on each load; the Entries list loads an entry's text only when you edit it.
* Hardening: the crawler caps downloads (5 MB per page, 20 MB per sitemap) and connects to the exact address the safety check approved; targeted sync ignores non-public post types; a failed document upload keeps the previous version instead of storing a half-written one.
* Improved: with multilingual replies off the bot answers in the site language, not English; OpenAI reasoning models work; queries with many synonyms no longer bloat search; duplicate chunks no longer waste context slots; cross-language search also works on WPML/Polylang pages; the chatbot name and system prompt no longer bake their defaults on first save; WooCommerce variable and sale prices index correctly and stock changes from orders re-sync; the privacy panel describes IP handling accurately.

= 1.51.0 =
* New: cross-language search. A question written in an alphabet your knowledge base does not contain (Bengali, Arabic, Cyrillic, Chinese… against an English site) is now translated into your knowledge base language purely for searching, so the bot finds the answer instead of "not knowing" it. One small AI call per distinct question, remembered for 30 days; same-alphabet questions (Dutch on an English site) are never translated. On by default; Settings → Behavior → Multilingual Replies.
* Improved: keyword search now weighs rare words more than common ones, so "phone number" finds the entry about your phone instead of every page that mentions a number.
* New: importing Q&A pairs updates an existing entry with the same question instead of adding a duplicate (checkbox in the Q&A panel, on by default). Unchanged rows cost nothing; older duplicates of the same question are merged.
* New: stale-answer watch. When a synced or crawled page changes and drops an email address, phone number, link or price that one of your own Q&A entries or Business Facts still states, the Knowledge Base page and System Health flag it for review.

= 1.50.0 =
* Fixed: contact details that only existed inside a link were lost when training. A "WhatsApp" button, an "Email us" link, a click-to-call number, a Calendly booking button or an Instagram icon now sync as "WhatsApp (https://wa.me/…)", "Email us (info@…)" and so on, so the bot can actually hand visitors the number, address or link. Applies to synced pages, Elementor buttons and icon lists, ACF link fields and crawled pages. Ordinary page links are unchanged. Re-run a sync (or crawl) once to pick the links up.
* The website guide may now share those contact links, while still never inventing or altering a URL.

= 1.49.0 =
* New: content roles. Every knowledge entry is now either official business information or a background article (blog posts and article-style crawled pages are detected automatically, and you can flip any item in the Entries list). The bot can still explain a background article's content, but will never state a service, price, partnership or commitment based on one — your blog posts can no longer turn into promises you didn't make.
* New: Business Facts panel (Settings → Behavior). One place for the facts that must never be wrong — contact email, phone, WhatsApp, address, opening hours, response time, booking link. The bot always answers these from the panel, even when an old page or Q&A entry still carries an outdated value; editing a fact also refreshes cached answers immediately.
* The generated privacy content now uses the Business Facts contact email as the data-questions contact when no dedicated privacy contact is set.

= 1.48.0 =
* New: AI Disclosure & Privacy Kit. The widget now shows a short line telling visitors they are chatting with an AI that can make mistakes (on by default — the EU AI Act and California's B.O.T. Act require this kind of disclosure), with a "How this works" link that opens an in-widget AI & Privacy panel.
* New: the AI & Privacy panel is generated from your live configuration — it names your actual AI provider (with a link to its privacy policy), lists exactly the data collected given the features you have on, shows your real retention period, and explains the visitor's rights and how to request deletion. Change a setting and the panel is already correct.
* New: privacy text for your own site, generated from the same source — suggested text in the WordPress Privacy Policy Guide, a one-click draft privacy page (never auto-published), and a Markdown download for your legal reviewer. Settings → Privacy.
* New: System Health has a "Privacy & Compliance" section (disclosure status, privacy-policy link, consent, retention), and the Setup Wizard has a final AI-disclosure step.
* Fixed: choosing a reply language while "Multilingual replies" was off silently did nothing — the bot kept answering in English with no hint why. The settings screen now says so in plain sight, and picking a language switches multilingual replies on for you. System Health also flags the dead combination.
* Fixed: on every real deployment so far, the lead form was fully configured but its master toggle was off — so the form never appeared and nobody noticed. The settings screen and System Health now warn loudly about that state.

= 1.47.0 =
* Improved: the number of knowledge-base candidates considered per question now scales with the configured context depth — fixes questions whose answer was indexed but crowded out of a fixed-size candidate pool by near-miss content.

= 1.46.3 =
* Fixed: the Setup Wizard had the same two problems the other screens had just been fixed for. Other plugins' notices landed inside the wizard card, and the "Chatbot name" and "Welcome message" fields came pre-filled with English text that was written into your site the moment you finished the wizard — so a Dutch site ended up with an English widget before it had even been used. Both fields now start empty and show the stock wording as a hint.

= 1.46.2 =
* Fixed: other plugins' notices and promotional pop-ups were being injected into the middle of our screens — a licence warning and a "rate our plugin" modal appeared inside the Human Handoff chat panel, squeezed into an unreadable column. WordPress moves notices to the first heading it finds on a page; our screens now give it a proper landing zone above the interface, so notices stay readable and our layout stays intact.
* Anything a plugin injects later, after the page has loaded, is moved out of the way automatically.

= 1.46.1 =
* Fixed: the privacy line under the lead capture form ("By submitting, you agree to our privacy policy") was missing from the Dutch translation, so it stayed English on Dutch sites. Found the first time the lead form was switched on.

= 1.46.0 =
* Fixed: the widget spoke English on non-English sites even though the translation shipped with the plugin. The settings screens pre-filled every text field with the English wording, so the first time you saved, that English text was written into your site and permanently replaced the translated version. Those fields now start empty and show the stock wording as a grey hint instead.
* New: clear any wording field and the widget uses the stock text in each visitor's own language. Type something and it is used exactly as written. On a Dutch site, an empty "Your name" field now shows "Je naam" with no further setup.
* If your widget is showing English text you never chose, clear those fields under Settings and save — the correct language appears automatically.

= 1.45.0 =
* New: your own wording is now translatable. The welcome message, "Talk to a Human" button, offline and timeout messages, lead-form labels, quick replies and teasers are exposed to WPML (String Translation) and Polylang (Strings translations), so each visitor sees them in their own language. Settings → AI & Language points you at the right screen.
* Fixed: on multilingual sites, an answer where the bot said it did not have the information was only recognised when it was written in English. Dutch, German, French, Spanish and other replies were treated as successful answers, so they never appeared under Knowledge Gaps and never triggered the "hand over to a human after repeated dead ends" rule. Declines are now recognised in every supported reply language.
* Improved: replies in other languages now read like a native speaker wrote them instead of a word-for-word translation of English phrasing (a Dutch visitor was being told "Ik ben sorry").
* Fixed: the thumbs up/down buttons under a reply sat beneath the bot's avatar instead of under the message when message avatars were switched on.
* Fixed: on sites with page caching, logged-in visitors could have live-chat polling blocked indefinitely by a mismatched security token, so replies from a human agent never arrived.

= 1.44.0 =
* New: Reset Knowledge Base (Knowledge Base → Tools). Clear indexed content by type — WordPress content, crawled pages, uploaded documents, manual entries — and start a fresh sync. Settings, API keys, conversations, leads and ratings are never touched.
* The reset also clears the matching sync ledger, so re-syncing genuinely re-indexes instead of reporting "already up to date".
* Faster cleanup on Supabase installs: mirrored vectors are deleted in batches instead of one request per entry.

= 1.43.0 =
* New: language-aware knowledge retrieval for multilingual (WPML/Polylang) sites — answers and recommended links come from pages in the visitor's language.
* New: the message box is now multi-line — Shift+Enter for a new line, and it grows as you type; line breaks are preserved in the chat.
* Improved: the widget follows right-to-left pages automatically.
* Improved: Dashboard stats are cached for five minutes (with a Refresh action), keeping the admin fast on busy sites.
* Improved: suggested quick replies stop repeating after the first few answers instead of padding every reply.
* Fixed: four widget texts (header title, home greeting, rating and consent prompts) were always English on translated sites even when left at their defaults.

= 1.42.0 =
* New: conversations restore from the server — a cleared browser cache or a page change mid-answer no longer loses the visitor's transcript.
* New: a thumbs-down now offers "Tell us what went wrong" and "Talk to a human" instead of being a dead end; no more double rating prompts on close.
* New: multi-line replies for support agents (Enter sends, Shift+Enter for a new line — canned replies keep their formatting), bot messages render formatted in the agent view, and the handoff list shows the visitor's real name/email when a lead was captured, plus last-activity times.
* Improved: resolutions record who resolved and when; a second agent's screen locks when a colleague resolves the chat; WhatsApp transcripts are no longer readable through the public widget endpoint.
* Improved: mobile full-screen chat respects notches/Dynamic Island, locks the page behind it, and keeps the composer above the iOS keyboard.

= 1.41.0 =
* Fixed: an agent reply could permanently hide a visitor message that arrived in the same moment (handoff polling race); conversations view now shows agent replies with proper Visitor/Bot/Agent labels; search result counts and list ordering corrected; "Delete conversation" now removes ALL related data (handoff messages, ratings, leads, attachments).
* Fixed: a slow-to-start AI reply could save the question twice and bill tokens twice; the widget now survives blocked browser storage (Safari "Block all cookies", enterprise policies) instead of not rendering at all.
* New: self-hosted one-click updates (define CHATFLINT_UPDATE_URL), admin-visible error log with copy-for-support system info on System Health, and a debounced email alert to the site owner when the AI provider starts failing.
* Performance: removed schema checks that ran on every wp-admin pageview and twice per second during live handoffs; auto-sync safety-net cron relaxed to 5 minutes; version constant no longer re-reads the plugin file per request.

= 1.40.0 =
* New: Website guide mode — answers now include links to the relevant page (contact, services, projects, products) from your menus and synced pages; the bot can only share links it actually knows and never invents URLs.
* New: widget style isolation — host-theme CSS can no longer restyle the chat (buttons, fonts, spacing); your Design settings apply identically on any site.
* Improved: clearer admin heading hierarchy across all screens.

= 1.39.0 =
* New: long pages sync as a few grouped, section-labeled chunks instead of dozens of tiny "Part N" entries; FAQ pages group related Q&A pairs; entries list shows one expandable item per page.
* New: rich text editor (WordPress' own) for the Text panel and entry editing — headings, lists and paragraphs are kept, stored as clean structured text the AI reads directly.

= 1.38.0 =
* New: crawls skip category/tag/author/date archive pages and shop-facet URLs by default (toggleable) — no more knowledge-base noise from listing pages; choosing "Sitemap" now errors clearly if no sitemap exists instead of silently link-crawling.
* Improved: every Add Knowledge flow ends in a clear completion state with a Done button and auto-refreshed counts; imports resume on reopen; failed starts no longer freeze the buttons.

= 1.37.0 =
* New: page-builder aware content extraction — Elementor (previously synced as empty!), Divi and Gutenberg dynamic blocks now sync their real content; headings, lists and tables survive as structure; every chunk knows its page URL and section.
* Fixed: large PDFs no longer collapse into a single unusable entry; documents chunk per page ("manual — page 7"); duplicate uploads under a new filename are detected.
* New: per-item "Preview as the bot sees it", honest sync status counts, visible failure reasons, persisted last-sync summary.

= 1.36.0 =
* New: calibrated answer length — simple questions get short answers, list questions get scannable overviews, detail only when asked.
* Fixed: lead forms with optional email rejected every submission; exit-intent overlay could permanently dead-lock the chat; lead form no longer interrupts streaming answers or re-asks after being dismissed twice.
* New: master widget on/off switch with a Dashboard status card ("Live on all pages" / "Hidden — no API key"), visibility checks in System Health, and a reorganized Design → Placement & Visibility tab.

= 1.34.0 - 1.35.0 =
* Security hardening pass (rate-limit bypass, stored XSS, nonce caching, vector search) and token-cost optimization (answer cache on by default, trimmed history resends, length calibration). Dutch (nl_NL) translation for all visitor-facing strings.

= 1.33.0 =
* New: Design → Widgets tab — all toggleable widget features (Home Screen, Quick Replies, Proactive Teasers, Message Avatars, Attachments, "Powered by" credit) now live on one screen as cards, each with its own on/off switch and an expandable settings panel. Click a card to configure it; switching a feature on opens its settings right away. Same options, same form — just a far cleaner way to manage them.
* Changed: Content & Text now focuses on chat identity (bot name, welcome message, time-based greetings); the Visibility tab keeps the page display rules.

= 1.32.0 =
* New: home screen v2 — the widget's landing view now leads with your company name in the header (bot name returns in chat), a big automatic time-of-day headline (Good morning/afternoon/evening — visitor's clock; or your own text), the greeting, an optional tagline, an inviting input-style "Chat with us…" button, a live availability card ("Online now / Typically replies in a few seconds", flipping to offline outside business hours), a "Try asking" grid of your quick replies, and a Home/Chat tab bar for easy switching. All texts editable under Design → Content & Text.
* New: teaser sequences — after the first proactive teaser bubble, up to two follow-up messages appear one after another, each individually dismissible, optionally followed by your first two quick replies as tappable chips (chip = open chat + ask it). Everything the teasers said continues inside the chat when it opens.
* New: unread badge on the chat button — counts teaser messages, and human-agent replies that arrive while the widget is minimized; clears on open. Toggleable under Design → Visibility & Extras.
* All new options ship in settings export/import; existing setups keep working unchanged until you customize.

= 1.31.0 =
* New: the Design page is reorganized into four tabs — Theme & Colors, Launcher & Window, Content & Text, Visibility & Extras — with a persistent live preview that stays on screen whatever you edit and now reflects everything: launcher (style, shape, size, icon, position), header, bubbles, quick replies, branding and text. A Chat/Home switch previews both widget screens.
* New: Auto (system) theme — the widget follows each visitor's light/dark preference.
* New: launcher options — circle or rounded-square shape, a 6-icon SVG library, or your own uploaded image, alongside the existing emoji choice.
* New: header fill choice — soft gradient (default) or solid color; brand-color swatch shortcuts next to the accent picker.
* New: time-based welcome messages — optional morning/afternoon/evening greetings picked by the visitor's local clock (empty slots fall back to the fixed message).
* All new options ship in settings export/import and default to the existing look — nothing changes until you opt in.

= 1.30.0 =
* New: custom avatars for human agents — each teammate can set a personal "Chat support avatar" on their WordPress profile, and a site-wide "Support team avatar" fallback lives under Design → Message avatars. Precedence: personal avatar → team avatar → WordPress profile picture (Gravatar). Older messages without a recorded sender also pick up the team avatar.
* Improved: human-handoff chat is now near real-time — the widget polls every ~1.2 seconds while the conversation is live (backing off when idle or still waiting for an agent), the agent inbox polls every 1.5 seconds, and hidden browser tabs pause polling and catch up instantly on return.

= 1.29.0 =
* New: message avatars in the chat widget — every AI reply shows a small avatar on its left (your custom widget avatar, or a built-in bot mark in your accent color). When a teammate takes over via human handoff, their real WordPress profile picture and display name appear on their messages, and the status notice says "Connected with {name}" — visitors always know whether they're talking to the AI or a person.
* Agent identity is remembered in the conversation history, so restored transcripts keep showing who said what.
* Toggle under Design → Chat Widget ("Message avatars", on by default); included in settings export.

= 1.28.0 =
* Fixed: on Content Sync, switching a type to "Only items I pick" was a dead end — "0 items picked" with no visible way to pick. It now opens an inline picker immediately (searchable, paginated list with sync-status chips; ticks save instantly), and every picked-mode type shows a "Choose items" button.
* Improved: Knowledge Base entries list now has real visual hierarchy — bold title with muted entry id, one-line content excerpt beneath, colored source badges, and a green "N answers" usage chip (dash when unused).
* Improved: source names in the "Your sources" table are links that drill straight into that source's filtered entries.

= 1.27.0 =
* New: the Knowledge Base "Add & Sources" view is now a source-groups table — one row per connected source (each WordPress content type with synced counts and scope, crawled websites, documents, hand-written entries) with sync badges (Auto / Scheduled / Manual) and direct actions.
* New: "+ Add Knowledge" opens a focused two-step modal — choose a source type, then see only that source's options, with a Back button. Esc or clicking outside closes it; "add this question" links open it straight on Q&A.
* The "Choose items" action jumps directly into a type's per-item picker inside the modal.

= 1.26.0 =
* New: Knowledge Base page redesigned into three clean views — "Add & Sources" (a grouped source picker: Your WordPress site / External websites / Documents / Written by you, plus a connected-sources overview), "Entries" (the searchable chunk table with per-source stats) and "Tools" (overlap detection, retrieval testing) — navigated from the left rail instead of one long scroll.
* New: pick individual pages, posts and products right on the Knowledge Base page — each content type expands into a searchable, paginated item list with live sync-status chips; switch between "All items" and "Only items I pick" per type. Fully shared with the Content Sync page's selection.
* Improved: deep links behave — entry filters/search land on Entries, "add this question" links land on Add & Sources with Q&A prefilled.

= 1.25.0 =
* New: Per-URL control for Website Crawl — exclude any crawled URL (per-row or in bulk): its content is removed from the knowledge base immediately and every future crawl, manual or scheduled, skips it. Re-include anytime.
* New: status filter (Indexed / Pending / Failed / Blocked / Excluded) and bulk selection in the crawled-URLs list; excluded URLs stay visible with an "Excluded" badge.
* Fixed: "Remove" on a crawled URL now sticks — previously the next crawl re-discovered and re-embedded the removed page at full cost. Remove now also excludes the URL (re-includable anytime).

= 1.24.0 =
* New: Selective content sync — each content type can now be "All items" or "Only items I pick". Pick individual pages, posts, products or CPT items from the Content Sync list (per-row Include/Exclude, bulk actions, "Picked"/"Not picked" chips and filters).
* The selection is honored everywhere: manual sync, cost estimate, "sync only not-synced", automatic sync on save, and the nightly freshness check — a de-selected item is cleanly removed on the next sync instead of silently coming back.
* Explicitly syncing an item from the list automatically adds it to your picks; "Remove" also un-picks it, so an edit to the post no longer resurrects removed content (fixes a long-standing auto-sync loophole).
* The Knowledge page's quick "WordPress Content" panel respects the per-item picks and says so when they're active.

= 1.23.0 =
* New: Getting-started checklist on the Dashboard — six state-aware steps from "connect your provider" to "first conversation", dismissible.
* New: System Health screen — API keys, embeddings, database tables, scheduled tasks (WP-Cron), streaming endpoint reachability, PHP environment and recent provider failovers, each with a fix-it link.
* New: Help & Docs screen — how the plugin fits together, shortcode reference ([ai_chatbot], [ai_chatbot_inline], the Gutenberg block), integration URLs and a plain-language glossary.
* New: Conversations export to CSV.
* New: Optional "Powered by" footer credit in the widget with custom text/link (off by default) — agencies can credit themselves on client sites.
* New: "Send test email" buttons for lead and handoff notification addresses.
* Improved: guidance everywhere — plain-language explanations replace jargon across Settings, warnings when handoff has no alert channel or a fallback provider has no key, cost confirmation before "Re-embed All", billing note and skip-warning in the setup wizard, and helpful empty states with next-step buttons on every Inbox screen.
* Improved: charts no longer rely on a CDN (Chart.js is bundled) and show friendly empty states.
* Fixed: two settings could be silently reset on every save (lead form "Name" field and handoff "Name" collection — disabled checkboxes posted no/zero values).
* Fixed: Leads CSV export and lead deletion broke after the v1.22 shell redesign (headers sent after output).
* Fixed: Website Crawl claimed a crawl continues with the tab closed — it pauses and resumes instead; copy now says so.

= 1.22.0 =
* New: Redesigned admin navigation — the sidebar is now just Dashboard, Inbox, Knowledge, Design and Settings, with a persistent in-page navigation rail listing every screen (grouped, with pending-count pills).
* New: Dedicated Design page collecting everything visual — widget name, welcome message, home screen, themes, colors, launcher, avatar and live preview.
* New: Dashboard landing page (analytics overview) when opening ChatFlint.
* Improved: Settings tabs moved into the left navigation rail; #tab deep links still work and every tab shows the Save button.
* Fixed: hidden admin pages (including the Setup Wizard) were inaccessible on current WordPress ("Sorry, you are not allowed to access this page").
* Note: all existing page URLs are unchanged — bookmarks, email deep links and integrations keep working.

= 1.21.0 =
* New: Multi-provider support — Google Gemini, DeepSeek, Grok (xAI) and OpenRouter alongside OpenAI/Anthropic, with live model lists, per-provider keys and configurable failover.
* New: Guided Knowledge Base "Add Knowledge" workflow (WordPress content, URL, sitemap, files, Q&A pairs, text) with per-source overview.
* New: Widget appearance controls — theme presets, colors with auto-contrast, corner radius, launcher size, text scale, header subtitle and avatar, with live admin preview.
* New: Modernized widget and admin design; smooth animations with reduced-motion support; screen-reader announcements for replies.
* Improved: Widget is served minified (~45% smaller); Analytics queries indexed and time-bounded; answer cache invalidates across all providers/models.
* Many fixes from a full production review (streaming, caching, provider integration, settings persistence).

= 1.12.0 =
* Chat attachments, uninstall cleanup, inline chat embed, analytics insights, conversation tags & notes, provider failover, answer cache, spam protection, translation readiness.

== Upgrade Notice ==

= 1.57.0 =
Adds the 7-day free trial (our AI, no key needed to start) — find it in the setup wizard and under Settings. Existing configured sites are unaffected.

= 1.56.0 =
Answer quality improves on every site with no action needed: the bot now reads more of your knowledge base per question, stops over-weighting words you did not ask about, and uses page addresses as a search signal. Also fixes leads and conversations occasionally duplicating or vanishing between pages of the admin lists.

= 1.54.0 =
Shops: run one content sync with Products ticked after updating — the shopping assistant (product cards, comparisons, add to cart) needs the new product facts. It is on by default once products are indexed; turn it off or tune it under Design → Widgets → Shopping Assistant.

= 1.53.0 =
Adds the built-in update channel — this is the last version you install by hand; later releases arrive on the Plugins screen. Pick an Answer voice under Settings → Behavior if your replies mix "I", "we" and the owner's name. Non-English WooCommerce shops re-index their products once on the next sync.

= 1.52.0 =
Stability release from a full code review — recommended for every site. After updating, run one content sync (and crawl, if used): synced pages re-index once under the improved extractor and pick up contact links; unchanged text reuses its stored embeddings, so the cost is small. API keys are no longer shown on the settings screens (leave the field blank to keep the saved key).

= 1.50.0 =
Contact details that only existed inside links (WhatsApp, email, phone, booking) are now indexed. Run one sync or crawl to pick them up.

= 1.43.0 =
Multilingual (WPML/Polylang) sites: run a content sync after updating so existing knowledge gets tagged with its language — language-aware answers activate automatically once it finishes.

= 1.41.0 =
Recommended for all sites: fixes silent message loss in live handoff and duplicate question saves, plus adds owner alerts when the AI provider fails. After updating from 1.36 or earlier, the first content sync re-indexes your knowledge base once under the improved extractor (normal embedding cost applies).

= 1.21.0 =
Major update: new AI providers, redesigned Knowledge Base and themeable widget. Settings migrate automatically; no action required.
