Skip to content

feat(docs): add agent playbook and plain-text Markdown mirrors - #57

Merged
olamide226 merged 2 commits into
mainfrom
docs/agent-readable-markdown
Sep 11, 2026
Merged

feat(docs): add agent playbook and plain-text Markdown mirrors#57
olamide226 merged 2 commits into
mainfrom
docs/agent-readable-markdown

Conversation

@olamide226

Copy link
Copy Markdown
Collaborator

Makes the documentation site ingestible by AI agents, and fixes the 404 every docs path returned when suffixed with .md.

Plain-text Markdown mirrors

Every page now has a mirror at the same path with a .md suffix — /reference/sdk.md, /concepts/wire-format.md, and so on (46 pages, plus /index.md for the landing page).

docs/src/lib/to-markdown.ts converts MDX to clean Markdown rather than serving raw source, so agents don't have to parse JSX:

Source Output
import … from '@astrojs/starlight/components' dropped
<Aside type="caution"> > **Caution** blockquote
<TabItem label="Docker"> / <Card title="…"> bold label, body dedented to the wrapper's indent
<LinkCard title href description /> - [title](href) — description
<Tabs> / <Steps> / <FileTree> unwrapped; bodies are already valid Markdown

The transform is code-fence aware, so the pages that document JSX (<RepScript />, Next.js layouts, component examples) pass through untouched. Verified across all 46 files: no leftover component tags, no stray imports, even code-fence parity everywhere.

Entry points for agents

  • /agents.md — a single-page integration playbook. Decision tree for choosing gateway mode, dev tooling and client API; tier classification rules; install matrix across all npm packages, the Docker image and the raw binary; five copy-paste recipes (SPA migration, Docker embedded, Docker proxy, Kubernetes sidecar, local dev); the client API with the behavioural contracts that change how code is written against it (get() is synchronous, the first getSecure() decrypts everything, SSE connects lazily); gateway flag/env/endpoint tables; ten failure modes; and a verification checklist. It also renders as a normal docs page and appears in the sidebar.
  • /llms.txt — indexed by sidebar section with descriptions, linking to the .md URLs.
  • /llms-full.txt — the complete documentation set as one file (~187 KB).

Content-type handling

