=== Rebilder ===
Contributors: rebilder
Tags: ai, agents, markdown, llms-txt, woocommerce
Requires at least: 6.0
Tested up to: 7.1
Requires PHP: 7.4
Stable tag: 0.4.1
License: GPLv2 or later
License URI: https://www.gnu.org/licenses/gpl-2.0.html

Serves your existing posts, pages and WooCommerce products as clean markdown to AI agents that ask for it. Humans and search engines are untouched.

== Description ==

AI shopping and research agents fetch your pages the way a browser does. Then
they try to read the answer out of your theme's HTML: navigation, cookie
banners, carousels, and somewhere in there, the price.

This plugin gives them a straight answer instead. When a request for one of
your URLs arrives with `Accept: text/markdown`, it responds with that page's
content as markdown: the title, the facts, the body. Same URL. Same substance.
Different format.

There is nothing to configure. Activate it and it works.

= What it serves =

* **Posts and pages:** title, publication and update dates, author, categories
  and tags, and the body content as markdown.
* **WooCommerce products:** name, price, availability, stock, SKU, categories,
  attributes, short description and description.
* **/llms.txt:** an index of your content, so an agent that lands on your
  domain can find out what is there.
* **/answers (optional):** a Q&A directory you import from your Rebilder
  account. Agents get markdown, people get an HTML page, and both get FAQ
  structured data, at the same URLs. The plugin leaves `/answers` alone until
  you paste an export in Settings → Rebilder, and every entry stops serving
  when its freshness window lapses.

= Three promises =

**1. Nothing is sent anywhere until you connect it.** Out of the box this
plugin makes no network request at all. No ping, no usage beacon, no version
check. It schedules no cron job. Every install starts that way and stays that
way unless you decide otherwise.

If you want to see which agents are reading your site, paste a Rebilder API
key into Settings → Rebilder. The plugin then reports the requests described
under External services below. Removing the key stops it again, immediately
and completely.

You can check this yourself:

* **One file.** `includes/class-rebilder-connect.php` is the only file in this
  plugin that can make a request. Search the rest of the folder for
  `wp_remote_`, `curl_init`, `fsockopen`, `file_get_contents` or
  `wp_schedule_event` and you will find nothing.
* **One function.** Inside that file, `wp_remote_post` is the only call that
  makes a request. There is no raw socket anywhere in the plugin.
* **One address.** It is hardcoded to `https://api.rebilder.com/v1/events`,
  with no filter and no constant to override it, so no other plugin on your
  site can redirect it.

Our build reads the plugin with PHP's own tokenizer and refuses to package a
release if an outbound call appears anywhere else, if it is anything other than
`wp_remote_post`, or if this section stops matching the code. Our tests also
run the plugin with no key configured and check that zero requests are
attempted.

**2. Search engines are untouched.** Googlebot, bingbot and Microsoft's other
fetchers are identified before any other signal is examined. They always
receive the same HTML a human receives, even if they send a markdown Accept
header.

**3. Nothing is generated.** Every value in the markdown is read from WordPress
or WooCommerce. No AI model runs. Prices match your product page: the plugin
prints WooCommerce's display price with your tax display setting, price
decimals, price suffix and currency, and the full range for variable and
grouped products. A discount is only shown when WooCommerce says the product
is on sale. Stock counts follow your "Stock display format" setting.

= Caching =

The plugin sends `Vary: Accept` on every response, so caches that respect it
keep the HTML and the markdown apart. Markdown responses also tell page caches
not to store them: they set `DONOTCACHEPAGE`, send no-cache headers and send
`X-LiteSpeed-Cache-Control: no-cache`. If a CDN in front of your site ignores
all of these, configure it to vary on the `Accept` header for your pages.

= Free, and what is not free =

Everything described above is free and always will be, including the connection
to a Rebilder account. The markdown serving runs entirely on your own server
and costs us nothing, so there is nothing to meter.

