Skip to content
Draft
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
133 changes: 133 additions & 0 deletions .agents/skills/ask-the-docs/SKILL.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
---
name: ask-the-docs
description: >-
Answer questions about the Supabase docs app (apps/docs) using
documented architecture, build pipeline, and review-pattern notes, and
apply feature-design principles (codebase reuse, coding minimalism)
when proposing or critiquing changes. Use when the user asks "how does
X work in the docs app?", "where does Y live?", "is this approach OK
for the docs app?", or before writing non-trivial changes under
apps/docs/ — especially anything touching the MDX pipeline, markdown
generation, content components, federated docs, or contributor-facing
authoring patterns. Can answer architecture questions with Mermaid
diagrams when helpful.
---

# Ask the docs-app librarian

A reference for `apps/docs` knowledge — architecture, build pipeline,
federated docs, known fragilities — plus the feature-design principles
the codebase rewards: **understand and reuse the existing code before
writing new code**, and **practice coding minimalism** to keep the
surface area small.

Two jobs:

1. **Look up what's already documented** about the docs app —
architecture, tradeoffs, gotchas, prior decisions — instead of
re-deriving from cold reads.
2. **Pre-empt review feedback** by applying the codebase-reuse /
minimalism principles before opening a PR. Catches the "fix it in the
next round" comments early.

## When to invoke

- User asks about `apps/docs` architecture, conventions, or behavior
("how does the markdown pipeline work?", "where do listings data files
go?", "why does Troubleshooting have a `.mjs` utils file?").
- User asks about LLM/agent consumption (`llms.txt`, markdown negotiation,
`searchDocs`, bulk exports, agent onboarding guides, humans vs agents vs
crawlers, AI prompt blocks in quickstarts).
- About to write code under `apps/docs/` that touches: MDX components,
`internals/markdown-schema/`, `generate-guides-markdown.ts`, content
data modules, the lint pipeline, telemetry events, contributor-facing
snippets, federated routes, reference codegen, or Management API /
OpenAPI reference pages.
- Reviewing a docs-app PR and want a sanity check against the documented
principles.

**Not for:** general Supabase docs _content_ questions (use
`work-linear-issue`, `audit-quickstarts`, etc.), or app-level work outside
`apps/docs/`.

## Answering with diagrams

Architecture and pipeline questions are often clearer with a diagram
than with prose. Default to including a **Mermaid diagram** in answers
about:

- The MDX runtime vs markdown-export pipeline split.
- Build flow (Turbo → pnpm `prebuild` / `build` / `postbuild` → Vercel).
- LLM/agent consumption surface (`llms.txt`, negotiation, bulk exports).
- Federated docs fetch flow.
- CI / PR flow.
- Component / data-registry relationships.
- Management API OpenAPI → codegen → reference page flow.

Mermaid fences (`` ```mermaid `````) render natively on GitHub, Cursor,
and most Markdown previewers. Several reference files already embed
Mermaid; reuse or adapt them rather than re-deriving.

Keep diagrams **small and one-topic**. If a diagram needs more than a
dozen nodes, split it.

## Reference files

Short, focused docs under `reference/`. Read whichever apply to the task
at hand — they cite each other where context matters.

| File | What's inside |
| ---------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| [`reference/adding-features.md`](./reference/adding-features.md) | Best-practices guidance for adding features to `apps/docs`. Inventory existing code first, pick the smallest viable shape, reuse pipelines. |
| [`reference/docs-app-direction.md`](./reference/docs-app-direction.md) | Refactoring vision and working norms — what new work should align with. |
| [`reference/known-issues.md`](./reference/known-issues.md) | Living list of broken, fragile, or in-flux systems. Check before depending on anything (federated docs, search, Sentry, reference-page architecture). |
| [`reference/app-map.md`](./reference/app-map.md) | Architecture cheat sheet — directories, the two-pipeline (MDX runtime + markdown export) model, heading/typography contract, telemetry, lint entries. |
| [`reference/build-pipeline.md`](./reference/build-pipeline.md) | Turborepo + pnpm lifecycle steps for building `apps/docs` — codegen, prebuild, postbuild, Vercel deploy. Mermaid diagram included. |
| [`reference/llm-agent-surface.md`](./reference/llm-agent-surface.md) | Audience routing (humans vs agents vs crawlers), `llms.txt`, content negotiation, bulk exports, two-pipeline parity for embedded content (AI prompts). |
| [`reference/federated-docs.md`](./reference/federated-docs.md) | How docs pulls markdown from external repos at build time. Routes, `pageMap`, remark/rehype plugins, link transforms, known failure modes. |
| [`reference/ci-and-lint.md`](./reference/ci-and-lint.md) | GitHub Actions on every PR — `docs_lint`, `Docs Tests`, typecheck, prettier, Vercel preview gate. Where to add a check before creating a new one. |
| [`reference/management-api-reference.md`](./reference/management-api-reference.md) | Management API OpenAPI download → Redocly bundle → codegen → `ApiEndpointSection`; why not to swap in Scalar/Redoc. |
| [`reference/gotchas.md`](./reference/gotchas.md) | Specific traps to watch for. One-liner per item. |

## How to use during a chat

1. **Start by reading** `adding-features.md` and `app-map.md` if the
question touches design choices or unfamiliar code paths. They're
small on purpose — read both, don't skim.
2. **Verify before recommending.** Reference content may lag behind the
live code. Confirm with the actual files (`apps/docs/...`) before
acting on remembered claims about file paths, function names, or
behavior.
3. **Cite the principle**, not just the rule. "Per `adding-features.md`
§ 'Reuse pipelines, don't fork them', this routes through the
existing markdown-schema handler rather than introducing a side
path."
4. **Reach for Mermaid** when explaining architecture, flows, or
relationships — see [Answering with diagrams](#answering-with-diagrams).

## Updating the librarian

This skill lives in `.agents/skills/ask-the-docs/` in `supabase/supabase`.
When something in `apps/docs` changes in a way that makes a reference
file inaccurate, or a generally-applicable lesson emerges from a PR
review, open a pull request against this repo to update the relevant
file, same as any other in-repo change.

Keep each canonical file under ~250 lines; split before they bloat.
Capture only what a future contributor would benefit from knowing — if
a fact is already obvious from a quick read of the live code, don't
write it down.

## Related skills

- [`pm-the-docs`](../pm-the-docs/SKILL.md) — audience, stage, and
cross-cutting scope calls (Frame stage of the "Write the docs" checklist,
mirrored in `pm-the-docs`'s reference file).
- [`work-linear-issue`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/work-linear-issue/SKILL.md) — implementing
assigned DOCS-\* tickets.
- [`review-the-docs`](../review-the-docs/SKILL.md) — reviewing open docs
PRs with type-specific verification.
- [`audit-content-listings`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/audit-content-listings/SKILL.md) — batch
conversion of overview pages to content listings.
- [`create-pull-request`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/create-pull-request/SKILL.md) — opening or
updating a docs PR.
206 changes: 206 additions & 0 deletions .agents/skills/ask-the-docs/reference/adding-features.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,206 @@
# Adding features to `apps/docs`

Best-practices guidance for adding features to the docs app. Read this
**before** writing code — most "fix it in the next round" review comments
trace back to skipping one of these steps.

The premise: `apps/docs` has accumulated significant surface area already.
Any new file, build step, lint job, or content shape is a permanent
maintenance cost. The goal is to deliver the feature with the smallest
durable footprint by **understanding the existing code first** and
**reusing what's already there**.

## The cost lens

Every change adds one of two things:

- **Reach** — the feature now does more (user-visible value).
- **Surface** — there is now more code, configuration, or vocabulary to
maintain (recurring cost).

A good change maximizes reach per unit of surface. When a design discussion
stalls, re-frame as: _"Does the user-visible improvement justify the
maintenance cost?"_ If you cannot answer yes confidently, cut scope before
defending the design.

See [`docs-app-direction.md`](./docs-app-direction.md) for the broader
context — the docs app already carries known tech debt, and the maintainer's
stated direction is to reduce surface, not extend it.

## Step 1 — Inventory before you write

Before adding a file, search for what's already there. The docs app has
existing systems for almost every common job; using them is faster than
building parallel ones.

| Need | Look first at |
| ------------------------------------------- | ----------------------------------------------------------------------------------------------------------- |
| Rendering MDX with a custom component | The MDX component map in `features/docs/MdxBase.shared.tsx` |
| Markdown export of a component | The schema registry in `internals/generate-guides-markdown.ts` and handlers in `internals/markdown-schema/` |
| Reusable content blocks | `<$Partial path="..." />` and `content/_partials/` |
| Headings / typography | `<Heading>` from `MdxBase.shared.tsx`; prose / `not-prose` classes |
| Visual primitives (cards, panels, callouts) | `ui-patterns/GlassPanel`, `ui-patterns/IconPanel`, `ui/Admonition`, etc. |
| Internal vs external link logic | `withDocsBasePath` / `addBaseUrlPrefix` in `lib/internal-links.ts` |
| Telemetry | `useSendTelemetryEvent` + `packages/common/telemetry-constants.ts` |
| Validation / schemas | `zod` schemas under `apps/docs/lib/` |
| Code samples in MDX | `$CodeSample` directive |
| Build steps | `prebuild` / `postbuild` chain in `apps/docs/package.json` |
| CI checks | Existing workflows under `.github/workflows/`. See [`ci-and-lint.md`](./ci-and-lint.md). |
| Lint rules for MDX content | `supa-mdx-lint` configuration — extend it, don't add a new lint job |

If something close to what you need already exists, **the default is to
extend it**, not to build alongside.

## Step 2 — Pick the smallest viable shape

For most feature requests, the shapes in descending order of preference are:

1. **Pure content change** — MDX edit, partial, or data file. No new code.
2. **Configuration of an existing component** — pass a new prop to an
existing primitive; extend a config object.
3. **A new data shape consumed by existing components** — a typed
`*.data.ts` module read by an already-registered MDX component.
4. **A thin component that composes existing primitives** — a small file
that orchestrates `<Link>`, `<GlassPanel>`, `<Heading>`, etc. Adds an
MDX component-map entry but no new visual primitives.
5. **A new primitive in the design system** — last resort. Justify against
`packages/ui` / `ui-patterns`.

Move down the list only when the option above genuinely cannot express the
feature. The further down you go, the more you should write down why.

## Step 3 — Reuse pipelines, don't fork them

If a feature has to render in more than one place (HTML + markdown export,
runtime + build, etc.), wire both consumers through a **single shared
shape** — a data registry, a schema, a constant map — instead of
maintaining parallel implementations.

Pattern that works well in this codebase:

- The MDX component reads from a data registry keyed by an `id`.
- The markdown-export handler reads from the _same_ registry, using the
same `id` carried as a JSX prop.
- The data shape (zod schema) is the single source of truth.

Antipatterns to avoid:

- Two extraction paths that serialize the same content differently.
- A bespoke link-wrapper component when `<Link>` + `<GlassPanel>` already
covers the pattern — compose at the call site instead.
- New custom build steps that run alongside the existing `prebuild` /
`postbuild` chain when a hook already exists.
- A new CI workflow when `docs_lint`, `Docs Tests`, or the existing
typecheck/prettier jobs could absorb the check. See
[`ci-and-lint.md`](./ci-and-lint.md).
- A new content vocabulary (custom front-matter block, novel MDX directive,
new YAML schema) when a React component + partial would express the same
thing.

## Step 4 — Conventions that keep the diff small

These are the patterns most often called out in PR review. None of them
matter individually; together they keep the surface tight.

### File naming

A file's name matches what it exports. If the file exports `Foo`, it's
`Foo.ts(x)`. The directory listing should answer "what's in here?" without
opening the file. Same for handler files in `internals/markdown-schema/` —
the file name is the JSX element name.

### Import aliases

`import { Foo as Bar }` is reserved for genuine name collisions. Aliasing
for "clarity" or "consistency with old naming" adds friction.

### Single-use helpers stay inline

A helper used in one place lives in that place. New files are for shared
code. Wandering helpers in unrelated folders make code hard to find.

### Pure helpers live in `*.utils.ts`

Schema files hold schemas. Data / constant files hold data. Helpers —
including lookups like `getXById` over a constant map — live in
`X.utils.ts`. Predictable location beats "logical grouping by concept."

### Don't override the design system

Use shared primitives (`<Heading>`, `<GlassPanel>`, prose classes) and let
them carry typography and spacing. Adding `text-xl` or `font-semibold` to
a new component is the wrong escape hatch.

### Keep `internals/` out of client and MDX code

`apps/docs/internals/` is for build-time markdown generation. Client
components and the MDX runtime should not import from it. If a function is
needed on both sides, it belongs in `lib/`.

### Markup follows semantics, not visuals

A collection of links is a `<ul>`, regardless of whether it visually
renders as a list or a grid. CSS handles layout; markup handles semantics.

### Collapse near-duplicates with discriminator props

When two components share structure and differ only in classes or markup
details, collapse them. Extract the differences into class-name constants
keyed by the discriminator (`type: 'grid' | 'list'`). Don't ship two
components that are 90% identical.

### Use maps / lookups over arithmetic on known sets

If the input domain is `'h2' | 'h3' | 'h4'`, a `Map` (or `Record<Literal, T>`)
keyed by those literals is clearer than slicing strings and synthesizing
output. Exhaustiveness checking comes along for free.

### Avoid render-time closure churn

Hooks should return _stable_ callbacks (`useCallback`) that consumers
invoke, not curried builders that create a new closure per item per render.
Inline arrow functions at the call site are fine; building closures in a
loop during render is not.

### Be robust on URL / string parsing

`/^https?:\/\//i` is incomplete. Protocol-relative (`//host`), `mailto:`,
`tel:`, and bare schemes are all external. Prefer `new URL(href, base)` or
a regex that covers `^(?:[a-z][a-z0-9+\-.]*:|\/\/)`.

### Keep diffs minimal

Import reordering, prettier reflows, or unrelated whitespace edits in a
feature PR muddy the review. If a file isn't conceptually part of the
change, revert it. Auto-formatter ran on a file you didn't touch? Reset
it.

## Step 5 — Pre-flight before opening the PR

Run through this checklist before pushing:

- [ ] Searched the inventory in Step 1 for existing primitives / pipelines.
- [ ] Picked the smallest shape that delivers the feature (Step 2).
- [ ] Renders consistently across pipelines that share content (Step 3).
- [ ] File and export names match (Step 4 — file naming).
- [ ] No unnecessary helpers, imports, files, or aliases.
- [ ] Typography defers to shared primitives.
- [ ] No `internals/` imports from client / MDX code.
- [ ] Diff contains only changes relevant to the feature.
- [ ] `pnpm format`, `pnpm typecheck`, and the relevant lint job pass.

Replies on review threads move faster when they point to a specific commit
("done in abc1234") than when they explain the reasoning at length.
Expect review to come in **passes** that go progressively deeper — that is
the path to a minimum-surface design, not nitpicking.

## Related

- [`docs-app-direction.md`](./docs-app-direction.md) — broader context on
the docs app's tech debt and refactoring direction.
- [`app-map.md`](./app-map.md) — where each existing seam lives.
- [`build-pipeline.md`](./build-pipeline.md) — the build steps you should
consider extending before adding a new one.
- [`ci-and-lint.md`](./ci-and-lint.md) — the CI checks you should consider
extending before adding a new workflow.
- [`gotchas.md`](./gotchas.md) — specific traps known to bite.
Loading
Loading