=== AI Visibility Engine by Alli AI ===
Contributors: alliai
Tags: seo, ai, llm, bot detection, visibility
Requires at least: 6.0
Tested up to: 6.9
Stable tag: 1.0.3
Requires PHP: 7.2
License: GPL-2.0-or-later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Makes your site visible to AI — serves optimised pages to bots and exposes LLM-friendly endpoints via the Alli AI Engine.

== Description ==

Alli AI for WordPress proxies eligible requests to the Alli AI Engine directly from within WordPress, emulating the behavior of a Cloudflare Workers integration without requiring any DNS changes.

**How it works:**

The plugin installs an `advanced-cache.php` drop-in that intercepts requests before WordPress loads. Eligible requests (bot traffic, `.md` endpoints, `/llms.txt`, `/llms-full.txt`) are forwarded to the Alli AI Engine; everything else passes through to normal WordPress rendering.

**Key features:**

* Early request interception via `advanced-cache.php` (before WordPress loads)
* Bot and LLM crawler detection and proxying
* `.md` suffix support — `/about.md` returns a markdown version of any page
* `Accept: text/markdown` header negotiation
* `/llms.txt` and `/llms-full.txt` endpoints always proxied to the engine
* Safe fallback — any proxy error falls through to native WordPress rendering
* Cache purge hooks on post publish, unpublish, and delete
* Fully translated into 38 languages (Arabic, Bulgarian, Catalan, Croatian, Czech, Danish, Dutch, Estonian, Basque, Finnish, French, Galician, German, Greek, Hindi, Hungarian, Icelandic, Indonesian, Italian, Japanese, Korean, Latvian, Lithuanian, Norwegian, Polish, Portuguese (Brazil), Portuguese (Portugal), Romanian, Russian, Serbian, Slovak, Slovenian, Spanish, Swedish, Turkish, Ukrainian, Vietnamese, Chinese Simplified)

**Two operation modes:**

* **Advanced** — installs `advanced-cache.php`; intercepts bot and LLM requests before WordPress loads (lowest overhead)
* **Template Redirect** — intercepts after WordPress loads; always available, works on managed hosts and alongside other cache plugins

This plugin requires an active Alli AI account and API token. See the External services section below for full disclosure.

== Installation ==

1. Upload the `alli-ai` folder to `/wp-content/plugins/`
2. Activate the plugin through the **Plugins** menu in WordPress
3. Go to **Settings → Alli AI** and enter your API token
4. Verify the **Config Status** indicator shows a green checkmark

== Frequently Asked Questions ==

= Does this plugin work alongside other caching plugins? =

Yes. When another plugin owns `advanced-cache.php` (e.g. W3 Total Cache, WP Super Cache, LiteSpeed Cache), Alli AI automatically switches to Template Redirect mode. All proxying happens via `template_redirect`; other caching plugins are not affected.

= What happens if the Alli AI Engine is unreachable? =

The plugin always falls back to normal WordPress rendering on any proxy failure — timeout, DNS error, or 5xx response. Your site will never be broken by a network issue.

= Is my API token secure? =

The token is never output in HTML or JavaScript. It is stored in WordPress options and in a hash-named PHP file in `wp-content/cache/`, protected by `.htaccess`. The token is sent to the Alli AI Engine over HTTPS only.

= My server runs Nginx — is there anything I need to do? =

On Nginx, `.htaccess` files have no effect. You should add a server-level rule to deny direct web access to the `wp-content/cache/` directory. The plugin will show an admin notice if it detects Nginx and the cache directory is present.

= How do I purge the Alli AI cache? =

The cache is purged automatically when you publish, update, unpublish, or delete a post. You can also purge manually from **Settings → Alli AI → Purge All Cache**.

= Something isn't working — how do I get debug information? =

Enable **Debug Logging** on the Settings page. The plugin will write a structured log to `wp-content/uploads/alli-ai/alli-debug.log` (errors and warnings are always logged; informational events require debug mode on). When the log has entries a **Download log** button appears at the bottom of the settings page — click it to save the file and send it to Alli AI support. The log contains only diagnostic information (error messages, plugin version, PHP version, WordPress version, and timestamps). It never contains API tokens, verification keys, visitor IP addresses, cookies, or any other personal or sensitive data.

== Development ==

= Building a release ZIP =

The plugin ZIP is built from the git tree, so only committed files are included. Dev files (tests, Makefile, CI config, etc.) are excluded via `.gitattributes`.

**Automated — GitHub Actions (recommended)**

Push a version tag to trigger the release workflow:

  git tag v0.0.3
  git push origin v0.0.3

GitHub Actions will build the ZIP and publish a GitHub Release with the changelog entry from `CHANGELOG.md`.

You can also trigger it manually: **Actions → Release → Run workflow**.

**Manual build**

  make build

Output: `dist/alli-ai-<version>.zip`

Or without `make`:

  git archive --format=zip --prefix=alli-ai/ HEAD > alli-ai.zip

The `--prefix=alli-ai/` flag ensures the ZIP unpacks into a folder named `alli-ai/`, which WordPress requires to match the plugin slug.

Note: `git archive` reads `.gitattributes` from the committed tree. Commit `.gitattributes` first or the exclusions won't take effect.

= Releasing a new version =

