Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 11 additions & 1 deletion .github/workflows/docs.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
name: Docs

# Checks packages/docs on every pull request and push to main that can change the built site: the docs
# themselves, the SDK they import, the skills they publish under /skills/, and the lockfile.
# themselves, the SDK they import, the skills they publish under /skills/, the changelogs the release
# notes are built from, and the lockfile.
# Same-repo pull requests also get a preview: a Worker version uploaded under the alias pr-<number>.
# Production deploys are not done here; see docs-deploy.yml.
on:
pull_request:
paths:
- packages/docs/**
- packages/sdk/**
- packages/cli/CHANGELOG.md
- plugins/radius/**
- .claude-plugin/**
- pnpm-lock.yaml
Expand All @@ -18,6 +20,7 @@ on:
paths:
- packages/docs/**
- packages/sdk/**
- packages/cli/CHANGELOG.md
- plugins/radius/**
- .claude-plugin/**
- pnpm-lock.yaml
Expand All @@ -43,6 +46,10 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
# Release notes list a radius-sdk / radius-cli version once its release tag exists, dated by
# the tag; docs-deploy.yml checks out the same way.
fetch-depth: 0
fetch-tags: true

- name: Set up pnpm
uses: pnpm/action-setup@v6
Expand Down Expand Up @@ -75,6 +82,9 @@ jobs:
- name: Test flat skill generation
run: pnpm test:skills

- name: Test release notes generation
run: pnpm test:release-notes

- name: Markdown audit
run: pnpm docs:markdown-audit

Expand Down
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ From the repository root, run whichever of these apply to what you changed. Ever
- Every PR that changes `packages/cli` or `packages/sdk` adds a changeset (`pnpm changeset`, or a file in `.changeset/`). Never edit `CHANGELOG.md` or package versions by hand.
- Document an SDK or CLI change in `packages/docs` in the same PR, and audit the skills under `plugins/radius/skills` that cover it.
- A skill may name a new SDK or CLI API only once that version is on npm. State the minimum package version in the skill.
- Bump `plugins/radius/.claude-plugin/plugin.json` in any PR that changes a skill, the plugin manifest or the plugin README: patch for corrections, minor for new capabilities. The plugin is not part of Changesets.
- Bump `plugins/radius/.claude-plugin/plugin.json` in any PR that changes a skill, the plugin manifest or the plugin README: patch for corrections, minor for new capabilities. The plugin is not part of Changesets. Each bump adds a `## <version> (<YYYY-MM-DD>)` entry to `plugins/radius/CHANGELOG.md`; the docs release notes are built from it, so write the first sentence of each change for developers who use the skills.
- In skill examples, write prices as decimal strings such as `'0.001'`. Claude substitutes `$0` and other positional placeholders even inside code fences.
- No eval case, test or example you run may spend from a funded wallet. The funded testnet proof (`pnpm eval:payments:live`) runs only when a person asks for it.
- Never print, log or commit private keys, `RADIUS_*` secrets or API keys.
Expand Down
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,8 @@ The [Radius Claude Code plugin](plugins/radius) contains the `radius-dev`, `x402
[`.claude-plugin/marketplace.json`](.claude-plugin/marketplace.json). These files
live outside `packages/*`. The plugin has its own version in
[`plugins/radius/.claude-plugin/plugin.json`](plugins/radius/.claude-plugin/plugin.json)
and does not enter the npm Changesets release flow. The marketplace's
and does not enter the npm Changesets release flow. Each version bump adds an entry to
[`plugins/radius/CHANGELOG.md`](plugins/radius/CHANGELOG.md), which the docs release notes are built from. The marketplace's
`metadata.version` describes the catalog, not the plugin; the marketplace entry
does not duplicate the plugin version.

Expand Down
4 changes: 3 additions & 1 deletion packages/docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,10 @@ dist/
.vocs/
tmp/

# Generated at build time (scripts/generate-skills-md.ts, scripts/generate-sitemap.ts)
# Generated at build time (scripts/generate-skills-md.ts, scripts/generate-sitemap.ts,
# scripts/generate-release-notes.ts)
public/skills/
docs/pages/release-notes.mdx
public/sitemap.txt
public/*.xml

Expand Down
2 changes: 2 additions & 0 deletions packages/docs/.prettierignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ tmp/
public/**/*.md
public/**/*.txt
public/**/*.xml
# Generated by scripts/generate-release-notes.ts
docs/pages/release-notes.mdx
19 changes: 16 additions & 3 deletions packages/docs/CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ packages/docs/
│ ├── constants.ts # Network constants used in MDX and generated Markdown
│ └── remark-llm-output.ts # Output-only remark plugin for agent Markdown
├── worker/index.ts # Worker entry: /api/try/* ("Try Radius"), Markdown negotiation, agent logging
├── public/ # Static assets (logos, robots.txt, _redirects, _headers, generated skills/sitemap)
├── scripts/ # Build utilities (skills, sitemap, tx cost, postbuild mirror, validators)
├── public/ # Static assets (logos, robots.txt, _redirects, _headers, generated skills/sitemap/feed)
├── release-notes/network.md # Radius Network release notes, by hand (see Release notes)
├── scripts/ # Build utilities (skills, sitemap, release notes, tx cost, postbuild mirror, validators)
├── vocs.config.ts # Site configuration
├── wrangler.jsonc # Worker, static assets, TRY_PAY_TO, logs, Analytics Engine
├── CLAUDE.md # This file
Expand Down Expand Up @@ -165,7 +166,7 @@ Network values (chain IDs, RPC URLs, asset names and decimals, contract addresse

## Deployment

The site is the `radius-docs` Cloudflare Worker (`wrangler.jsonc`). Workers static assets serve `dist/public`, including `public/_redirects` and `public/_headers` (which marks every `workers.dev` host, previews included, `noindex`); `worker/index.ts` runs only for the paths in `assets.run_worker_first`. Under `/api/try/*` it is the backend of the interactive "Try Radius" components (`docs/components/try/`, used on `/try`), a testnet faucet proxy (the faucet API sends no CORS headers) and priced testnet routes built with `radius-sdk/hono`. Payments go to `TRY_PAY_TO` in `wrangler.jsonc`. Every other path except scripts, styles and images (excluded in `run_worker_first`) also reaches it, because Cloudflare Web Analytics only counts browsers that run its script. It serves pages and agent-facing files (`*.md`, `llms.txt`, `llms-full.txt`, `robots.txt`, sitemaps) from static assets, serves a page's Markdown twin to requests whose `Accept` header prefers `text/markdown`, and records agent requests twice: an `agent fetch` line in Workers Logs (kept 3 to 7 days, for debugging) and a data point in the `docs_agent_fetches` Analytics Engine dataset (for weekly KPIs; `worker/index.ts` documents its columns, which are append-only, including the host to filter previews out). A request is recorded when it negotiated Markdown or has no `Sec-Fetch-Mode` header, which every current browser sends, including on the page's own fetch of its `.md` twin (PageActions prefetches it on every page view). Neither record holds an IP address, query string or body. New static asset folders or file types go in the `run_worker_first` exclusions, so they stay asset-first: every Worker invocation is billed. Run it locally with `pnpm build && pnpm wrangler dev`; `vocs dev` serves the pages only, so the components' API calls fail there.
The site is the `radius-docs` Cloudflare Worker (`wrangler.jsonc`). Workers static assets serve `dist/public`, including `public/_redirects` and `public/_headers` (which marks every `workers.dev` host, previews included, `noindex`); `worker/index.ts` runs only for the paths in `assets.run_worker_first`. Under `/api/try/*` it is the backend of the interactive "Try Radius" components (`docs/components/try/`, used on `/try`), a testnet faucet proxy (the faucet API sends no CORS headers) and priced testnet routes built with `radius-sdk/hono`. Payments go to `TRY_PAY_TO` in `wrangler.jsonc`. Every other path except scripts, styles and images (excluded in `run_worker_first`) also reaches it, because Cloudflare Web Analytics only counts browsers that run its script. It serves pages and agent-facing files (`*.md`, `llms.txt`, `llms-full.txt`, `robots.txt`, sitemaps, `release-notes.xml`) from static assets, serves a page's Markdown twin to requests whose `Accept` header prefers `text/markdown`, and records agent requests twice: an `agent fetch` line in Workers Logs (kept 3 to 7 days, for debugging) and a data point in the `docs_agent_fetches` Analytics Engine dataset (for weekly KPIs; `worker/index.ts` documents its columns, which are append-only, including the host to filter previews out). A request is recorded when it negotiated Markdown or has no `Sec-Fetch-Mode` header, which every current browser sends, including on the page's own fetch of its `.md` twin (PageActions prefetches it on every page view). Neither record holds an IP address, query string or body. New static asset folders or file types go in the `run_worker_first` exclusions, so they stay asset-first: every Worker invocation is billed. Run it locally with `pnpm build && pnpm wrangler dev`; `vocs dev` serves the pages only, so the components' API calls fail there.

The `docs.radiustech.xyz` custom domain is managed in the Cloudflare dashboard, not in `wrangler.jsonc`: listing it there makes `wrangler deploy` call the custom-domains API, which needs zone and DNS permissions the CI token deliberately lacks.

Expand All @@ -174,6 +175,18 @@ The `docs.radiustech.xyz` custom domain is managed in the Cloudflare dashboard,

---

## Release notes

`docs/pages/release-notes.mdx` and the Atom feed `public/release-notes.xml` are generated (and gitignored) by `scripts/generate-release-notes.ts`, which `prebuild`, `predev`, `docs:validate` and `docs:markdown-audit` run. Do not edit the page; edit its sources:

- **Radius Network:** `release-notes/network.md`, by hand. `## <YYYY-MM-DD> (<build>)` per release; the text is MDX.
- **radius-sdk, radius-cli:** their `CHANGELOG.md`, written by Changesets. A version is listed once its `<package>@<version>` git tag exists, dated by the tag, so the docs never announce a version that is not on npm. The generator fails when a checkout has no such tags: CI checks out with `fetch-depth: 0` and `fetch-tags: true`.
- **Radius skills:** `plugins/radius/CHANGELOG.md`, one `## <version> (<YYYY-MM-DD>)` entry per plugin version bump.

Each release is a `## <date>: <product> <version>` heading, so its anchor (`#2026-10-15-radius-sdk-060`) is a stable link to share. Each change's first sentence is bolded as its headline, and the page description names the latest release for link previews and `llms.txt`. Production picks up new entries on the next docs deploy: after every npm release, or a docs-only deploy run by hand.

---

## Content Pages

Three areas, each with its own sidebar in `vocs.config.ts`; the area list is in `docs/areas.ts`. The top nav and a Discover / Build / Reference switcher at the top of the desktop sidebar (`SidebarHeader` slot, `docs/components/AreaSwitcher.tsx`) link them; on mobile, Vocs shows the areas as a menu drop-down. Vocs picks the sidebar whose key is the longest prefix of the page path. Moved URLs redirect in `public/_redirects`.
Expand Down
24 changes: 12 additions & 12 deletions packages/docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,23 +6,23 @@ Source of [docs.radiustech.xyz](https://docs.radiustech.xyz), built with [Vocs](

Run from `packages/docs` (Node 22.15+, pnpm). Build the SDK once first: `pnpm --filter radius-sdk build` (the docs resolve it from its `dist/`).

| Command | Description |
| -------------------------- | ------------------------------------------------------------------------------ |
| `pnpm dev` | Development server at `http://localhost:5173` (pages only, no `/api/try`) |
| `pnpm build` | Generate skills and sitemap, build to `dist/public`, mirror Markdown twins |
| `pnpm wrangler dev` | After a build: serve the site and the Worker (`/api/try/*`) like production |
| `pnpm typecheck:docs` | Type-check the site, scripts and Worker |
| `pnpm docs:validate` | Frontmatter, links, headings and JSON blocks in `docs/pages` |
| `pnpm docs:markdown-audit` | Fail if an MDX component would be left unrendered in agent Markdown |
| `pnpm docs:agent-check` | After a build: fail on unparsed callouts or `.md` links with no file |
| `pnpm docs:sitemap-check` | After a build: validate `sitemap.xml` |
| `pnpm fetch-cost` | Refresh the fee constants in `docs/constants.ts` (the deploy workflow does it) |
| Command | Description |
| -------------------------- | -------------------------------------------------------------------------------- |
| `pnpm dev` | Development server at `http://localhost:5173` (pages only, no `/api/try`) |
| `pnpm build` | Generate skills, release notes and sitemap, build to `dist/public`, mirror twins |
| `pnpm wrangler dev` | After a build: serve the site and the Worker (`/api/try/*`) like production |
| `pnpm typecheck:docs` | Type-check the site, scripts and Worker |
| `pnpm docs:validate` | Frontmatter, links, headings and JSON blocks in `docs/pages` |
| `pnpm docs:markdown-audit` | Fail if an MDX component would be left unrendered in agent Markdown |
| `pnpm docs:agent-check` | After a build: fail on unparsed callouts or `.md` links with no file |
| `pnpm docs:sitemap-check` | After a build: validate `sitemap.xml` |
| `pnpm fetch-cost` | Refresh the fee constants in `docs/constants.ts` (the deploy workflow does it) |

CI (`.github/workflows/docs.yml`) runs format, lint, typecheck, the validators and the build on every pull request that touches the docs, the SDK or the skills, and uploads a preview version of the Worker for same-repo pull requests.

## Hosting and releases

The site is a Cloudflare Worker (`wrangler.jsonc`): Workers static assets serve `dist/public`, including `public/_redirects` and `public/_headers` (`noindex` on `workers.dev` hosts, so previews and the pre-cutover site stay out of search results), and `worker/index.ts` handles `/api/try/*`, the backend of the interactive "Try Radius" components (a testnet faucet proxy and priced testnet routes built with `radius-sdk/hono`). Pages and the agent-facing files (`*.md`, `llms.txt`, `llms-full.txt`, `robots.txt`, sitemaps) also pass through the Worker, which serves them from static assets, gives a page's Markdown twin to requests that ask for `text/markdown`, and records agent requests in Workers Logs and the `docs_agent_fetches` Analytics Engine dataset: browser analytics never see agents. Scripts, styles and images stay asset-first.
The site is a Cloudflare Worker (`wrangler.jsonc`): Workers static assets serve `dist/public`, including `public/_redirects` and `public/_headers` (`noindex` on `workers.dev` hosts, so previews and the pre-cutover site stay out of search results), and `worker/index.ts` handles `/api/try/*`, the backend of the interactive "Try Radius" components (a testnet faucet proxy and priced testnet routes built with `radius-sdk/hono`). Pages and the agent-facing files (`*.md`, `llms.txt`, `llms-full.txt`, `robots.txt`, sitemaps, the `release-notes.xml` feed) also pass through the Worker, which serves them from static assets, gives a page's Markdown twin to requests that ask for `text/markdown`, and records agent requests in Workers Logs and the `docs_agent_fetches` Analytics Engine dataset: browser analytics never see agents. Scripts, styles and images stay asset-first.

Production follows releases, not `main`, so the docs never describe a package version that is not on npm. `.github/workflows/docs-deploy.yml` builds and deploys, then moves the `docs-live` tag to the deployed commit:

Expand Down
6 changes: 6 additions & 0 deletions packages/docs/docs/pages/_root.css
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,12 @@ h1 {
font-weight: 600;
}

/* A link to a heading (a shared release, a section) scrolls it below both fixed bars: Vocs offsets
* headings for the top nav only, so the "On this page" bar covered them. */
[data-v-content] :is(h2, h3, h4)[id] {
scroll-margin-top: 2.5rem;
}

/* Inline code only; code blocks are `pre > code`. */
[data-v-content] :not(pre) > code {
color: #eb6359;
Expand Down
9 changes: 6 additions & 3 deletions packages/docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,21 @@
"generate-skills": "tsx scripts/generate-skills-md.ts",
"test:skills": "node --import tsx --test scripts/generate-skills-md.test.ts",
"generate-sitemap": "tsx scripts/generate-sitemap.ts",
"generate-release-notes": "tsx scripts/generate-release-notes.ts",
"test:release-notes": "node --import tsx --test scripts/generate-release-notes.test.ts",
"fetch-cost": "tsx scripts/fetch-transaction-cost.ts",
"predev": "tsx scripts/generate-release-notes.ts",
"dev": "vocs dev",
"prebuild": "tsx scripts/generate-skills-md.ts && tsx scripts/generate-sitemap.ts",
"prebuild": "tsx scripts/generate-skills-md.ts && tsx scripts/generate-release-notes.ts && tsx scripts/generate-sitemap.ts",
"build": "vocs build",
"preview": "vocs preview",
"format:check": "prettier --check .",
"format:write": "prettier --write .",
"lint": "eslint .",
"lint:fix": "eslint --fix .",
"docs:validate": "tsx scripts/validate-docs-v2.ts",
"docs:validate": "tsx scripts/generate-release-notes.ts && tsx scripts/validate-docs-v2.ts",
"postbuild": "tsx scripts/postbuild-static-markdown.ts",
"docs:markdown-audit": "vocs markdown-audit",
"docs:markdown-audit": "tsx scripts/generate-release-notes.ts && vocs markdown-audit",
"docs:agent-check": "tsx scripts/validate-agent-markdown.ts",
"docs:sitemap-check": "tsx scripts/validate-sitemap.ts",
"typecheck:docs": "tsc --noEmit && tsc --noEmit -p tsconfig.scripts.json && tsc --noEmit -p worker/tsconfig.json"
Expand Down
4 changes: 4 additions & 0 deletions packages/docs/public/_headers
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,7 @@
# only docs.radiustech.xyz should be indexed.
https://:worker.:account.workers.dev/*
X-Robots-Tag: noindex

# The release notes feed (scripts/generate-release-notes.ts) is Atom, not generic XML.
/release-notes.xml
Content-Type: application/atom+xml; charset=utf-8
Original file line number Diff line number Diff line change
@@ -1,11 +1,9 @@
---
title: Release notes
description: Read the latest Radius release notes, including product updates, feature launches, fixes, and important developer changes.
---

# Release notes [Latest product and developer changes]

Latest changes to the Radius Network. New features, improvements and bug fixes will be posted here.
<!--
Radius Network release notes, written by hand, newest first. scripts/generate-release-notes.ts merges
them with the radius-sdk, radius-cli and Radius skills changelogs into docs/pages/release-notes.mdx.
Start each release with `## <YYYY-MM-DD> (<build>)`; `###` and `####` headings group its changes.
The text is rendered as MDX: escape `{`, `}` and `<` outside code.
-->

## 2026-09-28 (099a1b5b)

Expand Down
Loading
Loading