=== Rebilder — Agent-Readable Content ===
Contributors: rebilder
Tags: ai, agents, markdown, llms-txt, woocommerce
Requires at least: 6.0
Tested up to: 7.0
Requires PHP: 7.4
Stable tag: 0.3.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
try to read the answer out of your theme's HTML — navigation, cookie banners,
carousels, related-products carousel, 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: markdown for agents, an HTML page for people, FAQ structured data
  for both, at the same URLs. Nothing serves 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, no URL, no hostname. It schedules no cron job. That is the state every
install starts in and the state it stays in unless you decide otherwise.

If you want to see which agents are reading your site, you can paste a Rebilder
API key into Settings → Rebilder, and the plugin will start reporting the
requests described under "What is sent when you connect" below. Removing the
key stops it again, immediately and completely.

The claim is mechanical rather than rhetorical, so you can check it yourself
rather than take our word:

* **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 of this file ever stops matching the code.
Our tests go one further and run the plugin with no key configured, checking
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 and always receive
the same HTML a human receives, even if they send a markdown Accept header.
That is also how the plugin stays reachable by Microsoft Copilot, which answers
from Bing's index and sends no user agent of its own. Showing a search engine
something different from a visitor is cloaking, and this plugin is built so
that it cannot do it.

**3. Nothing is generated.** Every value in the markdown is read from WordPress
or WooCommerce. No AI model runs. No price is recalculated, rounded, or
estimated — WooCommerce's own stored value is printed as-is, with your shop's
currency, and a discount is only shown when WooCommerce says the product is on
sale.

= What is sent when you connect =

Only if you paste an API key. Before that, this section describes nothing that
happens.

**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**, and **neither is a search
results page**, whichever of the three asked for it — that 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 rather than trimmed afterwards.
Most traffic to most sites therefore produces nothing at all.

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

**What.** 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 a password-reset code can never ride along. The path is kept as it is,
  which is exactly why search results pages are dropped outright: WordPress
  writes a search as `/search/what-was-typed/` as well as `?s=what-was-typed`,
  and removing the query string only reaches one of the two;
* the `Accept` header;
* which agent it appeared to be (for example "chatgpt"), and whether it asked
  for markdown — always recorded as unverified, because this plugin parses the
  claim and does not check the signature;
* the referring **site**, as an origin like `https://chatgpt.com` and never the
  full link;
* what was served: markdown or HTML, and whether we had 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, because the whole request is
dropped. Order, cart or customer data. Your page content, your post text, your
product descriptions. Ordinary human page views.

**Nothing a visitor typed, ever.** Every field in the list above is a
timestamp, a number, or a value from a short fixed list. The URL is the only
free-form string in the record, and it is the address of a page on your own
site, kept as the requester asked for it.

**One exception, and it is deliberate.** When you press "Connect this site",
the plugin makes a single blocking request to the same address with an empty
batch, to check the key is live and tell you if it is not. Without it, one
mistyped character would leave you with a plugin that says it is connected and
a dashboard that never fills in.

**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 — it may be in use on another site — so
revoke it in the Rebilder Console if you want it dead everywhere.

= Caching =

The plugin sends `Vary: Accept` on every response, so caches keep the HTML and
the markdown apart. If you use a caching plugin or a CDN that strips or ignores
`Vary`, configure it to respect 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.

== Frequently Asked Questions ==

= Will this affect my SEO? =

No. Search engine crawlers are detected first and always 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 payload
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
does essentially nothing: it reads two request headers, decides the visitor is
human, and gets out of the way — and even when connected, a normal visitor
produces no request to us at all.

= 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 "What is sent when you connect" above 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.

== Changelog ==

= 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/`.
  Removing the query string only covers the first, and the record keeps the
  path as it is, so the whole request is dropped instead.
* 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`.
