=== KAL-AI – Learning Mentor (LearnDash) | Content Expert (content sites) ===
Contributors: meirk
Tags: learndash, chatbot, ai, lms, mentor
Requires at least: 5.9
Tested up to: 7.1
Stable tag: 2.43.26
Requires PHP: 7.4
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Give every LearnDash student a personal AI mentor in minutes. Then turn the rest of your library into a cited Content Expert.

== Description ==

**Your students are stuck. Your course already has the answer.** Kal AI puts a **Learning Mentor** on every LearnDash course — it answers from *your* lessons and jumps to the exact second in the video.

Install it now. The Quick Start wizard does the heavy lifting.

https://www.youtube.com/watch?v=-TIbZ4-yN-M

**Click Install. You'll be live on a course before your coffee cools.**

= 1. LearnDash Quick Start — the reason to install today =

One guided wizard. No code. No copy-pasting 200 lesson URLs.

1. Activate Kal AI and create a **free** account in the plugin (20 import hours, 30 days, no credit card)
2. Open **LearnDash Setup**
3. Click **Detect** — we find your video fields on Lessons and Topics
4. Pick the course, turn on **auto-embed**, run bulk setup
5. Refresh the course. The mentor is on the page.

Students can ask a question and get a cited answer with a **timestamp into the lesson video**. The mentor remembers who they are, tracks tasks, and keeps them moving.

Works with **YouTube, Vimeo, Google Drive, and Bunny Stream** (including Presto Player embeds).

**See the Learning Mentor the student actually gets:**

https://www.youtube.com/watch?v=yTrAc444JaE

**Connect Vimeo, Google Drive, and Bunny Stream:**

https://www.youtube.com/watch?v=J8Wc6B-VTeo

= What the Learning Mentor does for your school =

* Answers only from **your** approved course content — not random web results
* Cites the lesson and opens the **exact moment** in the video
* Builds a course path with tasks you can edit
* Remembers the learner and their progress
* Auto-embeds on the course (or `[kalai_chat]` on any page)
* **Admins-only preview** so you can test on the live course before students see it
* **Advertiser mode** for logged-out visitors: a teaser answer + enroll CTA, while enrolled students get the full mentor
* Syncs lesson text to WordPress: polished transcript, summary, and FAQ via `[kal_seo]`

= 2. Content Expert — for the rest of your WordPress site =

Not teaching a LearnDash course? Use **Content Expert** mode.

Import articles, PDFs, DOC/DOCX, YouTube, Vimeo, Drive files, Bunny videos, and audio. Visitors ask. They get **cited answers from your library**.

* Any post type, custom fields, or **body-content auto-detect** (finds the video/file in the post)
* Multiple bots — one for the academy, one for the blog, one for a campaign
* Brand the widget (colors, avatar, theme, greeting)
* Lock it to your domain
* Optional: logged-in users only, or WooCommerce Subscriptions unlock
* Conversations dashboard: see what people asked, which bot answered, which source it used

= Go live in four steps =

1. Click **Download** on this page (or search "Kal AI" under Plugins → Add New)
2. Activate and create your free Kal AI account in the wizard
3. Run **LearnDash Setup** — or connect a Content Expert source
4. Auto-embed. You're done.

**Free to start. No credit card.** 20 import hours for 30 days.

= Also included =

* Integrations page for Vimeo, Google Drive, and Bunny Stream
* Accurate import-time estimates (video duration / document word count)
* Select-all-matching across every results page
* Domain restriction, logged-in-only, and admins-only deploy options
* Shortcodes: `[kalai_chat]`, `[kalai_seo]` / `[kal_seo]` (transcript, summary, FAQ)