Cloudflare Pages serves .md as text/markdown, which browsers download rather than render. A _headers override fixes that, but the wildcard form wasn't safe to assume: Cloudflare documents a splat as greedily matching all characters and doesn't document a /*.md suffix pattern as supported.

docs/src/integrations/md-headers.mjs therefore enumerates the rules explicitly from the real build output — 49 rules against a 100-rule limit, with a build warning if that is ever approached. public/_headers is generated rather than hand-maintained, so it can't drift from the routes.

Supporting changes

  • The sidebar moves out of astro.config.mjs into docs/src/sidebar.mjs, shared by Starlight and the /llms.txt route so the index can't drift from the nav.
  • A Starlight Head override adds <link rel="alternate" type="text/markdown"> to each page, making mirrors discoverable from the HTML without guessing the convention.
  • SITE_URL consolidated into docs/src/site.mjs.
  • README gains a "For AI agents" section and header links.
  • Syncs the stale published copy of rep-manifest.schema.json (copy-schemas.mjs output that had drifted from schema/).

Verification

  • pnpm build succeeds; all 48 mirrors plus both llms files generated.
  • pnpm check — 0 errors, 0 warnings, 0 hints.
  • Dev server serves /reference/sdk.md, /llms.txt and /agents.md with content-type: text/plain; charset=utf-8.
  • Content in agents.md cross-checked against source: gateway env var names against gateway/internal/config/config.go, the Kubernetes sidecar against deployment/kubernetes.mdx, CLI flags and the rep bin name against cli/package.json.

Make the documentation ingestible by AI agents.

Every page now has a plain-text Markdown mirror at the same path with a
`.md` suffix — previously a 404. `src/lib/to-markdown.ts` converts MDX to
clean Markdown rather than serving raw source: imports are dropped,
`<Aside>` becomes a blockquote, `<TabItem>`/`<Card>` become bold labels
with dedented bodies, `<LinkCard>` becomes a list item, and
`<Tabs>`/`<Steps>`/`<FileTree>` are unwrapped. The transform is
code-fence aware so pages documenting JSX pass through untouched.

Adds three entry points for agents:

- `/agents.md` — a single-page integration playbook: decision tree,
  install matrix, recipes for SPA migration, Docker (both modes),
  Kubernetes and local dev, the client API with its behavioural
  contracts, gateway reference, and common failure modes.
- `/llms.txt` — indexed by sidebar section, linking to `.md` URLs.
- `/llms-full.txt` — the full documentation set as one file.

Cloudflare Pages serves `.md` as `text/markdown`, which browsers
download instead of render. Pages splat patterns match greedily and a
`/*.md` suffix pattern is not documented as supported, so
`src/integrations/md-headers.mjs` enumerates the rules explicitly from
the build output (49 of a 100-rule limit, with a warning if that is
approached). `public/_headers` is now generated rather than maintained
by hand.

The sidebar moves to `src/sidebar.mjs` so Starlight and the `/llms.txt`
route share one ordering, and a Starlight `Head` override advertises
each page's mirror via `<link rel="alternate" type="text/markdown">`.

Also syncs the stale published copy of the manifest JSON schema.
@olamide226 olamide226 closed this Sep 11, 2026
@olamide226 olamide226 reopened this Sep 11, 2026
@greptile-apps

greptile-apps Bot commented Sep 11, 2026

Copy link
Copy Markdown

Greptile Summary

Summary

  • The Kubernetes hot-reload example correctly describes the mounted .env reload source, but its update command modifies a separate ConfigMap key instead of that file.
  • As written, operators following the command retain the prior feature-flag value after the gateway reloads.

Confidence Score: 5/5

The documented update command should be corrected, but this is a non-blocking documentation defect.

The remaining issue is limited to the Kubernetes documentation: the example patch creates a second ConfigMap entry while the configured gateway continues reading the unchanged .env entry. greptile-apps[bot] resolved the previously reported Kubernetes reload recipe without explanation; the current documentation now uses a mounted env-format file and passes it through --env-file, which addresses that issue.

Files Needing Attention: docs/src/content/docs/deployment/kubernetes.mdx

T-Rex T-Rex Logs

What T-Rex did

  • T-Rex produced finding-comment-proofs for two posted P2 findings.
  • T-Rex ran a general-contract-validation-proof to validate the patch against the ConfigMap and envfile semantics, and performed the work locally due to the lack of a Kubernetes client or cluster access.
  • T-Rex captured and organized artifacts from the validation run to support reviewer inspection.

View all artifacts

T-Rex Ran code and verified through T-Rex

Comments Outside Diff (2)

  1. docs/src/content/docs/deployment/kubernetes.mdx, line 163-164 (link)

    P2 Patch updates wrong key

    The documented ConfigMap stores all reloadable values in its single .env key, and the gateway reloads only /config/.env. This patch instead adds a separate REP_PUBLIC_FEATURE_FLAGS key, so Kubernetes mounts a new /config/REP_PUBLIC_FEATURE_FLAGS file while /config/.env retains its old value. The documented update appears to reload successfully but does not deliver the requested feature-flag value to connected clients.

    Artifacts

    Evidence from the check

    • Authored Python harness that applies the documented patch to the documented ConfigMap shape and parses only `/config/.env`, establishing the tested path.

    Command output from the check

    • Executed baseline command shows the sole `.env` key mounts as `/config/.env` and yields `REP_PUBLIC_FEATURE_FLAGS=dark-mode`, establishing the comparison point.

    Command output from the check

    • Executed patched command shows a new ConfigMap key and separate mounted file while `/config/.env` remains unchanged and the gateway still reads `dark-mode`, confirming no requested feature-flag reload.

    View artifacts

    T-Rex Ran code and verified through T-Rex

  2. General comment

    P2 Hot-reload patch updates a new ConfigMap key rather than the mounted env file

    • Bug
      • The patch at lines 163-164 adds data.REP_PUBLIC_FEATURE_FLAGS. The configured dynamic ConfigMap stores all variables under the .env key, which mounts as /config/.env; the gateway reload path reads only that file. Consequently the requested dark-mode,ai-assist value is mounted as separate /config/REP_PUBLIC_FEATURE_FLAGS and does not reload into the gateway.
    • Cause
      • The patch payload addresses a top-level data key named REP_PUBLIC_FEATURE_FLAGS instead of replacing or updating the contents of data[".env"].
    • Fix
      • Patch the .env ConfigMap entry with complete updated env-file content, or generate and kubectl apply an updated ConfigMap manifest whose .env value contains REP_PUBLIC_FEATURE_FLAGS=dark-mode,ai-assist.

    T-Rex Ran code and verified through T-Rex

Reviews (2): Last reviewed commit: "fix(docs): correct the Kubernetes hot-re..." | Re-trigger Greptile

Comment thread docs/src/content/docs/agents.mdx Outdated
`Reload()` re-reads configuration via `config.ReadAndClassify(s.cfg.EnvFile)`
(gateway/internal/server/server.go:398). With `EnvFile` empty — it is set
only by `--env-file`/`REP_GATEWAY_ENV_FILE` (config.go:155) — classify.go
builds the variable set from `os.Environ()` alone (classify.go:101-122).

Both Kubernetes recipes supplied configuration through `envFrom` while
watching a mounted ConfigMap. `envFrom` is captured once at container
start, so a volume refresh fired the watcher and the reload succeeded,
but the injected payload kept its original values. The documented
"no pod restart" workflow did not work.

Both recipes now mount a single env-format ConfigMap key and pass
`--env-file=/config/.env`, and the ConfigMap shape is corrected — a
`data:` map of one key per variable mounts as one file per key, not as
an env file.

Also documents the precedence trap: ReadAndClassify merges the env file
first and lets the process environment overwrite it, so a key set through
both `envFrom` and `--env-file` silently keeps its `envFrom` value.

Verified against a locally built gateway using a kubelet-style volume
(timestamped directory + atomic `..data` symlink rename): the corrected
recipe moves the injected value across the swap and emits
`rep.config.changed` for each key, and the same key set in both sources
reproduces the stale-value behaviour.
@olamide226
olamide226 merged commit ef2b494 into main Sep 11, 2026
10 checks passed
@olamide226
olamide226 deleted the docs/agent-readable-markdown branch September 11, 2026 14:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant