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
4 changes: 3 additions & 1 deletion eslint.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ import pleaseai from '@pleaseai/eslint-config'

export default pleaseai(
{
ignores: ['docs/**', 'website/src/content/**', 'website/.astro/**', 'website/dist/**'],
// website/src is scaffolded by Nimbus; keeping its upstream style lets
// `nimbus-docs diff --apply` upgrades apply cleanly.
ignores: ['docs/**', 'website/src/**', 'website/.astro/**', 'website/dist/**', 'website/AGENT.md', 'website/CLAUDE.md'],
Comment thread
amondnet marked this conversation as resolved.
},
{
// The CLI legitimately prints to stdout.
Expand Down
20 changes: 19 additions & 1 deletion website/.gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,22 @@
dist/
node_modules/
dist/
.astro/
.wrangler/
.nimbus/

.env
.env.local
.env.*.local
.env.production
.dev.vars
.dev.vars.*

npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*

.DS_Store
.idea/
.vscode/*
!.vscode/extensions.json
157 changes: 157 additions & 0 deletions website/AGENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
# This Nimbus docs site

> `CLAUDE.md` delegates here. Keep project instructions canonical in this file.

Astro-based docs. The `nimbus-docs` package handles content schemas, sidebar/TOC, MDX→markdown, build hooks, and the `nimbus-docs` CLI. Install dependencies first, then run it as `npx @cloudflare/nimbus-docs <command>`: npx uses the project's installed version. Before an install, npx fetches the latest release instead, which may differ from the site's version and give different results. The scoped name keeps npx from fetching the unrelated `nimbus-docs` package. Everything in `src/` is yours to edit.

## File layout

```
astro.config.ts # imports nimbus + defineNimbusConfig
nimbus.json # records the last reviewed Nimbus package version
src/
├── components.ts # MDX globals — components every .mdx can use without an import
├── components/ # AgentDirective, Header, Render + ui/<slug>/
├── content/
│ ├── docs/*.mdx
│ └── partials/*.mdx # referenced via <Render file="..." />
├── content.config.ts # registers docsCollection() + partialsCollection()
├── layouts/ # BaseLayout (NimbusHead), DocsLayout (sidebar/TOC/breadcrumbs)
├── lib/cn.ts # Tailwind className merger
├── pages/
│ ├── [...slug].astro
│ ├── [...slug]/index.md.ts # Markdown version of every page, all collections
│ ├── [...slug]/index.mdx.ts # authored source of every page, all collections
│ ├── [...section]/llms.txt.ts # per-section llms.txt, nested sections included
│ ├── 404.astro
│ ├── index.astro # home page (the empty starter uses content/docs/index.mdx)
│ ├── llms.txt.ts
│ ├── llms-full.txt.ts
│ ├── nimbus-api/coordinates.json.ts # API citation manifest
│ ├── og.png.ts # site-level OG card
│ ├── og/
│ │ ├── _og-card-config.ts # shared OG theme tokens (underscore = not a route)
│ │ └── [...slug].ts # per-page OG cards
│ └── robots.txt.ts
└── styles/ # globals.css, prose.css
```

Cloudflare deploys also have `wrangler.jsonc` at the project root.

## Writing docs

Frontmatter validates against the schema from `docsCollection()` (`@cloudflare/nimbus-docs/content`). Required: `title`.

```mdx
---
title: My page
description: One-line summary.
---

Content here. The page H1 comes from `title` — don't repeat it in the body.

## Section heading
```

Rules:

- **Components are PascalCase.** Register one in `src/components.ts` to use it in every `.mdx` without an import, or import it in the file that uses it. A pre-build validator catches unresolved names with a "did you mean" hint.
- **Partials use `<Render file="..." />`.** Don't import `.mdx` directly. Shared content lives in `src/content/partials/<slug>.mdx`.
- **Icons use Nimbus's `Icon` + Phosphor.** `<Icon name="ph:<glyph>" class="w-4 h-4" />` from `@cloudflare/nimbus-docs/components/Icon.astro`. Glyphs: [phosphoricons.com](https://phosphoricons.com).
- **Don't remove `<AgentDirective />` from `BaseLayout.astro`.** It points agents at `/llms.txt`.

## Adding things

| Goal | Action |
|---|---|
| New doc page | Create `src/content/docs/<slug>.mdx`. Sidebar picks it up. |
| New partial | Create `src/content/partials/<slug>.mdx`. Use via `<Render file="<slug>" />`. |
| UI from registry | `npx @cloudflare/nimbus-docs add <slug>`. Register in `src/components.ts` if used in MDX. |
| Feature recipe | `npx @cloudflare/nimbus-docs add <feature-slug> --print`. Prints the recipe for you to follow; it changes no files itself. |
| Check it builds | `npx @cloudflare/nimbus-docs check` — build-free preflight (env + structure + authoring + types). `--json` for an agent loop, `--fix` to repair what's safe. |
| Custom page route | Add a file under `src/pages/`. |
| Custom OG style | Edit `src/pages/og/_og-card-config.ts`. |
| Check for updates | `npx @cloudflare/nimbus-docs outdated` — starter files behind their tag + registry components behind. |
| Upgrade Nimbus | Update the package, then run `npx @cloudflare/nimbus-docs migrate --dry-run --diff`. Review every change and required manual step before applying. |
| Upgrade a starter file | `npx @cloudflare/nimbus-docs diff <file>` to review, `diff --apply <file>` to pull a clean upstream change. |
| Upgrade a registry component | `npx @cloudflare/nimbus-docs add <slug> --overwrite`, then review with `git diff`. |

Sätteri is Nimbus's default Markdown and MDX processor. Extend it using `markdown.mdastPlugins` for Markdown AST transformations or `markdown.hastPlugins` for HTML AST transformations.
If the site replaces Sätteri with another processor, set `admonitions: false` and keep that processor's existing callout implementation.

List installable items: `npx @cloudflare/nimbus-docs list`.

## Sidebar

The sidebar mirrors `src/content/docs/`. A folder becomes a group, and its `index.mdx` is the group's landing page; set `sidebar.group.label` there to rename the group. Within a group, `sidebar.order` sorts entries (lowest first, otherwise alphabetical), `sidebar.label` shortens a page's rail title, and `sidebar.hidden: true` builds a page without listing it.

To add an external link or fix the top-level order, set `sidebar.items` in `defineNimbusConfig` in `astro.config.ts`. Items you list replace the generated top level, and a listed item's `label` wins over the folder's `sidebar.group.label`:

```ts
sidebar: {
items: [
{ label: "Guides", autogenerate: { directory: "guides" } },
{ label: "GitHub", link: "https://github.com/you/repo" },
],
},
```

Everything else: <https://nimbus-docs.com/navigation/sidebar/>.

## Agent interfaces

Read the release-matched guide at [`node_modules/@cloudflare/nimbus-docs/dist/docs-for-agents.md`](node_modules/@cloudflare/nimbus-docs/dist/docs-for-agents.md), especially for preview packages. Nimbus publishes discovery automatically; add project-owned Skills under `skills/<name>/SKILL.md`. Keep `<WebMCP />` in `BaseLayout.astro` for browser-agent search with default Pagefind. Markdown negotiation applies to request-rendered pages; static hosting and response headers follow the deployment target's setup.

## Upgrading Nimbus

Keep `nimbus.json` committed. Its `lastReviewedNimbusVersion` is the baseline Nimbus uses to select the versioned reviews crossed by a package upgrade; state-detected migrations come from the current project files. It is not a package pin and should not be edited by hand.

1. Update `@cloudflare/nimbus-docs` with the project's package manager.
2. Preview the complete plan with `npx @cloudflare/nimbus-docs migrate --dry-run --diff`. If no baseline exists yet, add `--from <previous-version>`.
3. Review every versioned entry and resolve each blocked/manual item.
4. Apply safe edits only with explicit consent: `npx @cloudflare/nimbus-docs migrate --yes`. Review the resulting diff, then rerun the preview.
5. When no migration remains, run `npx @cloudflare/nimbus-docs migrate --yes` again to record the completed review in `nimbus.json`.
6. Pull in starter fixes: `npx @cloudflare/nimbus-docs outdated` lists starter files that changed upstream. For each one, review it with `npx @cloudflare/nimbus-docs diff <file>`, and take a clean update with `diff --apply <file>`. Merge files you've edited by hand. `migrate` doesn't cover these.
7. Run the project's typecheck and production build, then run `npx @cloudflare/nimbus-docs check` again for post-build coverage.

Except for task-printing mode (`--print`), `migrate` exits nonzero while work or review remains; that is a pending-upgrade signal, not necessarily a command failure. Never skip versions by changing `nimbus.json` directly.

## Audit this site

First set `site` in `astro.config.ts` to the production URL; a fresh site still has the placeholder. Ask the user for the URL if you don't know it, and never make one up.

Then run `npx @cloudflare/nimbus-docs check --json`. It runs the environment, structural, authoring, and type checks build-free — config validity, `site` placeholder, route collisions, MDX component resolution, the lint rules, and a `tsc` type-check — and returns three top-level signals plus per-scope detail:

- **`status`** (`passed` | `failed` | `partial`) and **`readiness`** (`buildable` | `blocked` | `unknown`) are the primary signals. `status` is the whole-run verdict; `readiness` answers "does env + structure say it builds?". `ok` (=== zero errors) is kept for back-compat only.
- **`findings[{scope,code,severity,file,line,message,fixable,fix}]`** are problems we evaluated. Apply each `fix` (or `check --fix`).
- **`scopes[].notes[{code,reason,requiresBuild?,requiresInput?}]`** are checks we *couldn't* evaluate yet (e.g. types before a build). A note is never a finding and never carries a `fix` — you resolve it by making the missing thing exist (usually a build), not by `--fix`. `summary.notes` counts them.

Loop until `status !== "failed"` and no finding has a `fix` without `fix.requiresInput` — `summary.fixable` also counts fixes that need input (a placeholder `site`), which `--fix` can't apply for you. An error with no `fix` (such as `nimbus/dependencies-missing`) ends the loop too: do what its message says (install dependencies), then run `check` again, or stop and report it. A `partial` run with nothing left to fix is a **stop** (optionally build, then re-check), not a `--fix` retry. Exit is `1` only when `status` is `"failed"`. For full coverage (types + link-checking) run a build first, then `check` again. With server output, `check` stays `partial` with the note `nimbus/request-rendering-build-required` even after a build: it doesn't verify request-rendered pages, so a passing production build is the gate.

Then walk the categories below for what `check` doesn't cover yet — route-file existence, registry hygiene, the AI surface, post-build search, and Cloudflare config. Emit findings as:

```
- [error|warn|info] FILE:LINE — what + why + fix.
```

End with `Summary: N errors, N warnings.`

- **Config** — `astro.config.ts` calls `nimbus(defineNimbusConfig({ ... }))`; `site` is set; `editPattern` (if set) contains `{path}`; `output:` matches the deploy target.
- **Content** — `content.config.ts` registers `docsCollection()` (and `partialsCollection()` if used); every `.mdx` is inside a registered collection; frontmatter validates.
- **Sidebar** — every sidebar ref resolves to a content entry; no orphans; no slug collisions.
- **MDX** — every PascalCase component in `*.mdx` is registered or imported; every `<Render file=...>` resolves; code-fence languages are valid.
- **Routes** — `llms.txt.ts`, `robots.txt.ts`, `[...slug]/index.md.ts`, `og.png.ts`, `og/[...slug].ts` all exist.
- **Registry hygiene** — every `src/components/ui/<slug>/` is either MDX-registered or imported in `src/`; transitive deps (`lib/cn.ts`, etc.) exist.
- **AI surface** — `<AgentDirective />` renders in `BaseLayout.astro`; doc `<head>` has `<link rel="alternate" type="text/markdown" ...>`.
- **Search** — `data-pagefind-body` is on the docs main wrapper; after a production build, `dist/pagefind/` exists with ≥1 indexed page.
- **Cloudflare** (if applicable) — `wrangler.jsonc` has `name` and `compatibility_date`. Static output: `assets.directory = "./dist"` and `assets.not_found_handling = "404-page"`. Cloudflare Pages (this site): `pages_build_output_dir = "dist"` instead of `assets`; Pages serves the emitted `404.html` for unmatched paths. Server output (`@astrojs/cloudflare`): no `assets.directory` or `main`; the adapter writes the deploy config to `dist/server/wrangler.json` at build time, so check that file after a build.

## Don't

- Hand-add components under `src/components/ui/` that exists in the Nimbus registry — use `npx @cloudflare/nimbus-docs add <slug>` so deps resolve.
- Import `.mdx` files directly — use `<Render file="..." />`.
- Remove `<AgentDirective />` unless asked.

## Project home

[nimbus-docs.com](https://nimbus-docs.com)
3 changes: 3 additions & 0 deletions website/CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# This Nimbus docs site

Read and follow [AGENT.md](./AGENT.md). It is the canonical project guidance for editing, auditing, upgrading, and validating this Nimbus site.
21 changes: 17 additions & 4 deletions website/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# emulate docs

Documentation site for [pleaseai/emulate](https://github.com/pleaseai/emulate),
built with [Astro Starlight](https://starlight.astro.build) and deployed to
Cloudflare Pages.
built with [Nimbus](https://nimbus-docs.com) (Cloudflare's docs framework on
Astro) and deployed to Cloudflare Pages.

**Live site: <https://emulate.pleaseai.dev>**

Expand All @@ -17,17 +17,30 @@ bun run dev # http://localhost:4321
## Content sources

- `src/content/docs/guides/` and `reference/` — hand-written pages
- `src/content/docs/services/*.md` — **generated** from `../skills/<service>/SKILL.md`.
- `src/content/docs/services/*.mdx` — **generated** from `../skills/<service>/SKILL.md`.
Do not edit them directly; update the skill and regenerate:

```bash
bun run sync:services
```

The sidebar is built from the directory tree; each page's `sidebar.order`
frontmatter sets its position. Everything else under `src/` (layouts,
components, routes, styles) was scaffolded by Nimbus and can be edited freely. See
`AGENT.md` for Nimbus-specific guidance, and run `bunx @cloudflare/nimbus-docs outdated`
to see upstream template changes when upgrading `@cloudflare/nimbus-docs`.

## Checks

```bash
bun run typecheck # astro check
bun run lint:docs # nimbus-docs authoring lint
```

## Build & deploy

```bash
bun run build # static output in dist/
bun run build # static output in dist/, including llms.txt and .md versions
bun run preview # serve the build locally
```

Expand Down
51 changes: 0 additions & 51 deletions website/astro.config.mjs

This file was deleted.

49 changes: 49 additions & 0 deletions website/astro.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import nimbus, { defineConfig as defineNimbusConfig } from '@cloudflare/nimbus-docs'
import { tableScroll } from '@cloudflare/nimbus-docs/markdown'
import tailwindcss from '@tailwindcss/vite'
import { defineConfig } from 'astro/config'

const nimbusConfig = defineNimbusConfig({
site: 'https://emulate.pleaseai.dev',
title: 'emulate',
description:
'Local drop-in replacement services for CI and no-network sandboxes. Fully stateful, production-fidelity API emulation.',
locale: 'en',
github: 'https://github.com/pleaseai/emulate',
editPattern: 'https://github.com/pleaseai/emulate/edit/main/website/{path}',
socialImageAlt: 'emulate documentation preview',
sidebar: {
items: [
{ label: 'Guides', autogenerate: { directory: 'guides' } },
{ label: 'Services', autogenerate: { directory: 'services' } },
{ label: 'Reference', autogenerate: { directory: 'reference' } },
],
},
})

export default defineConfig({
// nimbus:adapter
output: 'static',
// Tailwind v4 via its Vite plugin (the PostCSS plugin doesn't build under
// Astro 7's Vite 8 bundler).
vite: {
plugins: [tailwindcss()],
},
prefetch: {
prefetchAll: true,
defaultStrategy: 'hover',
},
integrations: [
nimbus(nimbusConfig, {
rules: {
'nimbus/frontmatter-shape': 'error',
'nimbus/internal-link': 'error',
},
markdown: {
// Wrap wide tables so they scroll instead of overflowing the page
// (styled by `.nb-table-scroll` in src/styles/prose.css).
hastPlugins: [tableScroll()],
},
}),
],
})
Loading
Loading