Rebilder also sells a hosted service: an Agent Readability Score for your
site, a report of what agents asked for and could not find, and score history
over time. That is a separate paid product at rebilder.com. This plugin does
not require it and does not upsell inside your admin.

== Installation ==

1. Install and activate the plugin.
2. That is the whole setup for markdown serving.
3. Optional: paste a Rebilder API key in Settings → Rebilder to see agent
   traffic in your Rebilder Console. Skip this and the plugin makes no network
   request.

To check it is working, from a terminal:

`curl -H "Accept: text/markdown" https://your-site.com/your-page/`

You should get markdown. Loading the same URL in a browser is unchanged.

On a multisite network you can activate it for one site or for the whole
network.

== Frequently Asked Questions ==

= Will this affect my SEO? =

Search engine crawlers are detected first and receive your normal
HTML pages. The markdown is only ever served to requests that identify as AI
agents or explicitly ask for `text/markdown`.

= Does it work with page builders? =

Yes. The plugin renders the content WordPress renders. It applies the same
`the_content` filter your theme does, so blocks, shortcodes and builder output
are all included.

= Does it store anything or slow my site down? =

It adds no database tables and stores at most two options: the answers export
you paste in, and the API key you paste in, each only if you use that feature.
Both are deleted on uninstall. Serving stores nothing. For a normal visitor it
reads two request headers, decides the visitor is human, and gets out of the
way. Even when connected, a normal visitor produces no request to us at all.

= I already have a page at /answers. =

The plugin only uses `/answers` after you import answers. Settings → Rebilder
names any published page at that address, so you can change its slug before
you import. Clearing the import gives the address back to your page.

= What happens when I deactivate or uninstall it? =

`/llms.txt` and `/answers` stop answering from the next request. On a network,
deactivating for the network does this on every site. Uninstalling also
deletes the answers import and the API key from every site that has them.

= Is my content sent anywhere? =

No. Your posts, pages, products and their text are never sent anywhere by this
plugin, connected or not. If you connect it, what leaves is a short record of
who asked for which URL. See External services for the exact field list.

= Can I use it without any Rebilder account? =

Yes, and that is the default. The markdown serving, `/llms.txt` and everything
else described above work with no account, no key and no network access.

== Screenshots ==

1. Settings → Rebilder: connect reporting to your Rebilder Console and import approved answers.
2. A product page requested as markdown, with price, availability and stock read from WooCommerce.
3. The /answers page people see, built from the same imported answers agents read as markdown.

== External services ==

This plugin can connect to Rebilder, a service that shows you which AI agents,
search crawlers and AI-referred visitors requested your pages, and what they
asked for and could not find. The connection is off until you paste a Rebilder
API key in Settings → Rebilder. Until you connect it, the plugin makes no
network request.

**Where it sends.** `https://api.rebilder.com/v1/events`, from one file
(`includes/class-rebilder-connect.php`) using one function (`wp_remote_post`).

**When.** At most one small record per page load, and only for three kinds of
request: an AI agent, a search crawler, or a person an AI assistant referred
(a visitor arriving from ChatGPT, Perplexity, Claude, Gemini and similar).
Ordinary human page views are never reported. Neither is a search results
page, whoever asked for it. A search page is the one address on a WordPress
site that can contain something a visitor typed, so the whole request is
dropped before a record is built.

**How.** After your page has been delivered to the visitor, never while one is
being rendered. The request is non-blocking with a two-second timeout, and its
reply is ignored. If our servers are slow or down, your site does not notice.

**What is sent.** Exactly these fields:

* the time of the request;
* the URL that was requested, with the query string removed except for
  `page`, `variant`, `sku`, `lang`, `locale` and `currency`, so a login token
  or password-reset parameters are excluded. The path is kept as it is, which
  is why search results pages are dropped outright: WordPress writes a search
  as `/search/what-was-typed/` as well as `?s=what-was-typed`;
* the `Accept` header;
* which agent it appeared to be (for example "chatgpt"), and whether it asked
  for markdown. This is always recorded as unverified, because the plugin
  reads the claim and does not check a signature;