This plugin requires a free [Kal AI](https://kal-ai.com) account. By using it you agree to the [Kal AI Terms of Service](https://kal-ai.com/terms) and [Privacy Policy](https://kal-ai.com/privacy).

== Installation ==

**From this directory (fastest):**

1. Click **Download** (or in wp-admin: **Plugins → Add New →** search **Kal AI**)
2. Install and **Activate**
3. Go to **Kal AI → Dashboard → Get Started**
4. Create a free account (or paste your API key)
5. If you run LearnDash: open **LearnDash Setup** and run Quick Start
6. If you don't: connect a Content Expert source and deploy the widget

**Via ZIP / FTP:**

1. Upload the `kal-ai` folder to `/wp-content/plugins/`
2. Activate the plugin
3. Go to **Kal AI → Dashboard** and follow the wizard

== Frequently Asked Questions ==

= I run LearnDash. How fast can I go live? =
Watch the Quick Start video above, then open **Kal AI → LearnDash Setup**. Detect your video fields, pick a course, enable auto-embed, run it. Most sites are live on the first course in minutes.

= Do I need LearnDash? =
No. LearnDash is the fastest path. Without it, use **Content Expert** — articles, videos, PDFs, Google Drive, Bunny Stream — and embed with `[kalai_chat]` or auto-embed.

= Do I need a Kal AI account? =
Yes. Create one inside the plugin wizard. No credit card. New accounts get **20 import hours for 30 days**.

= Where is my API key? =
**Kal AI → Settings**, or in your Kal AI account under **Settings → API Key**.

= What video hosts work with LearnDash Quick Start? =
YouTube (native), plus **Vimeo, Google Drive, and Bunny Stream** after you connect them on the Integrations page. Bunny also detects Presto Player blocks.

= What is Advertiser mode? =
Logged-out visitors get a teaser and a sign-up CTA. Enrolled LearnDash students (or WooCommerce subscribers) get the full mentor. Use it to turn course browsers into enrollments.

= Can I test before students see it? =
Yes. Turn on **Admins only (preview)** in Deploy or in the LearnDash wizard. Only WordPress admins see the widget until you switch it off.

= What content can Content Expert import? =
Any WordPress post type, YouTube, Vimeo, Bunny Stream, Google Drive, PDF/DOC/DOCX (and PPT/XLS links), and MP3. Use a custom field or let **Body Content** auto-detect the file/video in the post.

= How do I put the chat on a page? =
Auto-embed on all pages or specific LearnDash courses, or paste `[kalai_chat]` on any page. Lesson text (transcript / summary / FAQ) is `[kal_seo]`.

= How does billing work? =
You start with 20 free import hours (30 days). Hours are used when content is processed. Buy more on the Billing page. Plans lower the per-hour rate.

= Is my content sent to Kal AI? =
Yes — only to process it, and only when you import or when a visitor chats. We do **not** keep your videos, PDFs, or original files.

When you import, Kal AI transcribes and indexes the source. **After import, we store captions, a text index, and a RAG index — that's all.** Those are what the chatbot searches so it can answer with citations. The raw media is discarded after processing.

When a visitor chats, their question is sent so the bot can search those indexes and reply. You can lock each bot to your domain. See the [Privacy Policy](https://kal-ai.com/privacy) and [External services](https://wordpress.org/plugins/kal-ai-chatbot/#description).

= Does this support WordPress Multisite? =
No. Single-site only.

= Which PHP version? =
PHP 7.4 or higher. PHP 8.0+ recommended.

== Screenshots ==

1. LearnDash Bulk Setup Wizard — detect video fields, pick a course, auto-embed the mentor
2. Bot Knowledge — choose which sources power each bot
3. Connect a source — LearnDash, YouTube, Vimeo, Drive, Bunny, articles, documents
4. Design — colors, avatar, theme, and floating widget label
5. Deploy — auto-embed, shortcode, domain lock, logged-in / admins-only
6. Sources — every library with item count, hours used, and connected bots
7. Conversations — what students asked, which bot answered, when

== Privacy Policy ==

Kal AI connects to the Kal AI cloud service hosted at [https://kal-ai.com](https://kal-ai.com) and [https://api.kal-ai.com](https://api.kal-ai.com).

**Data sent to Kal AI servers includes:**

* Content you choose to import (titles, lesson/body text, video URLs, documents) so we can transcribe and index it
* After processing, we store **captions**, a **text index**, and a **RAG index** — that's all. Not the original video or file.
* Visitor chat messages, so the bot can search those indexes and reply
* An anonymised WordPress user identifier and a short-lived HMAC token so the chat widget can load a visitor's conversation history (logged-in users only)
* Your API key, used to authenticate all requests

No data is sent without a deliberate action by the site administrator (importing content) or by a visitor interacting with the deployed chat widget.

== External services ==

This plugin connects to the following external services:

**Kal AI API** — The core service this plugin is built on. Used for all AI processing, bot management, content import, and chat widget delivery. Data transmitted: content you import (we store captions, a text index, and a RAG index; original files are not kept), visitor chat messages, WP user identifiers (HMAC-signed, for logged-in users). [Kal AI Terms of Service](https://kal-ai.com/terms) | [Kal AI Privacy Policy](https://kal-ai.com/privacy).

**Vimeo oEmbed API** (`https://vimeo.com/api/oembed.json`) — Used only when an admin imports Vimeo videos. The plugin sends the Vimeo video URL to retrieve metadata (title, duration). No visitor data is transmitted to Vimeo. [Vimeo Terms of Service](https://vimeo.com/terms) | [Vimeo Privacy Policy](https://vimeo.com/privacy).

**SUMIT (OfficeGuy) Payments** (`https://app.sumit.co.il`) — A payment processing service used on the plugin Billing admin page to handle subscription and import-hour purchases. The SUMIT payment script loads when a payment form is displayed. Payment data is submitted directly to SUMIT and is never stored on your server. [SUMIT Terms of Service](https://help.sumit.co.il/he/articles/10340800) | [SUMIT Privacy Policy](https://app.sumit.co.il/privacy).

== Upgrade Notice ==

= 2.43.26 =
Learning Mentor mode now creates one lesson per linked item, not the full LearnDash course.

= 2.43.25 =
Renamed to KAL-AI – Learning Mentor (LearnDash) | Content Expert (content sites).

= 2.43.24 =
FAQ privacy links are now clickable.

= 2.43.23 =
Privacy FAQ wording: we store captions, a text index, and a RAG index.

= 2.43.22 =
Clearer privacy FAQ: we store captions and AI/RAG indexes after import, not original files.

= 2.43.21 =
Renamed to KAL-AI – AI Learning Mentor | Content Expert.

= 2.43.20 =
Renamed to KAL-AI - AI Learning Mentor & Content Expert.

= 2.43.19 =
LearnDash Quick Start videos and listing copy. Update recommended.

= 2.43.18 =
* Updated the WordPress.org banner and short description for Content Expert and Learning Mentor

= 2.43.17 =

= 2.23.48 =
Restores live bot preview, fixes import progress, LearnDash detect, billing/import page styling, and PHP 7.x compatibility. Recommended for all users.

== Changelog ==

= 2.43.26 =
* Learning Mentor mode creates one lesson per linked source item. The full LearnDash outline is only used by Import / Rebuild from LearnDash and the bulk wizard.

= 2.43.25 =
* Renamed the plugin to KAL-AI – Learning Mentor (LearnDash) | Content Expert (content sites)

= 2.43.24 =
* FAQ: Privacy Policy and External services are now clickable links

= 2.43.23 =
* Privacy FAQ: after import we store captions, a text index, and a RAG index

= 2.43.22 =
* Clarified the privacy FAQ: after import we keep captions and AI/RAG indexes, not original videos or files

= 2.43.21 =
* Renamed the plugin to KAL-AI – AI Learning Mentor | Content Expert

= 2.43.20 =
* Renamed the plugin to KAL-AI - AI Learning Mentor & Content Expert

= 2.43.19 =
* WordPress.org listing: LearnDash Quick Start first, Content Expert second, plus setup / integrations / mentor videos

= 2.43.18 =
* Updated WordPress.org listing banner and short description (Content Expert + Learning Mentor)

= 2.43.17 =
* First WordPress.org directory release
* Admin live preview now opens in a new tab (directory guideline)
* Scripts and styles loaded only via wp_enqueue_* / wp_add_inline_script
* Declared compatibility with WordPress 7.1

= 2.43.16 =
* Added `[kal_seo type="all"]` lesson pack (overview, long summary, FAQ, gated transcript) with print support.
* LearnDash setup now uses lesson-level Drive/Bunny durations when the course-level total is missing.
* Detect always includes known video URL fields (`youtube_url`, `vimeo_url`, `bunny_url`, `gdrive_url`) on large sites.

= 2.43.15 =
* LearnDash Bulk Setup matches the Kal AI app: Lessons and Topics are always imported together (no post-type picker). Detect now finds video fields on both, including `youtube_url` on topics.

= 2.43.14 =
* Fixed: LearnDash setup wizard JS failed to load (missing brace), which hid the "not integrated" warning and broke the Detect button.

= 2.43.13 =
* Fixed: expanding a course showed "duration unknown" on every lesson even when the course already had a total duration. Empty lesson-duration results are no longer cached, and opening a course fetches times again.

= 2.43.12 =
* Fixed: large LearnDash courses were marked "blocked / private" when the duration API timed out. Durations are now fetched in batches, a failed fetch stays on calculating and retries, and it is not treated as private videos.

= 2.43.11 =
* Fixed: LearnDash bulk setup was marking most courses "blocked / duration unknown" right after update because a fast lesson-list call with empty durations was treated as private videos. Rows stay on calculating until the real duration scan finishes.

= 2.43.10 =
* Fixed: LearnDash bulk setup now uses lesson durations as soon as they load, instead of staying on "calculating duration…" until the slower course-level scan finishes.

= 2.43.9 =
* Fixed: LearnDash bulk setup no longer lets you select or import a course while duration is still calculating. Hours are charged by duration, so the checkbox stays locked until duration is known.

= 2.43.8 =
* Fixed: LearnDash bulk setup no longer marks a course "blocked / duration unknown" until the lesson list has actually been checked. The first course-level scan often misses durations even when videos are fine.

= 2.43.7 =
* Updated: new accounts created from the plugin now get 20 free import hours, valid for 30 days (was 3 hours with no time limit)

= 2.43.6 =
* Added: Deploy option to show the chat widget only to logged-in WordPress users.

= 2.43.2 =
* Clarified lesson-text sync: "Sync entire source" updates every matching post. Check videos and use "Sync selected only" for a partial sync.

= 2.43.1 =
* Added: "Sync lesson text" is now on each source row (Sources list) and the button is highlighted on the source videos page.

= 2.43.0 =
* Added: lesson-text shortcodes and WordPress custom fields for Kal AI summaries, FAQ, and polished transcripts. `[kal_seo]` defaults to the polished transcript. Also `[kal_seo type="summary_short"]`, `summary_long`, `faq`. Sync from Sources → Sync lesson text, or from the Kal AI app.

= 2.42.1 =
* Fixed: deleting a LearnDash bulk-setup bot left the course locked as "Imported" in the wizard, so it could not be set up again. The course is now selectable after the bot is gone, leftover sources are reused instead of duplicated, and deleting a LearnDash bot also removes its dedicated source.

= 2.40.0 =
* Added: "Select All N Matching" button on the import screen — selects every post that matches the current filters across ALL result pages, not just the 25 visible ones. Pages are scanned in the background and video durations / document & article word counts are loaded along the way, so the "This import needs Xh Ym" estimate reflects the full selection for every channel type (YouTube, Vimeo, direct video, Bunny, Google Drive, audio, documents, blog articles). Click the button again to stop the scan (already-selected posts stay selected)
* The old "Select All" button (current page only) was renamed to "Select Page" for clarity

= 2.39.0 =
* Fixed: ".doc" (legacy Word extension) linked files always showed "n/a" for Content Length and would have failed the same way during a real import — many ".doc" links actually serve modern Word XML content under the old extension, so they're now read the same way ".docx" already was (matches how real document imports have always handled ".doc")
* Fixed: the post body text (used to estimate word count for Blog Article imports and for the document "also include body text" option) was missing entirely when your site is proxied through this plugin's fast post-listing endpoint, causing every blog post to show "length n/a" in the app's import dialog. The post's body text is now included in that response

= 2.38.0 =
* Fixed: the "Content Length" column on the document import screen could get stuck on "⏳ Measuring…" forever for posts where no file link was actually found in the body (the "Ready to import (link exists)" filter didn't apply to "Body Content" sources, so those posts stayed listed with nothing to measure). Such rows now immediately show "— no file" instead of spinning
* Fixed: "Ready to import (link exists)" now actually filters out posts with no detected link for "Body Content" video/audio/document sources — previously it only worked for custom-field/taxonomy sources
* Hardened the document word-count request with a longer timeout and a client-side cap so it always resolves even if the server is briefly slow

= 2.37.0 =
* Added: document imports now show an accurate "This import needs Xh Ym" time estimate. Each selected post's linked file (PDF/DOCX/TXT) is extracted server-side to count its exact billable words, and a new "Content Length" column shows the measured length per post. When "Also include the post's body text" is enabled, the body words are added to the estimate too. Matches how document imports are actually billed (words ÷ 7,800 per hour)

= 2.36.0 =
* Fixed: the import screen wrongly showed "Settings required before importing (missing custom field name for the video/audio URL)" and blocked importing for any "Body Content (auto-detect)" source — video, audio, or document. Body Content sources scan the post body and legitimately have no custom field name, so they are no longer gated by that check

= 2.35.0 =
* Fixed: a critical bug where clicking "Start Import" (not just previewing posts) for any "Body Content" source — video, audio, or document — always silently imported 0 items. The real import form read the wrong POST field name for the source type, so it always fell back to "Custom Field" and looked up an empty field name
* Added: "File Types to Detect" checkboxes for document sources — restrict a channel to only PDF, only Word (DOC/DOCX), only PowerPoint, only Excel, or any combination, instead of always matching every supported document format
* Fixed: creating a new WordPress document channel with "Body Content" selected as the URL source incorrectly required a field name to be filled in, blocking channel creation

= 2.34.0 =
* Added: Document sources ("Documents (PDF, DOC, DOCX)" — previously labeled "PDF Documents") now support "Body Content (auto-detect linked file)" as a URL source, matching the existing option for video sources — auto-detects a linked PDF/DOC/DOCX/PPT/XLS file directly in a post's body instead of requiring a custom field
* Added: "Also include the post's body text" checkbox for document sources — prepends each post's own blog text above the extracted document text, useful for posts that are both a real written article and a link to a source-sheet/handout
* Renamed "PDF Documents" to "Documents (PDF, DOC, DOCX)" throughout the admin UI to reflect that DOC/DOCX (and PPT/XLS) files were already supported, not just PDFs

= 2.33.1 =
* Fixed: saving an Auto-Embed mode (e.g. "All pages") in the wp-admin Deploy panel appeared not to save — the form wrote only a legacy site-wide option instead of the bot itself, so the page re-rendered the bot's unchanged mode. The panel now saves the mode directly to the bot (same source of truth as the app)
* Added: "Exclude specific pages" textarea in the wp-admin Deploy panel under "All pages" (matching the app) — rules can be a page/post ID, a URL ending with * to exclude a folder, or a URL keyword
* Fixed: cache-busting after a save used a wrong transient prefix, so on Redis/Memcached hosts admin pages could show stale settings for up to 60 seconds after saving

= 2.33.0 =
* Fixed: switching a bot's WordPress Auto-Embed mode to "Off" in the app could leave the widget showing on the live site (or vice-versa) until the client happened to resave the legacy "Auto-Embed" panel here in wp-admin. An explicit "Off" is now correctly treated as configured, so it can no longer be silently overridden by that legacy site-wide fallback
* Sped up how quickly Deploy setting changes made in the app reach the live site — bots list cache TTL reduced from 2 minutes to 30 seconds
* Added: "Exclude specific pages" for the "All pages" Auto-Embed mode. Each rule can be a WordPress page/post ID, a URL wildcard prefix to exclude a whole folder (e.g. `example.com/course/*`), or a plain keyword matched anywhere in the URL (e.g. `course`)

= 2.31.1 =
* Fixed: the AJAX proxy's custom-field (`meta_keys`) lookup only ran for single-post `include=` requests, never for the normal paginated bulk sync used by "Sync Now" — so custom-field-based taxonomy filters and the new "subscribers only" field always came back empty/false during a real sync, even though a single-post preview fetch worked fine

= 2.31.0 =
* Advertiser Mode: added a "subscribers only" WordPress custom-field gate as an alternative to LearnDash course enrollment. Sites with no LearnDash can mark individual posts as restricted (e.g. via a custom field like `for_subscribers`) and non-subscribers see the existing preview + subscribe CTA for just those videos
* Signs an active WooCommerce Subscription flag (when the WooCommerce Subscriptions plugin is active) alongside the existing LearnDash enrollment claim, so non-LearnDash sites can unlock gated content for active subscribers too

= 2.30.1 =
* Fixed Bunny Stream "Body Content" scanning: the Presto Player reusable-block reference regex required the video-block JSON to immediately follow the block name (`wp:presto-player/reusable-edit{"id":473}`) with no space, but real Gutenberg markup always has a space (`wp:presto-player/reusable-edit {"id":473}`) — so it never actually matched and every lesson/topic using Presto Player was reported as having no video

= 2.30.0 =
* Bunny Stream "Body Content" scanning now resolves Presto Player reusable video blocks (`[presto_player id="..."]` / `wp:presto-player/reusable-edit`) — sites that embed Bunny videos in LearnDash lessons/topics via Presto Player (instead of a raw iframe or pasted GUID) are now detected correctly
* Also match bare Bunny CDN pull-zone URLs (`*.b-cdn.net/{guid}/...`) in body content, not just `iframe.mediadelivery.net` / `player.mediadelivery.net` embeds
* Body Content preview counts (post list / lesson list) now show detected embeds for Bunny Stream, matching Vimeo/YouTube/Direct Video

= 2.29.0 =
* Added full Bunny Stream support to the LearnDash Bulk Setup wizard (course preview, lesson list, and import) — a library picker now appears when Bunny Stream is chosen as the video source, matching Vimeo/YouTube/Google Drive, and it now also works from the native admin bulk-import page (previously only the regular WordPress source settings)
* LearnDash Bulk Setup fetches real Bunny durations for the hours estimate and creates the course channel with the right Bunny library linked
* Fixed the "Connect Bunny Library" form in Integrations sending mismatched field names, which silently failed to save the connection
* Lesson videos imported via LearnDash are now auto-linked to their WordPress post so future re-imports/rebuilds can match them without re-scanning content

= 2.28.0 =
* Added a Bunny Stream card to the Integrations page (connect/disconnect a video library with a Library ID + read-only API key), matching Vimeo and Google Drive so the "Go to Integrations" link from the Bunny Stream source type now works
* Bunny Stream now shows a "not integrated" warning on the source type dropdowns (Channels, edit source) like Vimeo and Google Drive

= 2.27.0 =
* Added "Admins only (preview)" — a per-bot toggle (Deploy panel and LearnDash Bulk Setup) that only shows the chat widget to logged-in WP admins, so you can verify a bot on the live course page before rolling it out to students

= 2.26.0 =
* Advertiser Mode: the widget now signs the current user's enrolled LearnDash course IDs (wp_courses) alongside the existing WP identity token, so Kal AI can tell enrolled students apart from guests when a bot has Advertiser Mode enabled (gated video preview + subscribe CTA)

= 2.25.1 =
* Fixed Bunny Stream sources on the Import page never resolving durations (stuck on "Loading…"): the Bunny custom field name was not applied when selecting the source, so video GUIDs could not be read from posts
* Posts without an extractable Bunny GUID are now marked "No duration" immediately instead of loading forever

= 2.25.0 =
* Fixed Bunny Stream Videos import: durations now load and count toward the hours estimate on the native Import page (was missing from the video-type list and had no duration fetcher)
* Fixed server-to-plugin proxy calls (posts, posts-with-cf, taxonomies, taxonomy terms, etc.) failing with "Invalid API key" for Kal AI admin-managed clients — the correct site API key is now resolved and sent on every request
* Fixed admin-ajax proxy fallback using the wrong action names, causing it to always fail with HTTP 400 instead of falling back correctly when REST is blocked

= 2.24.0 =
* Added Bunny Stream Videos as a Source Type — link a Bunny Stream library, point at a custom field or taxonomy holding the video GUID/URL, and import for AI transcription + chat

= 2.23.52 =
* Fixed bot widget on course pages: inline config block (collectionId) was being stripped when converting embed code to WP-safe script tags

= 2.23.48 =
* Fixed import progress bar never updating (stale JS global reference)
* Restored live inline bot preview on Design, Settings, and Knowledge tabs
* Fixed blank/unstyled Import and Billing pages (asset loading + PHP 7.x compatibility)
* Fixed LearnDash "Detect" button hanging on large sites (batched query)
* Fixed integrations page stuck on "Checking..." (added request timeout)
* Fixed saving bot settings wiping linked knowledge sources
* Fixed chat widget not appearing on course pages (embed host validation)
* Consolidated admin JavaScript into a single file
* Corrected "Tested up to" WordPress version

= 2.23.46 =
* Published to WordPress.org plugin directory
* Security hardening: replaced REST API user elevation with direct WP_Query
* All inline scripts converted to wp_add_inline_script
* Full prefix rename to kalai_ for WordPress.org compliance
* Updated shortcode to [kalai_chat]

= 2.23.42 =
* Split Design & Deploy into separate Design and Deploy tabs (continued refinement)
* Declared Multisite incompatibility
* Security: one account can now only be connected to one WordPress site
* Removed custom auto-updater (plugin now hosted on WordPress.org)
* Added Privacy Policy disclosure in readme

= 2.23.36 =
* Split Design & Deploy into separate Design and Deploy tabs
* Added Sources → Bots column showing which bots use each source
* Renamed "Channel" to "Source" throughout the interface
* Added integration status indicators to Source Type dropdown
* Domain restriction refactored to a simple checkbox (auto-detects WordPress domain)
* Removed redundant Collection Display Name and Collection Icon fields
* Bot Settings: added default Welcome Message placeholder
* Billing: fixed Enterprise plan not showing Buy Import Hours form
* Removed Public Access and Active checkboxes from Bot Settings (superseded by Domain Restriction)
* Sidebar icon updated
* Billing: fixed import hours not deducting correctly for video, article and document imports
* Billing: import cost preview banner now shows accurate estimate for article/post imports (word count ÷ 7800)
* Security: one account can now only be connected to one WordPress site
* QA: declared Multisite incompatibility; fixed printf escaping; added Network: false header

= 2.0.0 =
* LearnDash Bulk Setup Wizard with course/lesson selection
* Auto-embed per bot and per course
* Balance preview in LearnDash wizard (Bank Balance, Cost, Remaining)
* Per-bot floating widget customization
* Live preview in Design tab
* Conversations dashboard
* Enterprise plan support

= 1.0.0 =
* Initial release
* Content import (articles, YouTube, Vimeo)
* Bot management
* Chat widget deployment (shortcode + auto-embed)
* Billing & hours management
