@relvehq/agent-ready 0.0.0-stage → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +364 -3
  3. package/SETUP.md +354 -0
  4. package/dist/bin/agent-ready.d.ts +23 -0
  5. package/dist/bin/agent-ready.js +444 -0
  6. package/dist/cli/init.d.ts +70 -0
  7. package/dist/cli/init.js +366 -0
  8. package/dist/core/accept.d.ts +8 -0
  9. package/dist/core/accept.js +76 -0
  10. package/dist/core/config.d.ts +145 -0
  11. package/dist/core/config.js +103 -0
  12. package/dist/core/convert.d.ts +22 -0
  13. package/dist/core/convert.js +334 -0
  14. package/dist/core/detect.d.ts +30 -0
  15. package/dist/core/detect.js +82 -0
  16. package/dist/core/easy.d.ts +19 -0
  17. package/dist/core/easy.js +117 -0
  18. package/dist/core/enrich.d.ts +30 -0
  19. package/dist/core/enrich.js +155 -0
  20. package/dist/core/llms.d.ts +11 -0
  21. package/dist/core/llms.js +71 -0
  22. package/dist/core/report.d.ts +15 -0
  23. package/dist/core/report.js +46 -0
  24. package/dist/core/resolve.d.ts +43 -0
  25. package/dist/core/resolve.js +204 -0
  26. package/dist/core/respond.d.ts +18 -0
  27. package/dist/core/respond.js +59 -0
  28. package/dist/core/sitemap.d.ts +31 -0
  29. package/dist/core/sitemap.js +140 -0
  30. package/dist/index.d.ts +14 -0
  31. package/dist/index.js +76 -0
  32. package/dist/next/dashboard.d.ts +14 -0
  33. package/dist/next/dashboard.js +56 -0
  34. package/dist/next/index.d.ts +42 -0
  35. package/dist/next/index.js +100 -0
  36. package/dist/next/route.d.ts +26 -0
  37. package/dist/next/route.js +167 -0
  38. package/dist/node/index.d.ts +8 -0
  39. package/dist/node/index.js +191 -0
  40. package/dist/proof/audit.d.ts +47 -0
  41. package/dist/proof/audit.js +253 -0
  42. package/dist/proof/bots.d.ts +24 -0
  43. package/dist/proof/bots.js +60 -0
  44. package/dist/proof/dashboard.d.ts +8 -0
  45. package/dist/proof/dashboard.js +77 -0
  46. package/dist/proof/hits.d.ts +18 -0
  47. package/dist/proof/hits.js +51 -0
  48. package/dist/proof/jsonl.d.ts +5 -0
  49. package/dist/proof/jsonl.js +80 -0
  50. package/dist/proof/stats.d.ts +39 -0
  51. package/dist/proof/stats.js +127 -0
  52. package/dist/refine/check.d.ts +17 -0
  53. package/dist/refine/check.js +134 -0
  54. package/dist/refine/extract.d.ts +7 -0
  55. package/dist/refine/extract.js +120 -0
  56. package/dist/refine/file-store.d.ts +6 -0
  57. package/dist/refine/file-store.js +87 -0
  58. package/dist/refine/model.d.ts +30 -0
  59. package/dist/refine/model.js +105 -0
  60. package/dist/refine/prompts.d.ts +49 -0
  61. package/dist/refine/prompts.js +178 -0
  62. package/dist/refine/refine.d.ts +38 -0
  63. package/dist/refine/refine.js +75 -0
  64. package/dist/refine/remote.d.ts +57 -0
  65. package/dist/refine/remote.js +238 -0
  66. package/dist/refine/run.d.ts +52 -0
  67. package/dist/refine/run.js +66 -0
  68. package/dist/refine/types.d.ts +17 -0
  69. package/dist/refine/types.js +8 -0
  70. package/dist/wp/relve-agent-ready/includes/class-relve-ar-admin.php +550 -0
  71. package/dist/wp/relve-agent-ready/includes/class-relve-ar-converter.php +762 -0
  72. package/dist/wp/relve-agent-ready/includes/class-relve-ar-llms.php +192 -0
  73. package/dist/wp/relve-agent-ready/includes/class-relve-ar-markdown-builder.php +455 -0
  74. package/dist/wp/relve-agent-ready/includes/class-relve-ar-negotiation.php +334 -0
  75. package/dist/wp/relve-agent-ready/includes/class-relve-ar-refiner.php +894 -0
  76. package/dist/wp/relve-agent-ready/includes/class-relve-ar-response.php +226 -0
  77. package/dist/wp/relve-agent-ready/includes/class-relve-ar-router.php +421 -0
  78. package/dist/wp/relve-agent-ready/includes/class-relve-ar-settings.php +201 -0
  79. package/dist/wp/relve-agent-ready/includes/class-relve-ar-store.php +583 -0
  80. package/dist/wp/relve-agent-ready/includes/index.php +2 -0
  81. package/dist/wp/relve-agent-ready/index.php +2 -0
  82. package/dist/wp/relve-agent-ready/readme.txt +108 -0
  83. package/dist/wp/relve-agent-ready/relve-agent-ready.php +81 -0
  84. package/dist/wp/relve-agent-ready/uninstall.php +35 -0
  85. package/package.json +64 -6