* the referring site, as an origin like `https://chatgpt.com`, never the full
  link;
* what was served: markdown or HTML, and whether there was anything to answer
  with;
* how many milliseconds the page took to render.

**What is never sent.** IP addresses. Cookies or session data. Usernames,
emails, or anything about a logged-in user. Form contents. Search terms, in
either of the two ways WordPress writes them. Order, cart or customer data.
Your page content, post text or product descriptions. Ordinary human page
views.

**URL handling.** The record keeps the page path and the listed query
parameters. Keep personal or secret information out of those parts of your
URLs.

**Checking the key.** When you press "Connect this site", the plugin makes one
request to the same address with an empty batch, to check the key is live and
tell you if it is not.

**Turning it off.** Settings → Rebilder → Disconnect. The key is deleted and
the plugin goes back to sending nothing. Uninstalling deletes it too.
Disconnecting does not revoke the key, because it may be in use on another
site. Revoke it in the Rebilder Console to turn it off everywhere.

The service is provided by Rebilder LLC.
Terms of service: https://rebilder.com/legal/terms
Privacy policy: https://rebilder.com/legal/privacy

== Changelog ==

= 0.4.1 =
* Recognizes more AI agents: Meta, Amazonbot, DuckAssistBot, MistralAI-User; Applebot as a crawler.

= 0.4.0 =
* Product prices match the product page: your tax display setting, price decimals and price suffix, and the full range for variable and grouped products.
* Stock counts follow your WooCommerce "Stock display format" setting.
* Markdown responses tell page caches not to store them.
* `/answers` is only used after you import answers. Settings → Rebilder warns when a published page already uses that address.
* Deactivating now removes `/llms.txt` and `/answers`. Activation, deactivation and uninstall cover every site in a multisite network.
* The settings screen and the /answers page for people can be translated.
* Declares compatibility with WooCommerce order storage (HPOS).
* The plugin is now listed as "Rebilder".

= 0.3.2 =
* Preserve supporting facts and comparison tables when importing Answers Hub entries.
* Label publisher expertise in HTML, markdown and FAQ data.
* Support answers about industry topics, category choices and alternatives.

= 0.3.1 =
* Clearer setup steps, scoped admin styling and corrected answer-import guidance.

= 0.3.0 =
* Optional connection to your Rebilder Console: paste an API key in Settings →
  Rebilder and the plugin reports agent, crawler and AI-referred requests so
  you can see what agents asked for, and what they asked for and could not
  find. **Off by default.** With no key configured the plugin makes no network
  request, exactly as before.
* One file, one function, one address:
  `includes/class-rebilder-connect.php`, `wp_remote_post`, and
  `https://api.rebilder.com/v1/events`. Nothing is sent while a page is being
  rendered, and ordinary human page views are never reported.
* Search results pages are never reported either, in either of the two ways
  WordPress writes them: `?s=what-was-typed` and `/search/what-was-typed/`.
* Settings → Rebilder answers is now Settings → Rebilder, with the answers
  import unchanged underneath. Existing imports are unaffected.
* An agent that asks for markdown on a page we have none for is now recorded as
  a miss rather than ignored, which is what makes the Agent Miss Report work.

= 0.2.0 =
* Answers hub: paste your approved Q&A export from Rebilder into Settings →
  Rebilder answers and it serves at /answers: markdown for agents, HTML for
  people, FAQ structured data for both. No network request is added: import
  is a paste.

= 0.1.0 =
* First release: markdown serving for posts, pages and WooCommerce products,
  plus `/llms.txt`.

== Upgrade Notice ==

= 0.4.1 =
Recognizes more AI agents, including Meta, Amazonbot, DuckAssistBot and MistralAI-User. Applebot now gets your normal pages, like other search crawlers.

= 0.4.0 =
Product prices now match your product page, including tax display and price ranges. Markdown skips page caches, and deactivating removes /llms.txt and /answers.