1. Update `Version:` in `alli-ai.php`
2. Update `Stable tag:` in `readme.txt`
3. Add an entry to `CHANGELOG.md` under `## [x.x.x] - YYYY-MM-DD`
4. Commit, then tag: `git tag vX.X.X && git push origin vX.X.X`

== External services ==

This plugin communicates with three external services operated by Alli AI. Services 1 and 2 require an active Alli AI account with a valid API token.

The list of known AI crawler User-agents used for bot detection is bundled directly with the plugin and updated with each release. No external requests are made to fetch or refresh this list at runtime.

**1. Alli AI Engine — `https://engine.alliaiapp.com/`**

Used for: forwarding eligible HTTP requests (AI bot traffic, `.md` endpoints, `/llms.txt`, `/llms-full.txt`) to the Alli AI Engine so it can serve optimised responses.

Data sent on each proxied request:
* The original HTTP request headers (User-Agent, Accept, etc.)
* The request path and query string
* Your site's hostname
* Your API token (in the `Alli-Token` header)

When: on every request that the plugin identifies as eligible for proxying (AI crawlers, LLM-friendly endpoints). Regular visitor traffic is never proxied.

**2. Alli AI Proxy API — `https://proxy.alliaiapp.com/`**

Used for: plugin registration and periodic health checks.

Data sent:
* Your API token (in the `Alli-Token` header)
* Your site's hostname (in the `Alli-Host` header)
* A Unix millisecond timestamp
* Plugin platform identifier (`wp`)
* Plugin version number (e.g. `1.0.3`)

When:
* On every activation and plugin enable — registers this WordPress installation with the Alli AI service.
* Hourly (health ping) — verifies engine connectivity and syncs widget/markdown configuration. After 5 consecutive failures the plugin disables itself automatically.

**3. Alli AI Widget CDN — `https://static.alliai.com/`**

Used for: loading optional frontend scripts (widget and markdown reader) on your site's public pages when these features are enabled in the Alli AI dashboard.

Scripts that may be loaded:
* `https://static.alliai.com/widget/md.js` — markdown reader UI (only when markdown mode is set to `visible` or `shortcut`)
* A widget script URL provided by the Alli AI dashboard (only when a widget is configured; URL is validated to belong to `*.alliai.com` before injection)

Data sent: standard browser request headers (no personal visitor data is explicitly collected by the plugin).

When: on every public page load, only if the respective feature is enabled in the Alli AI dashboard. No scripts are injected when features are disabled.

**Privacy policy and terms of service:**

* Privacy policy: https://www.alliai.com/privacy
* Terms of service: https://www.alliai.com/terms

No personal visitor data (IP addresses, cookies, or session identifiers) is included in requests to any of the above services by the plugin itself.

== Screenshots ==

1. Settings page — API token, operation mode, debug options.
2. Admin notice showing the active operation mode.

== Changelog ==

= 1.0.3 =
* Dynamic LLM crawler detection — signatures fetched from the ai-robots-txt community list (24 h cache, 1 h retry on failure).
* Built-in fallback list expanded: Bytespider, CCBot, Diffbot added alongside existing signatures.
* AlliAI_Detector constructor accepts remote signatures merged on top of built-in defaults.
* Dropin config file now stores LLM signatures so advanced-cache.php benefits without WordPress loaded.
* Refactored PHPUnit bot/LLM tests to use @dataProvider.

= 1.0.2 =
* AlliAI crawler UA bypass — engine crawls origin directly to build optimised content.
* Verification key preserved in DB on disable/deactivate; file restored on re-activation.
* UI sections no longer lock after disable (gated by key-in-DB, not file-on-disk).
* Dropin fully passive in Template Redirect mode.
* Bots always proxied regardless of edge mode setting.
* Fixed: verification key no longer wiped on intentional plugin disable.
* Fixed: llms.txt / llms-full.txt deleted from disk when option is toggled off.
* Fixed: duplicate admin notices for dropin conflict removed.
* Fixed: legacy option `alli_ai_registered` cleaned up on uninstall.

= 1.0.1 =
* Widget and markdown script injection with domain validation (*.alliai.com only).
* Config sync cron every 10 minutes — pulls widget/markdown settings automatically.
* Inbound sync message support — instant config refresh on dashboard change.
* LLMs file retry reduced to 5 minutes; sync interval reduced to 1 hour.
* Install request now always sent on activation when token is configured.
* External services documentation expanded to include widget CDN.

= 0.0.2 =
* Live engine status polling with indicator dot.
* Generate LLMs files immediately on plugin enable.
* Paused state shown when plugin is disabled.
* Fixed WP Cron 24-hour interval drift.
* Fixed advanced-cache.php path resolution for non-standard plugin directories.

= 0.0.1 =
* Initial release.

== Upgrade Notice ==

= 1.0.3 =
LLM crawler list now updated automatically from the ai-robots-txt community source. Built-in fallback covers Bytespider, CCBot, and Diffbot.

= 1.0.2 =
Verification key now survives disable/deactivation — no need to re-enter it on re-activation. AlliAI crawler bypass added.

= 1.0.1 =
New widget injection feature with domain validation. Config sync now runs automatically every 10 minutes.

= 0.0.2 =
Bug fixes and UX improvements.

= 0.0.1 =
Initial release.