package/SETUP.md ADDED
@@ -0,0 +1,354 @@
1
+ # Setting up @relvehq/agent-ready
2
+
3
+ A step-by-step guide for the developer who adds this package to a site. The onboarding page with the same steps, the WordPress plugin download and a test block: https://relvehq.com/agent-ready
4
+
5
+ ## The one command
6
+
7
+ In your project's root:
8
+
9
+ ```
10
+ npx @relvehq/agent-ready init
11
+ ```
12
+
13
+ It detects Next.js, Node servers and WordPress, and sets up the one it finds:
14
+
15
+ | It finds | It does |
16
+ |---|---|
17
+ | `app/` or `src/app/` and `next` in `package.json` | Writes the Next.js files (Path 1), or prints the two lines to add to your middleware (Path 2). |
18
+ | `wp-config.php` or `wp-content/` | Copies the Relve Agent Ready plugin, bundled in the package, to `wp-content/plugins/relve-agent-ready/`. Then activate it and tick Enabled (Path 5). A copy that is already there is kept unless you add `--force`. |
19
+ | `express`, `connect`, `polka`, `fastify`, `@nestjs/core`, `h3` or `nitropack` in `package.json` | Writes nothing. Prints the exact lines for that framework and the env vars (Path 3). |
20
+ | None of these | Prints what it looked for and the onboarding URL, and exits with code 1. |
21
+
22
+ `--stack next`, `--stack node` or `--stack wordpress` skips detection. `--dry-run` prints the plan and writes nothing. The paths below are the same steps by hand, in detail.
23
+
24
+ ## What this does
25
+
26
+ - When an AI agent (ChatGPT, Claude, Perplexity and others) asks for a page as Markdown, your site answers with a small, clean Markdown version of that page.
27
+ - It also serves `/llms.txt`, a list of your pages built from your `sitemap.xml`.
28
+ - No AI runs on your server. It is plain code that answers in milliseconds.
29
+
30
+ What it does not change:
31
+
32
+ - Browsers get exactly the same HTML as before.
33
+ - Google and other search engines keep indexing your HTML pages. Markdown responses carry `X-Robots-Tag: noindex`.
34
+ - Your URLs, sitemap and robots.txt stay as they are.
35
+
36
+ ## Before you start
37
+
38
+ Paths 1 to 4 need Node.js 20 or newer. Path 5 (WordPress) needs no Node at all (Node only makes the install one command). Find your stack:
39
+
40
+ | Your site | What you do |
41
+ |---|---|
42
+ | Next.js 13.4+ with the App Router | Path 1 or Path 2. One command sets it up. |
43
+ | Any Node server (Express, Connect, Polka, Fastify, plain `http`) | Path 3. One middleware line. |
44
+ | Another runtime that uses `Request` / `Response` | Path 4. Use the core. |
45
+ | WordPress (self-hosted) | Path 5. Supported through the Relve Agent Ready plugin. No code. |
46
+ | WordPress.com | Path 5, only on plans that allow uploading plugins. |
47
+ | Webflow, Wix, Squarespace, Framer or another no-code builder | Not supported. These hosts do not let you run your own server code. |
48
+
49
+ ## Score your site first
50
+
51
+ Run the free checker. It only reads your site; it changes nothing.
52
+
53
+ ```
54
+ npx @relvehq/agent-ready check https://your-site.com
55
+ ```
56
+
57
+ It scores the site out of 100 and says what to fix. Save the result so you can compare after setup. Once the package is installed in your project, the short form works too:
58
+
59
+ ```
60
+ npx agent-ready check https://your-site.com
61
+ ```
62
+
63
+ (Do not run `npx agent-ready` before installing: that would look for a different, unscoped package.)
64
+
65
+ ## Path 1: Next.js, no middleware yet
66
+
67
+ ```
68
+ npm install @relvehq/agent-ready
69
+ npx agent-ready init
70
+ ```
71
+
72
+ `init` writes these files. It never edits a file you already have. Use `npx agent-ready init --dry-run` to see the plan first.
73
+
74
+ | File | What it holds |
75
+ |---|---|
76
+ | `agent-ready.config.ts` | `export default createAgentReady({})` with the defaults |
77
+ | `middleware.ts` | sends Markdown requests to the route below; everything else carries on |
78
+ | `app/%5F%5Fmd/[[...path]]/route.ts` | the internal route that builds the Markdown (`%5F` is `_`) |
79
+ | `.env.local` | `AGENT_READY_ENABLED=1` and `NEXT_PUBLIC_SITE_URL=http://localhost:3000` |
80
+
81
+ With a `src/` folder, the files go under `src/`. Without `tsconfig.json`, they are `.js`. Commit all of them except `.env.local`.
82
+
83
+ ## Path 2: Next.js with an existing middleware
84
+
85
+ Run the same two commands as Path 1. `init` sees your middleware, leaves it alone, and prints what to add:
86
+
87
+ ```ts
88
+ // 1. Wrap your middleware:
89
+ import { withAgentReady } from "@relvehq/agent-ready/next";
90
+ import agentReady from "./agent-ready.config";
91
+ export default withAgentReady(agentReady, yourMiddleware); // instead of exporting yourMiddleware
92
+
93
+ // 2. Add these two entries to your matcher:
94
+ // "/((?!_next/).+\\.md)", "/llms.txt"
95
+ ```
96
+
97
+ Notes:
98
+
99
+ - `yourMiddleware` is your current middleware function. Remove its old `export default` (or `export function middleware`).
100
+ - Markdown requests never reach your middleware. All other requests reach it unchanged.
101
+ - If your matcher skips paths that contain a dot, the `.md` entry is what lets `/pricing.md` through. Keep both new entries as plain strings in `export const config = { matcher: [...] }`. Next.js reads the matcher at build time, so it cannot be imported from a variable.
102
+
103
+ ## Path 3: Node server (Express, Connect, Polka, plain http)
104
+
105
+ `npx @relvehq/agent-ready init` prints these lines for your framework (it writes no file). By hand:
106
+
107
+ ```
108
+ npm install @relvehq/agent-ready
109
+ ```
110
+
111
+ ```ts
112
+ import express from "express";
113
+ import { createAgentReady } from "@relvehq/agent-ready";
114
+ import { agentReadyNode } from "@relvehq/agent-ready/node";
115
+
116
+ const app = express();
117
+
118
+ // Mount it first: before static files, routes and any HTML rendering.
119
+ app.use(agentReadyNode(createAgentReady({ site: "https://your-site.com" })));
120
+
121
+ app.use(express.static("public"));
122
+ // ...your routes
123
+ ```
124
+
125
+ - A request that does not want Markdown goes straight to `next()`. Your app answers it as before.
126
+ - `createAgentReady` still reads `AGENT_READY_ENABLED`. Set it to `1` (see "Go live") or pass `enabled: true`.
127
+ - Connect and Polka: the same `app.use(...)` line.
128
+ - Plain `http`: call the middleware first in your handler, with your own handler as `next`.
129
+ - Fastify: register `@fastify/middie`, then the same line:
130
+
131
+ ```ts
132
+ await app.register(import("@fastify/middie"));
133
+ app.use(agentReadyNode(createAgentReady({ site: "https://your-site.com" })));
134
+ ```
135
+
136
+ - NestJS: the same `app.use(...)` line in `main.ts`, after `NestFactory.create(...)` and before `app.listen(...)`.
137
+ - Nitro and h3: wrap it with `fromNodeMiddleware` from `h3`. In Nitro, as `server/middleware/agent-ready.ts`:
138
+
139
+ ```ts
140
+ import { fromNodeMiddleware } from "h3";
141
+ import { createAgentReady } from "@relvehq/agent-ready";
142
+ import { agentReadyNode } from "@relvehq/agent-ready/node";
143
+
144
+ export default fromNodeMiddleware(agentReadyNode(createAgentReady({ site: process.env.SITE_URL })));
145
+ ```
146
+
147
+ ## Path 4: anything else
148
+
149
+ The core works with Web `Request` and `Response`, so it fits any framework built on them (Hono, Bun, Deno and similar). The step that builds Markdown from your HTML needs Node APIs. See "Other frameworks" in the README for the short snippet that wires it.
150
+
151
+ ## Path 5: WordPress
152
+
153
+ WordPress runs PHP, so the site does not run this npm package. It runs a plugin instead, **Relve Agent Ready**, which answers the same requests with the same headers, and builds the Markdown from WordPress's own data (title, author, dates, categories, tags, the post content). No code to write.
154
+
155
+ Get the plugin one of two ways:
156
+
157
+ - **With Node, on the server or in your local copy of the site:** run `npx @relvehq/agent-ready init` in the WordPress root (the folder with `wp-config.php`). It copies the plugin to `wp-content/plugins/relve-agent-ready/`; then skip to step 2.
158
+ - **Without Node:** download the zip from https://relvehq.com/agent-ready (or the one Relve sends you, `relve-agent-ready-<version>.zip`) and upload it in step 1.
159
+
160
+ The plugin's own tests are never part of what is installed.
161
+
162
+ 1. **Install.** In WordPress admin: Plugins, Add New, Upload Plugin. Choose the zip, then Install Now.
163
+ 2. **Activate** it. It is installed switched off: nothing changes on your site yet.
164
+ 3. **Switch it on.** Go to Settings > Agent Ready:
165
+ - Tick **Enabled**.
166
+ - **Post types**: tick the ones agents should read (posts and pages are ticked by default). The front page and category, tag and author archives are served when Posts is ticked.
167
+ - **Excluded paths**: one path prefix per line, for anything that must never be served as Markdown.
168
+ - **llms.txt**: `auto` (the default), `on` or `off`. `auto` serves `/llms.txt` unless Yoast SEO, or a real `llms.txt` file on the server, already serves one; if you use Yoast's llms.txt, leave it on `auto` or set `off`. `on` serves ours even when Yoast has one.
169
+ - Save. The status panel at the top of the page shows whether it is on and the test commands for your site.
170
+
171
+ ### Test it
172
+
173
+ Swap in a real post URL from your site:
174
+
175
+ ```
176
+ curl -i -H "Accept: text/markdown" https://your-site.com/blog/your-post/
177
+ curl -i https://your-site.com/blog/your-post.md
178
+ curl -i "https://your-site.com/blog/your-post/?format=md"
179
+ curl -i https://your-site.com/blog/llms.txt
180
+ ```
181
+
182
+ `/llms.txt` lives under the site's home path: on a blog at `your-site.com/blog`, it is `/blog/llms.txt`; on a site at the domain root, `/llms.txt`.
183
+
184
+ What you should see:
185
+
186
+ | Command | Expected |
187
+ |---|---|
188
+ | `Accept: text/markdown` | `200`, `Content-Type: text/markdown; charset=utf-8`, `x-agent-ready-source: native` (or `stored`), `Vary: Accept` |
189
+ | `.md` URL and `?format=md` | the same Markdown body |
190
+ | `llms.txt` | `200`, `Content-Type: text/plain; charset=utf-8`, links to your posts and pages |
191
+
192
+ Then open the post in a browser. It must look exactly as before.
193
+
194
+ ### If a Cloudflare Worker or a reverse proxy serves the blog on your-site.com/blog
195
+
196
+ Many sites serve WordPress at `your-site.com/blog` through a Cloudflare Worker, Nginx or another proxy in front of the WordPress server. The plugin only sees what the proxy passes on. The proxy must:
197
+
198
+ - forward the `Accept` header unchanged
199
+ - forward paths that end in `.md` (some proxies only forward known page paths or drop paths with a dot)
200
+ - forward the query string, so `?format=md` arrives
201
+ - route `/blog/llms.txt` to WordPress like any other blog path
202
+ - not cache by URL alone for requests with `Accept: text/markdown`: either pass them through uncached, or add `Accept` to the cache key. Otherwise an agent may get a cached HTML page, or a browser may get Markdown.
203
+
204
+ `?format=md` is the most robust of the three: it works through any proxy that forwards the query string.
205
+
206
+ ### Page caches (WP Rocket and similar)
207
+
208
+ The plugin tells WP Rocket not to cache `.md` and `?format=md` responses, and marks every Markdown response as not cacheable (`DONOTCACHEPAGE`). A page cache can still answer an `Accept: text/markdown` request with the HTML it already holds, because it runs before WordPress and does not look at `Accept`. That is safe, just not Markdown. `.md` URLs and `?format=md` always work.
209
+
210
+ ### Refined files on WordPress
211
+
212
+ With your own OpenAI key, the plugin can write a better Markdown file for each post itself: see the plugin's settings page (Settings > Agent Ready) and its readme. You can also upload a zip of `.md` files you made with `npx agent-ready refine` (zip the `.agent-ready/md` folder): under the refined files section, choose it and click "Upload zip" (up to 20 MB, 2 MB per file). Each upload replaces the whole stored set; "Clear refined files" removes them all. See "Add refined files" below for how to check it.
213
+
214
+ ## Test it locally
215
+
216
+ Start your dev server, then run these three commands (change the port if yours is not 3000):
217
+
218
+ ```
219
+ curl -i -H "Accept: text/markdown" http://localhost:3000/
220
+ curl -i http://localhost:3000/index.md
221
+ curl -i http://localhost:3000/llms.txt
222
+ ```
223
+
224
+ What you should see:
225
+
226
+ | Command | Expected |
227
+ |---|---|
228
+ | `Accept: text/markdown` on `/` | `200`, `Content-Type: text/markdown; charset=utf-8`, `x-agent-ready-source: convert` (or `native` / `stored`), `Vary: Accept` |
229
+ | `/index.md` | the same Markdown body |
230
+ | `/llms.txt` | `200`, `Content-Type: text/plain; charset=utf-8`, a list of your pages |
231
+
232
+ Then open `http://localhost:3000/` in a browser. It must look exactly as before.
233
+
234
+ Score the local site too:
235
+
236
+ ```
237
+ npx agent-ready check http://localhost:3000
238
+ ```
239
+
240
+ ## Go live
241
+
242
+ Set these environment variables on your host:
243
+
244
+ | Variable | Value |
245
+ |---|---|
246
+ | `AGENT_READY_ENABLED` | `1` (anything else, or unset, means off) |
247
+ | `NEXT_PUBLIC_SITE_URL` | your public origin, e.g. `https://your-site.com` |
248
+
249
+ The site URL can come from any of these, first one set wins: `NEXT_PUBLIC_SITE_URL`, `SITE_URL`, `NEXT_PUBLIC_APP_URL`, `URL` (set by Netlify), `VERCEL_PROJECT_PRODUCTION_URL`, `VERCEL_URL` (set by Vercel). Passing `site` to `createAgentReady` wins over all of them. With no site URL the package stays off and logs one warning; it never fails your build.
250
+
251
+ Where to set them:
252
+
253
+ - Vercel: Project Settings, Environment Variables, Production.
254
+ - AWS Amplify: App settings, Environment variables.
255
+ - Netlify: Site configuration, Environment variables.
256
+ - Anything else: wherever your host or container sets env vars.
257
+
258
+ Then redeploy (env vars are read at build and start time) and score the live site again:
259
+
260
+ ```
261
+ npx @relvehq/agent-ready check https://your-site.com
262
+ ```
263
+
264
+ ### Behind a CDN (CloudFront, Cloudflare, Fastly)
265
+
266
+ Most CDNs do not put `Accept` in the cache key. If the CDN already holds the HTML for a page, an `Accept: text/markdown` request may get that HTML. That is safe, just not Markdown. `.md` URLs and `/llms.txt` always work, because they are their own URLs. For reliable `Accept` negotiation, add the `Accept` header to the CDN cache key.
267
+
268
+ ## Add refined files: better Markdown with your own OpenAI key (optional)
269
+
270
+ One command writes a better Markdown file for each page ahead of time, with Relve's prompt and your own OpenAI key (BYOK).
271
+
272
+ 1. Put your key in `.env.local`, `.env` or the shell as `OPENAI_API_KEY`, then run from your project root:
273
+
274
+ ```
275
+ npx agent-ready refine --site https://your-site.com --sitemap --dry-run
276
+ npx agent-ready refine --site https://your-site.com --sitemap
277
+ ```
278
+
279
+ `--dry-run` lists the pages and calls nothing. The real run fetches each page's HTML and sends it to the Relve API on relvehq.com with your key. Relve's prompt runs on Relve's server, calls OpenAI with your key, checks the result (every number and URL must be on the page) and returns the Markdown. The files land in `.agent-ready/md`: `index.md`, `pricing.md`, each with a `.json` next to it (fingerprint, model, tokens, date).
280
+
281
+ - What it costs: your own OpenAI usage, one model call per changed page. Relve charges nothing.
282
+ - Your key: it passes through Relve's server for that call only. Relve never stores or logs it, and it is never written to the output files.
283
+ - Options: `--paths /a,/b` instead of `--sitemap`, `--model gpt-4o` (also `gpt-4.1`, `gpt-4.1-mini`; default `gpt-4o-mini`, the fastest), `--site-name "Your Brand"`, `--limit 20`, `--out <dir>`, `--force`.
284
+ - The run ends with a summary (written, unchanged, rejected, errors, tokens). Rejected or failed pages are listed with a code (for example `too_little_text`) and nothing is saved for them; they keep the plain `convert` Markdown.
285
+ - Re-run it when your content changes. Unchanged pages are skipped with no model call, so they are free. You can add the command to CI or your deploy (before the build, with `OPENAI_API_KEY` as a secret).
286
+
287
+ Advanced: your own prompts. `--prompts <dir>` (or `AGENT_READY_PROMPTS`) runs your own prompt files on your machine instead of calling the Relve API. See the package README.
288
+
289
+ 2. Commit the folder at `.agent-ready/md` in your project root (or generate it in your deploy).
290
+ 3. Tell the package to read it. The store reads files with Node, so put it where only Node code runs.
291
+
292
+ Next.js: in the route file (`app/%5F%5Fmd/[[...path]]/route.ts`), not in `agent-ready.config.ts`. The config file is also loaded by the middleware, which runs on the Edge runtime and has no file system.
293
+
294
+ ```ts
295
+ import { createMarkdownRoute } from "@relvehq/agent-ready/next/route";
296
+ import { fileStore } from "@relvehq/agent-ready/refine/file-store";
297
+ import agentReady from "../../../agent-ready.config";
298
+
299
+ export const { GET, HEAD } = createMarkdownRoute({ ...agentReady, store: fileStore(".agent-ready/md") });
300
+ export const runtime = "nodejs";
301
+ export const dynamic = "force-dynamic";
302
+ ```
303
+
304
+ On Vercel, Amplify or Netlify, make sure the folder ships with the server code. In `next.config.js` (Next.js 15+; on 13.4 and 14 put it under `experimental`):
305
+
306
+ ```js
307
+ outputFileTracingIncludes: { "/**": ["./.agent-ready/md/**/*"] },
308
+ ```
309
+
310
+ Node server (Path 3): pass it straight to `createAgentReady`:
311
+
312
+ ```ts
313
+ import { fileStore } from "@relvehq/agent-ready/refine/file-store";
314
+ app.use(agentReadyNode(createAgentReady({ site: "https://your-site.com", store: fileStore(".agent-ready/md") })));
315
+ ```
316
+
317
+ 4. Redeploy. Check a refined page:
318
+
319
+ ```
320
+ curl -i https://your-site.com/pricing.md
321
+ ```
322
+
323
+ The response should carry `x-agent-ready-source: stored`. Pages without a refined file keep working as before (`convert`).
324
+
325
+ WordPress (Path 5): no folder to commit. Use the plugin's OpenAI key setting or upload a zip (see "Refined files on WordPress"), then run the same `curl` on a refined post's `.md` URL. Pages without a refined file keep `x-agent-ready-source: native`.
326
+
327
+ ## Turn it off
328
+
329
+ Set `AGENT_READY_ENABLED=0`, or remove the variable, and redeploy. Every request then goes through as if the package were not there. Removing it fully: delete the files `init` created and the two lines in your middleware.
330
+
331
+ WordPress: untick **Enabled** on Settings > Agent Ready, or deactivate the plugin. Deleting the plugin also removes its settings and the uploaded refined files.
332
+
333
+ ## Troubleshooting
334
+
335
+ | Symptom | Likely cause | Fix |
336
+ |---|---|---|
337
+ | `Accept: text/markdown` returns HTML | The CDN served its cached HTML | Test the `.md` URL; add `Accept` to the CDN cache key |
338
+ | | The package is off | Set `AGENT_READY_ENABLED=1` and redeploy |
339
+ | | No site URL, so it stayed off | Set `NEXT_PUBLIC_SITE_URL` (look for the "no site URL" warning in your logs) |
340
+ | | The page is too short to convert (under 200 characters of text) | An `Accept` request then gets the normal HTML on purpose (`x-agent-ready-source: html-fallback`) |
341
+ | `.md` URL returns 404 | The path is excluded (`/api`, `/admin`, `/login`, `/account`, `/checkout`, `/dashboard` and similar, or your `exclude`) | Expected for private pages; otherwise check your `exclude` list |
342
+ | | The page has under 200 characters of real text | Add content, or add a template or a refined file for it |
343
+ | `.md` URL returns your site's 404 page (Next.js) | Your matcher does not include the `.md` entry | Add `"/((?!_next/).+\\.md)"` to the matcher (Path 2) |
344
+ | `/llms.txt` is empty or lists no pages | No `/sitemap.xml`, or it lists URLs on another host | Publish a sitemap at `/sitemap.xml` with your public URLs |
345
+ | Existing middleware stopped running, or Markdown never appears | The middleware is not wrapped | Export `withAgentReady(agentReady, yourMiddleware)` as the default (Path 2) |
346
+ | Build passes, nothing happens | No site URL or `AGENT_READY_ENABLED` not set on the host | Set both and redeploy; env vars added after a build need a new build |
347
+ | Node server: Markdown never appears | The middleware is mounted after static files or routes | Move `app.use(agentReadyNode(...))` above them |
348
+ | WordPress: `Accept` request returns HTML, `?format=md` works | A page cache or the proxy in front answered first | Expected with page caches; for the proxy, see "If a Cloudflare Worker or a reverse proxy serves the blog" |
349
+ | WordPress: `.md` URL returns your theme's 404 page | The proxy in front does not forward `.md` paths, or the plugin is not enabled | Test on the WordPress server's own address; fix the proxy rules; tick Enabled |
350
+ | `x-agent-ready-source` is `convert`, not `stored` | The refined folder is missing on the server, or the store is not configured | Check the folder is committed and shipped, and the route file has `store: fileStore(...)` |
351
+
352
+ ## Getting help
353
+
354
+ Contact the Relve team. Include the output of `npx @relvehq/agent-ready check https://your-site.com --json` and the response headers from one of the curl commands above.
@@ -0,0 +1,23 @@
1
+ #!/usr/bin/env node
2
+ import { type InitFs } from "../cli/init";
3
+ export declare function nodeFs(root: string): InitFs;
4
+ /**
5
+ * The WordPress plugin folder: the copy built into the package
6
+ * (dist/wp/relve-agent-ready, next to dist/bin and dist/cli), else the source
7
+ * folder when running from the repo with tsx. null when neither is there.
8
+ */
9
+ export declare function bundledPluginDir(here?: string): string | null;
10
+ /** Every file under the plugin folder, relative with forward slashes; no tests/, no dotfiles. */
11
+ export declare function listPluginFiles(dir: string): string[];
12
+ export interface RunDeps {
13
+ log?: (s: string) => void;
14
+ env?: Record<string, string | undefined>;
15
+ fetch?: typeof fetch;
16
+ }
17
+ export declare function run(argv: string[], deps?: RunDeps | ((s: string) => void)): Promise<number>;
18
+ /**
19
+ * Read `.env.local` then `.env` from the working directory, like Next.js, so
20
+ * the keys a project already has (OPENAI_API_KEY, ANTHROPIC_API_KEY) just
21
+ * work. A variable already set in the shell wins; values are never printed.
22
+ */
23
+ export declare function loadEnvFiles(cwd?: string): string[];