diff --git a/.agents/skills/ask-the-docs/SKILL.md b/.agents/skills/ask-the-docs/SKILL.md index f7ed9c49fa4..3f87e86fefc 100644 --- a/.agents/skills/ask-the-docs/SKILL.md +++ b/.agents/skills/ask-the-docs/SKILL.md @@ -125,7 +125,10 @@ write it down. - [`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). + mirrored in `pm-the-docs`'s reference file). Cross-repo **product** lookup + (universe) lives there, not in this skill. +- [`test-the-docs`](../test-the-docs/SKILL.md) — execute docs snippets against a + Docker-isolated local stack; verification report. - [`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 diff --git a/.agents/skills/pm-the-docs/SKILL.md b/.agents/skills/pm-the-docs/SKILL.md index 3d3d2a4867b..d17a30cab70 100644 --- a/.agents/skills/pm-the-docs/SKILL.md +++ b/.agents/skills/pm-the-docs/SKILL.md @@ -3,10 +3,12 @@ name: pm-the-docs description: >- Docs-PM decision support for the "Write the docs" authoring process — makes audience, stage, and cross-cutting scope calls during the Frame - and Shape stages, and helps decide when a docs question needs to - self-serve vs. escalate to a docs PM. Use when framing a new docs page - or launch, deciding what product stage or audience a feature targets, - or judging whether a docs question needs PM sign-off. + and Shape stages (including cross-repo product lookup via universe when + accessible, else the public OSS path), and helps decide when a docs + question needs to self-serve vs. escalate to a docs PM. Use when framing + a new docs page or launch, deciding what product stage or audience a + feature targets, judging whether a docs question needs PM sign-off, or + confirming which product repos a launch spans. --- # PM the docs @@ -17,17 +19,26 @@ Backs the Frame and Shape stages of the "Write the docs" checklist (mirrored in - Starting a new docs page or launch and need to state the product stage, audience, and "why" before drafting (Frame). - Deciding content type, IA placement, or prerequisites for a page (Shape). +- Judging whether a launch spans multiple product repos (CLI, Auth, migrations, platform, …) — see [reference/universe-lookup.md](reference/universe-lookup.md). - Unsure whether a docs question is self-serve or needs a docs PM's sign-off. -**Not for** drafting content itself (see [`write-the-docs`](../write-the-docs/SKILL.md)), restructuring existing pages (see [`edit-the-docs`](../edit-the-docs/SKILL.md)), or docs-app architecture/IA placement mechanics (see [`ask-the-docs`](../ask-the-docs/SKILL.md)). +**Not for** drafting content itself (see [`write-the-docs`](../write-the-docs/SKILL.md)), restructuring existing pages (see [`edit-the-docs`](../edit-the-docs/SKILL.md)), running snippets (see [`test-the-docs`](../test-the-docs/SKILL.md)), or docs-app architecture/IA placement mechanics (see [`ask-the-docs`](../ask-the-docs/SKILL.md)). + +## Reference files + +| File | What's inside | +| ------------------------------------------------------------------------------ | -------------------------------------------------------------------------- | +| [reference/write-the-docs-checklist.md](reference/write-the-docs-checklist.md) | Six-stage authoring checklist mirror | +| [reference/universe-lookup.md](reference/universe-lookup.md) | Cross-repo product lookup: capability gate, universe accelerator, OSS path | ## Answering a scope/stage/audience question 1. Read the relevant stage in [reference/write-the-docs-checklist.md](reference/write-the-docs-checklist.md) — its checkboxes state exactly what needs deciding. 2. Read whatever context exists for the feature: the linked issue/project, the PRD, the shipped code or PR. When code and PRD disagree, the code wins for behavior claims. -3. Answer the checklist's questions directly: product stage, audience and job-to-be-done, the one-line "why," content type, IA placement, prerequisites. -4. Distinguish **confirmed fact** (stated in the ticket/PRD/code) from **inference** (your best read) — flag inference explicitly rather than presenting it as settled. -5. If a decision is genuinely open at the org level (not a docs authoring call), say so and name who should decide instead of inventing an answer to look complete. +3. When scope may span services (CLI, Auth, migrations, Dashboard, platform, …), follow [reference/universe-lookup.md](reference/universe-lookup.md) **capability gate** before settling Frame/Shape; use universe only if accessible, otherwise the OSS path. Record which repos you searched. +4. Answer the checklist's questions directly: product stage, audience and job-to-be-done, the one-line "why," content type, IA placement, prerequisites. +5. Distinguish **confirmed fact** (stated in the ticket/PRD/code) from **inference** (your best read) — flag inference explicitly rather than presenting it as settled. +6. If a decision is genuinely open at the org level (not a docs authoring call), say so and name who should decide instead of inventing an answer to look complete. ## Self-serve vs. escalate @@ -37,7 +48,8 @@ Escalate to your docs team's PM when scope or stage is unclear, you need a revie ## Related skills -- [`ask-the-docs`](../ask-the-docs/SKILL.md) — IA placement and docs-app architecture (Shape stage) +- [`ask-the-docs`](../ask-the-docs/SKILL.md) — IA placement and docs-app architecture (Shape stage). Cross-repo **product** lookup lives here in `universe-lookup.md`, not in `ask-the-docs`. - [`write-the-docs`](../write-the-docs/SKILL.md) — drafting once Frame/Shape are settled +- [`test-the-docs`](../test-the-docs/SKILL.md) — run snippets against a Docker-isolated local stack; verification report - [`edit-the-docs`](../edit-the-docs/SKILL.md) — restructure and improve existing pages - [`review-the-docs`](../review-the-docs/SKILL.md) — self-review and PR review stages diff --git a/.agents/skills/pm-the-docs/reference/universe-lookup.md b/.agents/skills/pm-the-docs/reference/universe-lookup.md new file mode 100644 index 00000000000..0ee205b50eb --- /dev/null +++ b/.agents/skills/pm-the-docs/reference/universe-lookup.md @@ -0,0 +1,96 @@ +# Cross-repo product lookup + +Cross-repo product search for Frame/Shape when a feature may span services. Use during `/pm-the-docs`, not `/ask-the-docs` (`ask-the-docs` stays on `apps/docs` architecture). + +**Cross-repo confirmation is required for everyone.** [`supabase/universe`](https://github.com/supabase/universe) is an optional accelerator when you have Supabase org access to that private meta-repo (and ideally a local clone). Contributors without that access use the OSS path below — that is a successful outcome, not a failure. + +## Capability gate + +Run this gate before any universe clone or submodule command. + +```mermaid +flowchart TD + start[Cross-repo grounding needed] + clone{"Local universe root exists?"} + ghApi{"gh api repos/supabase/universe succeeds?"} + useUniverse[Use universe clone + rg in repos/] + ossPath[OSS path: public gh search + linked product repos] + start --> clone + clone -->|yes| useUniverse + clone -->|no| ghApi + ghApi -->|yes Supabase org access| useUniverse + ghApi -->|no 404/403| ossPath +``` + +### 1. Local clone? + +Resolve the universe root in order (do not hardcode machine-specific absolute paths in committed files): + +1. `$SUPABASE_UNIVERSE_ROOT` (if set) +2. `$HOME/GitHub/supabase/universe` + +```bash +UNIVERSE_ROOT="${SUPABASE_UNIVERSE_ROOT:-$HOME/GitHub/supabase/universe}" +[[ -d "$UNIVERSE_ROOT/.git" || -f "$UNIVERSE_ROOT/.git" ]] && echo "local universe ok" +``` + +If that checkout exists → **accelerator path** (skip the `gh api` probe). + +### 2. Else probe org access (read-only, no clone) + +```bash +gh api repos/supabase/universe -q .full_name +``` + +| Result | Next step | +| ------ | --------- | +| Success (`supabase/universe`) | Accelerator path: you **may** clone with `--recurse-submodules` (or ask the user to), then search | +| 404, 403, or other failure | **OSS path only** — do **not** run `git clone` or `git submodule update` against universe | + +## OSS path (always valid) + +When the gate says universe is unavailable: + +- Search public code: `gh search code --owner supabase ''` (plus other public owners named in the ticket) +- Read any product repo already checked out or linked from Linear / the PR +- Prefer `supabase/supabase` in-tree sources when that is enough +- In the Frame/Shape summary, record `universe: unavailable (OSS)` and list the public sources used + +Never treat missing universe access as a blocker or an incomplete Frame/Shape. + +## Accelerator: universe (when accessible) + +Prefer an existing local clone. Only init or update submodules after the gate succeeds: + +```bash +cd "$UNIVERSE_ROOT" +git submodule update --init --recursive +``` + +Private submodules (`platform`, `branching`) may need a PAT. If those fail, note the gap and continue with public submodules plus the OSS search path. + +### Where to look + +Start from the universe README "Finding your way around" table, then `rg` inside the relevant submodule: + +| Looking for… | Start in | +| ------------ | -------- | +| Schema, extensions, RLS | `repos/postgres/`, `repos/postgrest/`, `repos/pg-toolbelt/` | +| Auth flows | `repos/auth/`, `auth-js` under `repos/supabase-js/` | +| Realtime / Storage / Edge Functions | `repos/realtime/`, `repos/storage/`, `repos/edge-runtime/` | +| Dashboard / Studio | `repos/supabase/apps/studio` | +| Management API / hosted infra | `repos/platform/` (private) | +| CLI, local dev, `config.toml` | `repos/cli/` | +| Docs & self-hosting Compose | `repos/supabase/` (`apps/docs`, `docker/`) | + +When scope is unknown, search initialized `repos/**` with a tight pattern rather than reading entire trees. + +## How to use in Frame / Shape + +1. Name the product surfaces the launch might touch (CLI, Auth, migrations, Dashboard, …). +2. Run the **capability gate**. +3. Resolve surfaces to repos (universe submodules **or** public search / linked checkouts). +4. Confirm with a short search whether behavior lives in one repo or several. +5. Record in the Frame/Shape summary: gate result (`universe: available` or `universe: unavailable (OSS)`), repos consulted, cross-cutting vs single-repo, and any gaps. + +Always distinguish confirmed fact from inference. diff --git a/.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md b/.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md index 5bffc867c62..afe39dc5a9d 100644 --- a/.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md +++ b/.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md @@ -1,61 +1,71 @@ # Write the docs -> Mirrors Supabase's proposed "Write the docs" process as of 2026-08-10. Process specifics may still evolve. - A practical six-stage checklist and quality standard for planning, drafting, and reviewing product documentation. +**P** = Product +**E** = Engineering +**Docs** = Docs team + +## Authoring + +Six short stages. Keep it lightweight; the point is to make good docs the default, not to add ceremony. + +_Self-serve first ([agent skills](../../../../apps/docs/CONTRIBUTING.md#ai-agent-skills-for-docs-authoring)), ask your docs team's PM as needed._ + ## What good looks like - The **why** is explicit: a reader learns what problem this solves and when to reach for it, not only the steps. -- The **content type is deliberate** and consistent within the page. +- The content **type is deliberate** and consistent within the page. - **Audience and prerequisites** are stated up front. -- At least one **example is runnable and has been run** (commands, code, expected result). -- **Correct stage** is stated; limitations are named honestly. +- **Examples are runnable and have been tested** (commands, code, expected result) — verify with `/test-the-docs` against a Docker-isolated local stack, not production. +- **Correct stage** like GA is stated; limitations are named honestly. - The page **lives in the right place** in the IA and links to and from related pages. -- Terminology and formatting match existing docs (defer to the style guide once one lands). +- Terminology and formatting match existing docs (and style guide once it lands). -## 1. Frame +### 1. Frame -_Skills:_ `ask-the-docs` to see how the surface works today; `pm-the-docs` for audience, stage, and cross-cutting scope calls. +_Skills:_ `/ask-the-docs` for how the docs surface works today; `/pm-the-docs` for audience, stage, and cross-cutting scope (cross-repo span via universe when accessible — see [universe-lookup.md](universe-lookup.md)). - [ ] P: State the product stage (private/public alpha, beta, GA) - [ ] P: Name the audience and the job they are trying to do - [ ] P: Write one line on _why_ the feature exists (the problem it solves), not only what it does -## 2. Shape +### 2. Shape -_Skill:_ `ask-the-docs` for IA placement, architecture, and where content lives. +_Skill:_ `/ask-the-docs` for IA placement, architecture, and where content lives. - [ ] P: Pick the content type(s): tutorial (learning), how-to (a task), reference (lookup), explanation (the why). Do not mix types on one page (refer to [Diátaxis](https://diataxis.fr/)) - [ ] P: Decide where the page lives in the existing IA and what links in and out (avoid orphan pages) - [ ] P: List prerequisites and assumed knowledge up front -## 3. Draft +### 3. Draft -_Skill:_ `write-the-docs` to draft net-new content grounded in Linear and the code. +_Skill:_ `/write-the-docs` to draft net-new content grounded in Linear and the code (`/pm-the-docs` → universe when accessible, else public search / named product repos). - [ ] P: Lead with the why and the outcome, then the how/what (product story first) -- [ ] P: Include at least one runnable, copy-pasteable example that you have actually run +- [ ] P: Include at least one runnable, copy-pasteable example that you have actually run (or will run in Self-review via `/test-the-docs`) +- [ ] P/E: Cross-repo behavior confirmed via universe when accessible, else public `gh search` / named product repos when the feature is not confined to `supabase/supabase` (lookup via `/pm-the-docs`, not `/ask-the-docs`) - [ ] E: Contribute technical depth and verify accuracy (APIs, limits, edge cases) - [ ] P: Call out the current stage inline and any known limitations -When the work is improving an existing page (restructure, reorder, connective text, brevity) rather than authoring net-new content, use `edit-the-docs` instead of `write-the-docs`. +When the work is improving an existing page (restructure, reorder, connective text, brevity) rather than authoring net-new content, use `/edit-the-docs` instead of `/write-the-docs`. -## 4. Self-review against the bar +### 4. Self-review against the bar -_Skill:_ `review-the-docs` — [Local self-review](../../review-the-docs/SKILL.md#local-self-review-no-open-pr) on your own branch before opening the PR. +_Skills:_ `/review-the-docs` for [local self-review](../../review-the-docs/SKILL.md#local-self-review-no-open-pr) before opening the PR; `/test-the-docs` to run snippets and produce a verification report. - [ ] P/E: Check the draft against "What good looks like" above before opening the PR -- [ ] P/E: Follow authoring-experience standards and tooling when available +- [ ] P/E: `/test-the-docs` run; verification report ready for the PR body +- [ ] P/E: Follow Authoring Experience standards and tooling when available -## 5. PR review +### 5. PR review -_Skill:_ `review-the-docs` to triage, classify, verify the build, and report. +_Skill:_ `/review-the-docs` to triage, classify, verify the build, and report. - [ ] P/E: Open the PR and request review per the rules of engagement - [ ] Docs: Review against the published bar -## 6. Keep it honest +### 6. Keep it honest - [ ] P: Keep the product launch checklist's "start on day 1" docs gate honest through ship (update as stage or behavior changes) @@ -63,17 +73,12 @@ _Skill:_ `review-the-docs` to triage, classify, verify the build, and report. **Self-serve when:** the checklist above is clear, standards exist, and you know the product stage and audience. -**Ask when:** scope or stage is unclear, you need a review path, the bar is ambiguous, or the launch docs touch cross-cutting surfaces (quickstarts, API keys, tutorials, onboarding, platform concepts). +**Ask when:** scope or stage is unclear, you need a review path, the bar is ambiguous, or the launch docs touch cross-cutting surfaces (quick starts, API keys, tutorials, onboarding, platform concepts). -**What to expect:** the docs PM is the point of contact for questions and review against the bar. +**What to expect:** the docs PM is the point of contact for questions, skills enablement, and review against the bar. **Where to ping:** your team's PR-review channel and current docs PM — check your contributor guide for who that is today. -## Reference +## Resources -Role prefixes: - -- **P** = Product. The product lead / area PM who writes the docs. -- **E** = Engineering. Contributes technical depth and verifies accuracy. -- **P/E** = Product and Engineering together. -- **Docs** = Docs team, the reviewer. +Skills for this checklist: [AI agent skills for docs authoring](../../../../apps/docs/CONTRIBUTING.md#ai-agent-skills-for-docs-authoring) (`/pm-the-docs`, `/ask-the-docs`, `/write-the-docs`, `/edit-the-docs`, `/test-the-docs`, `/review-the-docs`). diff --git a/.agents/skills/review-the-docs/SKILL.md b/.agents/skills/review-the-docs/SKILL.md index 2b42ac33c50..0316e3fc613 100644 --- a/.agents/skills/review-the-docs/SKILL.md +++ b/.agents/skills/review-the-docs/SKILL.md @@ -69,7 +69,8 @@ pnpm build:reference-markdown # when reference pipeline changed ``` 4. Spot-check frontmatter, internal links, and nav wiring for content changes. -5. Write a short **self-review note** (blockers vs nits) suitable to paste into the future PR body under a "Self-review" heading. +5. **Offer runnable verification** — for content/tutorial PRs with new or changed procedural fenced blocks, ask whether to run [`test-the-docs`](../test-the-docs/SKILL.md). Prerequisites are class-specific (Docker Compose stack profile for DB/API; examples profile for `example-app`). If accepted, include the verification report; if declined or a required prerequisite for that class is missing, record credible `deferred` reasons for those artifacts only. Do not reimplement sandbox execution here. +6. Write a short **self-review note** (blockers vs nits) suitable to paste into the future PR body under a "Self-review" heading. Then open the PR and continue with open-PR review if a second pass is needed. @@ -216,6 +217,7 @@ Checklist: - [ ] `$CodeSample` paths match existing example directories - [ ] Admonitions, tabs, and partial includes render sensibly in PR preview - [ ] No accidental whitespace-only or empty sections where components were removed +- [ ] Offered [`test-the-docs`](../test-the-docs/SKILL.md) for new/changed procedural snippets; verification report present or credible `deferred` reasons recorded Compare PR preview URL (from Vercel/deployment comment) against production for visual regressions when layout components are involved. @@ -239,6 +241,7 @@ Checklist: - [ ] MDX steps match example code after `pnpm codegen:examples` (if `$CodeSample` used) - [ ] Env var names and Supabase client setup match current `@supabase/ssr` patterns - [ ] Example pins catalog versions — no `"latest"` for in-repo packages +- [ ] Offered [`test-the-docs`](../test-the-docs/SKILL.md) for procedural tutorial steps (or `deferred` with reason) - [ ] **Platform E2E** (when auth involved): SQL migration applied, auth flow walked, profiles verified — see `work-linear-issue` Phase 3 --- diff --git a/.agents/skills/test-the-docs/SKILL.md b/.agents/skills/test-the-docs/SKILL.md new file mode 100644 index 00000000000..1261958ff95 --- /dev/null +++ b/.agents/skills/test-the-docs/SKILL.md @@ -0,0 +1,96 @@ +--- +name: test-the-docs +description: >- + Execute runnable docs snippets and examples inside a disposable Docker Compose + sandbox (runner container + local Supabase stack via `supabase start`). Use + after Draft or during Self-review when asked to test the docs, fact-check + CLI/SQL/code samples, or produce a verification report for a docs PR. + Complements review-the-docs lint/build checks; does not replace them. +--- + +# Test the docs + +Runs procedural docs content **inside disposable containers**, not on the host shell and not against production. Produces a verification report for the PR body / self-review note. + +For lint, markdown rebuilds, example-app triage, and PR review, use [`review-the-docs`](../review-the-docs/SKILL.md). For Frame/Shape and cross-repo product lookup, use [`pm-the-docs`](../pm-the-docs/SKILL.md). + +## When to invoke + +- After Draft, before or during Self-review (checklist Stage 4). +- Standalone: "test the docs", "fact-check these snippets", "run the examples". +- Content or tutorial PRs that add or change procedural fenced blocks. + +**Not for:** generated reference pages, docs-app architecture questions, or hosted/production projects. + +## Core rules + +1. **Never run against production.** Local stack or temp dir only. +2. **Never run MDX fences on the host shell.** Use the Compose sandbox — see [reference/sandbox-setup.md](reference/sandbox-setup.md) and [`sandbox/run.sh`](sandbox/run.sh). +3. **Proportional:** Tier A (one end-to-end path) is required; Tier B spot-checks new/changed procedural blocks, not every fence on every page. +4. **Product bugs** found while testing get linked or filed separately; fix docs only when the docs are wrong. + +## Phases + +### 1. Scope + +From explicit MDX paths, or: + +```bash +git diff --name-only master...HEAD -- 'apps/docs/content/**' +``` + +Skip generated reference output under `features/docs/generated/`. + +### 2. Extract + +List runnable artifacts from changed MDX: + +- Fenced blocks: `bash`, `sh`, `sql`, `javascript`, `typescript`, `tsx`, `jsx` +- `$CodeSample` paths → treat as `example-app` (build under `examples/`) +- Skip: `mermaid`, incomplete illustrative fragments, partial-only includes + +### 3. Classify + +Assign each artifact a class per [reference/snippet-classes.md](reference/snippet-classes.md): + +| Class | Action | +| --------------------- | ---------------------------------------------- | +| `runnable-local` | Run in temp stack / temp dir | +| `runnable-with-setup` | Run after documented setup (migrations, seed) | +| `example-app` | `npm install && npm run build` in `examples/…` | +| `illustrative-only` | No run required | +| `deferred` | Record reason; do not silently skip | + +### 4. Sandbox setup + +Follow [reference/sandbox-setup.md](reference/sandbox-setup.md) and drive lifecycle with [`sandbox/run.sh`](sandbox/run.sh): + +1. Refuse if the **host** is running as root. +2. Require `docker` + `docker info` + `docker compose` on the host for any in-container run. +3. Gate profiles **per artifact class**: + - `runnable-local` / `runnable-with-setup` that need DB/API: `./sandbox/run.sh up-stack` (DinD + runner → `supabase init` / `supabase start` in `/work`). + - CLI-only blocks with no DB: still use a runner profile so fences stay off-host; skip `supabase start` when unused. + - `example-app`: `TTD_EXAMPLE_DIR=/examples/ ./sandbox/run.sh up-examples` (Node in runner; **no** DinD). Do **not** defer solely because the host lacks a global Supabase CLI. +4. Always `./sandbox/run.sh down` when finished (cleanup trap on the host session). +5. Capture connection **URLs only** inside the runner; never paste credential fields into notes or logs. + +If a **required** prerequisite for that artifact is unavailable, mark that artifact `deferred` with the specific reason — never silent skip, and do not defer unrelated classes. + +### 5. Execute + +- **Tier A:** one copy-pasteable end-to-end path from the page. +- **Tier B:** each new/changed block classified `runnable-*` **or** `example-app` (build and record the result). +- Run every fence via `./sandbox/run.sh exec` or `exec-timeout` (never a bare host shell). +- Bound every artifact: default **60s** for shell / SQL / JS / TypeScript / `tsx` / `jsx`; allow longer for `example-app` install/build (e.g. **5m**). On timeout, kill the process **group** inside the runner, then record `fail` or `deferred` with reason. +- `curl` / `wget` only to filtered stack URLs (or page-documented local endpoints). `npm` / `npx` / `node` only for mounted `example-app` builds. +- Capture exit code, stdout/stderr (redact secrets), and observed vs expected behavior. + +### 6. Report + +Write a verification report per [reference/verification-report.md](reference/verification-report.md) for the PR body / self-review note. + +## Related skills + +- [`write-the-docs`](../write-the-docs/SKILL.md) — Draft; hands off here before PR +- [`review-the-docs`](../review-the-docs/SKILL.md) — lint/build/classify; consumes verification report +- [`pm-the-docs`](../pm-the-docs/SKILL.md) — Frame/Shape; universe for cross-repo product lookup diff --git a/.agents/skills/test-the-docs/reference/sandbox-setup.md b/.agents/skills/test-the-docs/reference/sandbox-setup.md new file mode 100644 index 00000000000..647d9840076 --- /dev/null +++ b/.agents/skills/test-the-docs/reference/sandbox-setup.md @@ -0,0 +1,83 @@ +# Sandbox setup + +Containerized local execution for `/test-the-docs`. The **host** only starts Docker Compose and tears it down. Every MDX fence (shell, SQL, JS/TS, example-app builds) runs **inside** the disposable `runner` container — never as a host shell. + +Assets live in [`../sandbox/`](../sandbox/): `compose.yaml`, `Dockerfile`, `run.sh`. + +## Threat model and guardrails + +| Layer | What it does | +| ---------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| Host | `docker compose` lifecycle only (`run.sh up-*` / `down`). No fence execution. | +| Runner container | Executes fences as non-root `runner` (uid 1001). No `$HOME` mount. Work dir is `/work`; optional read-only `/examples`. | +| DinD (`stack` profile) | Privileged `docker:dind` runs an isolated Docker daemon. `supabase start` creates stack containers **inside DinD**. The runner shares DinD’s network namespace (`network_mode: service:dind`) so `127.0.0.1` healthchecks and client URLs work. Residual risk: privileged DinD; mitigate with ephemeral project names and `run.sh down`. | +| Examples profile | No DinD and no docker.sock — Node-only builds. | + +This skill is for docs authors and reviewers verifying intended content. It is not unattended CI over arbitrary hostile input. + +Guardrails: + +- **Fences in-container only.** Never run MDX fences on the host shell. Use `./sandbox/run.sh exec` or `exec-timeout`. +- **Local stack only.** Reject snippets that target hosted or production Supabase projects. +- **No secrets in notes.** Never paste `PUBLISHABLE_KEY`, `SECRET_KEY`, `JWT_SECRET`, `ANON_KEY`, `SERVICE_ROLE_KEY`, `S3_PROTOCOL_ACCESS_KEY_ID`, `S3_PROTOCOL_ACCESS_KEY_SECRET`, or other keys into the verification report, PR body, or chat logs. Capture **URLs only** from `supabase status -o env`. +- **`curl` / `wget`.** Only to URLs from the filtered status capture (`API_URL`, `DB_URL`, `DATABASE_URL`), or to local endpoints the page under test documents. Mark other targets `deferred`. +- **`npm` / `npx` / `node`.** Only for `example-app` artifacts. Mount the app read-only at `/examples`, copy into `/work/example`, then `npm install && npm run build` (or the page’s documented build). Arbitrary `node -e`, remote `npx`, or Node from unrelated bash fences → `deferred`. +- **Prefer page commands.** Run documented steps from the MDX under test. +- **Fail closed** when Docker/Compose prerequisites for that artifact class are missing (see skill Phase 4). + +## Host prerequisites (fail closed) + +```bash +if [[ "$(id -u)" = "0" ]]; then + echo "error: refuse to run as root" >&2 + exit 1 +fi +command -v docker >/dev/null || { echo "error: docker not found" >&2; exit 1; } +docker info >/dev/null 2>&1 || { echo "error: Docker is not running" >&2; exit 1; } +docker compose version >/dev/null || { echo "error: docker compose not available" >&2; exit 1; } +``` + +The host does **not** need a global `supabase` CLI or Node for stack/example runs; those tools live in the runner image. If Docker/Compose is unavailable, mark artifacts that need the runner `deferred`. + +`run.sh` creates temp work/output dirs world-writable (`chmod 0777`) so the non-root runner (`uid 1001`) can write into the host bind mounts. + +## Lifecycle (`run.sh`) + +From `.agents/skills/test-the-docs/sandbox/`: + +```bash +# Optional: pin dirs / project name for the session +eval "$(./run.sh env)" + +# Stack profile: DinD + runner → supabase init/start inside /work +./run.sh up-stack + +# Capture URLs only inside the runner (never log credential fields) +./run.sh exec -- bash -lc ' + eval "$(supabase status -o env | grep -E "^(API_URL|DB_URL|DATABASE_URL)=")" + echo "API_URL is set (value omitted from logs)" +' + +# Run a fence with a deadline (process group killed on timeout) +./run.sh exec-timeout 60 -- bash -lc 'eval "$(supabase status -o env | grep -E "^(API_URL|DB_URL|DATABASE_URL)=")"; psql "$DB_URL" -c "select 1"' + +# Examples profile (no DinD): mount the app, then build +TTD_EXAMPLE_DIR=/path/to/repo/examples/auth/hono ./run.sh up-examples +./run.sh exec-timeout 300 -- bash -lc 'cd /work/example && npm install && npm run build' + +# Always tear down +./run.sh down +``` + +## Profiles + +| Profile | Services | Isolation | Use when | +| ---------- | ----------------------- | -------------------------------- | --------------------------------------------- | +| `stack` | `dind` + `runner-stack` | Privileged DinD; fences off-host | SQL, CLI, client calls against local Supabase | +| `examples` | `runner` | No Docker daemon in-sandbox | `example-app` install/build only | + +Do not start the stack unless the artifact needs it. + +## Teardown + +Always `./run.sh down` (stops `supabase` project containers when possible, `compose down -v`, removes temp work/output dirs). Leave Docker Desktop running for the next session. diff --git a/.agents/skills/test-the-docs/reference/snippet-classes.md b/.agents/skills/test-the-docs/reference/snippet-classes.md new file mode 100644 index 00000000000..5823c9e9988 --- /dev/null +++ b/.agents/skills/test-the-docs/reference/snippet-classes.md @@ -0,0 +1,28 @@ +# Snippet classes + +Classify each extracted artifact before running it. + +| Class | Meaning | Run? | +| --------------------- | -------------------------------------------------------------------------------- | -------------------------------------- | +| `runnable-local` | Complete CLI, SQL, or script that works against a local stack or temp dir | Yes | +| `runnable-with-setup` | Needs migrations, seed data, `.env`, or prior steps from the same page | Yes, after setup | +| `example-app` | `$CodeSample` or path under `examples/` | Build (`npm install && npm run build`) | +| `illustrative-only` | Incomplete on purpose, omits required context, or is conceptual | No | +| `deferred` | Needs production, paid feature, destructive op, or missing required prerequisite | No — record reason | + +## Safety + +- Prefer read-only SQL and non-destructive CLI flags. +- Never target a linked hosted/production project from this skill. +- Do not print secrets (service role keys, PATs) into Verification notes or logs. +- Mark incomplete copy-paste blocks `illustrative-only` rather than forcing a run that cannot succeed. +- Execute fences only inside the Compose runner per [sandbox-setup.md](sandbox-setup.md). Restrict `curl`/`wget` to filtered stack URLs; restrict `npm`/`npx`/`node` to `example-app` mounts. Mark out-of-policy fences `deferred`. + +## Language heuristics + +| Fence | Typical class | +| ------------------------------------------- | --------------------------------------------------------------------------- | +| `sql` | `runnable-local` or `runnable-with-setup` if ordered migrations | +| `bash` / `sh` | `runnable-local` if self-contained; else `deferred` / `illustrative-only` | +| `javascript` / `typescript` / `tsx` / `jsx` | Often `illustrative-only` unless a full runnable script or example-app path | +| `mermaid` | Skip (not executable) | diff --git a/.agents/skills/test-the-docs/reference/verification-report.md b/.agents/skills/test-the-docs/reference/verification-report.md new file mode 100644 index 00000000000..0d19fd32093 --- /dev/null +++ b/.agents/skills/test-the-docs/reference/verification-report.md @@ -0,0 +1,38 @@ +# Verification report + +Paste into the PR body or self-review note under a **Verification** heading. + +## Template + +```markdown +## Verification (`/test-the-docs`) + +| Snippet / step | Class | Sandbox | Result | Notes | +| ----------------------------- | -------------- | --------------------------------- | -------- | ------------------------ | +| e.g. `create type …` SQL | runnable-local | Compose runner + `supabase start` | pass | | +| e.g. `supabase db diff` | runnable-local | Compose runner + local stack | fail | product bug → link issue | +| e.g. paid Dashboard-only step | deferred | — | deferred | needs hosted project | + +**Tier A path:** + +**Environment:** Docker Desktop ; compose sandbox (`sandbox/run.sh`); fences in-container only +``` + +Do **not** put secrets (`JWT_SECRET`, `ANON_KEY`, `SERVICE_ROLE_KEY`, access tokens) in Notes or Environment. + +## Results + +| Result | Meaning | +| ---------- | -------------------------------------------------------------------- | +| `pass` | Command exited 0 and matched expected behavior | +| `fail` | Ran but wrong output / non-zero exit — docs wrong **or** product bug | +| `deferred` | Not run; reason required in Notes | +| `skipped` | Out of scope (`illustrative-only`) | + +## Product bugs + +If the snippet matches the code and still fails: + +1. Prefer linking an existing issue in the owning repo. +2. Otherwise note the repro in the PR and file/follow up with the product owner. +3. Do not "fix" the docs to hide a real platform bug without calling it out. diff --git a/.agents/skills/test-the-docs/sandbox/.empty/.keep b/.agents/skills/test-the-docs/sandbox/.empty/.keep new file mode 100644 index 00000000000..9c664e38e37 --- /dev/null +++ b/.agents/skills/test-the-docs/sandbox/.empty/.keep @@ -0,0 +1 @@ +# Keep empty bind-mount target for compose when no example is mounted. diff --git a/.agents/skills/test-the-docs/sandbox/.gitignore b/.agents/skills/test-the-docs/sandbox/.gitignore new file mode 100644 index 00000000000..6d9a510bfea --- /dev/null +++ b/.agents/skills/test-the-docs/sandbox/.gitignore @@ -0,0 +1,2 @@ +.state/ +!.empty/.keep diff --git a/.agents/skills/test-the-docs/sandbox/Dockerfile b/.agents/skills/test-the-docs/sandbox/Dockerfile new file mode 100644 index 00000000000..87e003adaa0 --- /dev/null +++ b/.agents/skills/test-the-docs/sandbox/Dockerfile @@ -0,0 +1,34 @@ +# Runner for /test-the-docs: executes MDX fences inside the container. +FROM node:22-bookworm-slim + +ARG TARGETARCH +ARG SUPABASE_CLI_VERSION=2.39.2 + +RUN apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + curl \ + postgresql-client \ + && rm -rf /var/lib/apt/lists/* + +# Docker CLI only (daemon is DinD over TCP for stack profile) +COPY --from=docker:27-cli /usr/local/bin/docker /usr/local/bin/docker + +RUN set -eux; \ + arch="${TARGETARCH}"; \ + case "${arch}" in \ + amd64) cli_arch=amd64 ;; \ + arm64) cli_arch=arm64 ;; \ + *) cli_arch=amd64 ;; \ + esac; \ + curl -fsSL "https://github.com/supabase/cli/releases/download/v${SUPABASE_CLI_VERSION}/supabase_linux_${cli_arch}.tar.gz" \ + | tar -xz -C /usr/local/bin supabase; \ + chmod +x /usr/local/bin/supabase; \ + supabase --version + +RUN useradd --create-home --uid 1001 --shell /bin/bash runner \ + && mkdir -p /work /output /examples \ + && chown -R runner:runner /work /output /examples + +USER runner +WORKDIR /work +CMD ["bash"] diff --git a/.agents/skills/test-the-docs/sandbox/compose.yaml b/.agents/skills/test-the-docs/sandbox/compose.yaml new file mode 100644 index 00000000000..00d24f3b73c --- /dev/null +++ b/.agents/skills/test-the-docs/sandbox/compose.yaml @@ -0,0 +1,81 @@ +# Disposable compose project for /test-the-docs. +# Host only starts/stops this project; MDX fences run inside the runner. +# +# Profiles: +# stack — privileged DinD + runner sharing DinD network (supabase start uses 127.0.0.1) +# examples — runner only; copies /examples into /work/example for npm install (no DinD) + +services: + dind: + image: docker:27-dind + privileged: true + environment: + DOCKER_TLS_CERTDIR: '' + command: ['dockerd', '--host=tcp://0.0.0.0:2375', '--host=unix:///var/run/docker.sock'] + healthcheck: + test: ['CMD', 'docker', 'info'] + interval: 2s + timeout: 5s + retries: 30 + start_period: 5s + profiles: + - stack + + runner: + build: + context: . + dockerfile: Dockerfile + working_dir: /work + user: '1001:1001' + environment: + TTD_IN_CONTAINER: '1' + command: ['sleep', 'infinity'] + volumes: + - type: bind + source: ${TTD_WORK_DIR:?set TTD_WORK_DIR} + target: /work + - type: bind + source: ${TTD_OUTPUT_DIR:?set TTD_OUTPUT_DIR} + target: /output + - type: bind + source: ${TTD_EXAMPLE_DIR:-./.empty} + target: /examples + read_only: true + networks: + - ttd + profiles: + - examples + + runner-stack: + build: + context: . + dockerfile: Dockerfile + working_dir: /work + user: '1001:1001' + # Share DinD's network namespace so supabase healthchecks on 127.0.0.1 succeed + network_mode: 'service:dind' + environment: + TTD_IN_CONTAINER: '1' + DOCKER_HOST: tcp://127.0.0.1:2375 + command: ['sleep', 'infinity'] + volumes: + - type: bind + source: ${TTD_WORK_DIR:?set TTD_WORK_DIR} + target: /work + - type: bind + source: ${TTD_OUTPUT_DIR:?set TTD_OUTPUT_DIR} + target: /output + - type: bind + source: ${TTD_EXAMPLE_DIR:-./.empty} + target: /examples + read_only: true + depends_on: + dind: + condition: service_healthy + profiles: + - stack + +networks: + ttd: + driver: bridge + name: ${TTD_NETWORK_NAME:-ttd-sandbox} diff --git a/.agents/skills/test-the-docs/sandbox/run.sh b/.agents/skills/test-the-docs/sandbox/run.sh new file mode 100755 index 00000000000..85fd7c235cb --- /dev/null +++ b/.agents/skills/test-the-docs/sandbox/run.sh @@ -0,0 +1,189 @@ +#!/usr/bin/env bash +# Host-side lifecycle for /test-the-docs sandbox. +# Starts a disposable compose project and execs fences inside the runner container. +# Usage: +# eval "$(./run.sh env)" # export TTD_* for the session +# ./run.sh up-stack # DinD + runner; supabase init/start in /work +# ./run.sh up-examples # runner only (no DinD); example-app builds in /work/example +# ./run.sh exec -- # run a command in the active runner +# ./run.sh exec-timeout 60 -- +# ./run.sh down # compose down -v and remove work/output dirs created by this script +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +COMPOSE_FILE="${SCRIPT_DIR}/compose.yaml" + +die() { + echo "error: $*" >&2 + exit 1 +} + +require_host_prereqs() { + if [[ "$(id -u)" = "0" ]]; then + die "refuse to run as root on the host" + fi + command -v docker >/dev/null || die "docker not found — install Docker Desktop" + docker info >/dev/null 2>&1 || die "Docker is not running — start Docker Desktop" + docker compose version >/dev/null 2>&1 || die "docker compose not available" +} + +compose() { + docker compose -p "${TTD_PROJECT_NAME}" -f "${COMPOSE_FILE}" "$@" +} + +runner_service() { + case "${TTD_PROFILE:-}" in + stack) echo runner-stack ;; + examples) echo runner ;; + *) die "TTD_PROFILE unset; run up-stack or up-examples first" ;; + esac +} + +ensure_state_dir() { + mkdir -p "${SCRIPT_DIR}/.state" +} + +write_env_file() { + ensure_state_dir + cat >"${SCRIPT_DIR}/.state/current.env" </dev/null 2>&1; then + break + fi + sleep 1 + done + docker info >/dev/null + cd /work + if [[ ! -f supabase/config.toml ]]; then + printf 'n\nn\n' | supabase init + fi + supabase start + ' + echo "sandbox ready: project=${TTD_PROJECT_NAME} work=${TTD_WORK_DIR} profile=stack (DinD)" >&2 +} + +cmd_up_examples() { + prepare_exports + export TTD_PROFILE=examples + write_env_file + compose --profile examples build runner + compose --profile examples up -d --remove-orphans runner + # Copy read-only mount into writable /work so npm can install without mutating the repo + compose --profile examples exec -T runner \ + bash -lc 'rm -rf /work/example && mkdir -p /work/example && cp -a /examples/. /work/example/' + echo "sandbox ready: project=${TTD_PROJECT_NAME} work=${TTD_WORK_DIR} profile=examples (build in /work/example)" >&2 +} + +cmd_exec() { + load_env_file + local svc + svc="$(runner_service)" + compose --profile "${TTD_PROFILE}" exec -T "${svc}" "$@" +} + +cmd_exec_timeout() { + load_env_file + local secs="$1" + shift + if [[ "${1:-}" == "--" ]]; then + shift + fi + local svc + svc="$(runner_service)" + compose --profile "${TTD_PROFILE}" exec -T "${svc}" \ + timeout --foreground --signal=TERM --kill-after=5s "${secs}s" "$@" +} + +cmd_down() { + if [[ -f "${SCRIPT_DIR}/.state/current.env" ]]; then + # shellcheck disable=SC1091 + source "${SCRIPT_DIR}/.state/current.env" + else + die "no active sandbox state" + fi + if [[ "${TTD_PROFILE:-}" == "stack" ]]; then + compose --profile stack exec -T runner-stack bash -lc 'cd /work && supabase stop 2>/dev/null || true' 2>/dev/null || true + fi + compose --profile "${TTD_PROFILE:-stack}" down -v --remove-orphans 2>/dev/null || true + rm -rf "${TTD_WORK_DIR:-}" "${TTD_OUTPUT_DIR:-}" 2>/dev/null || true + rm -f "${SCRIPT_DIR}/.state/current.env" + echo "sandbox torn down: ${TTD_PROJECT_NAME:-unknown}" >&2 +} + +usage() { + sed -n '2,10p' "$0" | sed 's/^# //; s/^#//' +} + +main() { + local cmd="${1:-}" + shift || true + case "${cmd}" in + env) cmd_env "$@" ;; + up-stack) cmd_up_stack "$@" ;; + up-examples) cmd_up_examples "$@" ;; + exec) + if [[ "${1:-}" == "--" ]]; then shift; fi + cmd_exec "$@" + ;; + exec-timeout) cmd_exec_timeout "$@" ;; + down) cmd_down "$@" ;; + -h | --help | help | "") usage ;; + *) die "unknown command: ${cmd}" ;; + esac +} + +main "$@" diff --git a/.agents/skills/write-the-docs/SKILL.md b/.agents/skills/write-the-docs/SKILL.md index 8380bd4c03e..80b892e4fee 100644 --- a/.agents/skills/write-the-docs/SKILL.md +++ b/.agents/skills/write-the-docs/SKILL.md @@ -28,7 +28,7 @@ Four inputs, read in this sequence (sequence, not priority; Linear remains the p 1. **Style guide — voice/terminology reference.** Start with [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) and [`apps/docs/WORD_LIST.md`](../../../apps/docs/WORD_LIST.md) for voice, structure, and terminology. If those don't cover the case, fall back to the nearest comparable existing page under `apps/docs/content/` and say explicitly: _"no dedicated style guide yet — following the precedent of ``."_ See [reference/style-fallback.md](reference/style-fallback.md). 2. **Linear — the ticket and its product context.** Linear is an internal Supabase tool: preferred when available, not required for open-source contributors. When a Linear issue is available, pull it, then its parent project/initiative description too (PRD, PRFAQ, RFC, or initiative narrative) and any PM comments. Product framing/positioning language usually lives one level up from the ticket, in the parent project or initiative description rather than the ticket body. Distinguish scope the ticket actually commits to from aspirational language in the PRD. If there is no Linear issue and no prior Frame/Shape product-intent output, stop drafting: ask internal authors for a Linear URL, otherwise hand off to [`pm-the-docs`](../pm-the-docs/SKILL.md) (Frame) and [`ask-the-docs`](../ask-the-docs/SKILL.md) when Shape/IA is unsettled. Resume only after product intent exists — never invent positioning, and never run Frame/Shape inside this Draft skill. -3. **Code.** Read the actual implementation before writing a single behavior claim — the PRD describes intent, the code describes what shipped. Check the Linear issue/project first for a linked `supabase/supabase` PR — its diff and description are the most precise "what actually shipped" source, more precise than a general codebase read. If no PR is linked, locate the feature directly in `supabase/supabase` (or the product's own repo), and apply [`ask-the-docs`](../ask-the-docs/SKILL.md)'s reuse/minimalism lens: understand what exists before describing it. If code and PRD disagree, the code wins for behavior claims — flag the mismatch rather than silently picking one. +3. **Code.** Read the actual implementation before writing a single behavior claim — the PRD describes intent, the code describes what shipped. Check the Linear issue/project first for a linked `supabase/supabase` PR — its diff and description are the most precise "what actually shipped" source, more precise than a general codebase read. If no PR is linked, locate the feature directly in `supabase/supabase` (or the product's own repo), and apply [`ask-the-docs`](../ask-the-docs/SKILL.md)'s reuse/minimalism lens: understand what exists before describing it. When behavior spans services (CLI, Auth, migrations, platform, …), follow [`pm-the-docs`](../pm-the-docs/SKILL.md) → [universe-lookup](../pm-the-docs/reference/universe-lookup.md) **capability gate** (universe when accessible, else OSS public search / linked repos — not `ask-the-docs`). If code and PRD disagree, the code wins for behavior claims — flag the mismatch rather than silently picking one. 4. **Whatever else the author supplies.** Screenshots, example projects, related pages, Slack threads, a specific voice sample. Screenshots are for more than general context — use them to verify the _exact_ button/menu/field labels before writing instructional steps that reference them; a mismatched UI label is one of the easiest, most avoidable errors in a draft. Ask for these when the feature's user-facing shape is still unclear after 1–3, rather than guessing. Summarize all four back to the requester before drafting: what's confirmed, what's product intent vs. shipped behavior, what's still a gap. Stop and ask if a real gap would change the draft's structure or scope. @@ -67,6 +67,7 @@ Before handing off, confirm: - [ ] Content type confirmed as Guide/Troubleshooting (not something that belongs in generated Reference instead) - [ ] Nav placement and nav enablement both wired, not just the placement - [ ] Internal links resolve; first-use of new terms/acronyms is defined +- [ ] If the draft has procedural snippets (CLI, SQL, client code, or example apps), **offered** to run [`test-the-docs`](../test-the-docs/SKILL.md) (optional; Docker Compose sandbox — stack profile for DB/API, examples profile for `example-app`) - [ ] Future promises minimized where possible (timeless documentation principle) - [ ] No unnecessary redundancy (same point restated multiple ways) - [ ] Single-item lists avoided unless there's a specific reason @@ -86,6 +87,8 @@ Re-read [`apps/docs/CONTRIBUTING.md`](../../../apps/docs/CONTRIBUTING.md) and [` This skill stops at a reviewable draft. It does not open worktrees or PRs itself: +- **Offer** [`test-the-docs`](../test-the-docs/SKILL.md) when the draft includes runnable procedural snippets. Ask before starting verification. Gate prerequisites **per artifact class** (Docker Compose stack profile for DB/API artifacts; examples profile / Node in-runner for `example-app`). If declined, or a required prerequisite for that class is missing, record `deferred` for those artifacts only and continue. When accepted, attach the verification report to the PR body / self-review note. +- Then run [`review-the-docs`](../review-the-docs/SKILL.md) local self-review (lint/build/classify). - Hand off to [`create-pull-request`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/create-pull-request/SKILL.md) (and [`work-linear-issue`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/work-linear-issue/SKILL.md) if the ticket needs a full worktree+PR flow) for the actual PR mechanics. Carry the Phase 1/2 flagged-assumptions list forward explicitly into that handoff — it belongs in the PR description (e.g. a "needs review" section) so a reviewer sees it, not just as an inline comment buried in the draft. - If the feature is UI-driven and the PR will need screenshots/GIFs, flag [`proof-it-works`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/proof-it-works/SKILL.md) as the next step rather than capturing evidence here. - Before opening the PR, run [`review-the-docs`](../review-the-docs/SKILL.md) local self-review: `pnpm lint:mdx`, `pnpm build:guides-markdown` where applicable, and anchor checks per [reference/drafting-mechanics.md](reference/drafting-mechanics.md). @@ -98,6 +101,8 @@ This skill stops at a reviewable draft. It does not open worktrees or PRs itself - Content-type gate detail: [reference/content-type-gate.md](reference/content-type-gate.md) - Existing-page restructure/clarity: [`edit-the-docs`](../edit-the-docs/SKILL.md) - "Write the docs" checklist (Draft stage): [`pm-the-docs`](../pm-the-docs/SKILL.md)'s [reference/write-the-docs-checklist.md](../pm-the-docs/reference/write-the-docs-checklist.md) +- Cross-repo product lookup: [`pm-the-docs`](../pm-the-docs/SKILL.md) → [universe-lookup](../pm-the-docs/reference/universe-lookup.md) +- Runnable verification: [`test-the-docs`](../test-the-docs/SKILL.md) - Docs-app architecture/placement: [`ask-the-docs`](../ask-the-docs/SKILL.md), [`audit-docs-ia`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/audit-docs-ia/SKILL.md) - PR mechanics: [`create-pull-request`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/create-pull-request/SKILL.md), [`work-linear-issue`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/work-linear-issue/SKILL.md) - Screenshots/proof: [`proof-it-works`](https://github.com/supabase/docs-agent-skills/blob/main/.claude/skills/proof-it-works/SKILL.md) diff --git a/apps/docs/CONTRIBUTING.md b/apps/docs/CONTRIBUTING.md index 42e465763e6..8ad5a85dd76 100644 --- a/apps/docs/CONTRIBUTING.md +++ b/apps/docs/CONTRIBUTING.md @@ -23,14 +23,15 @@ To make docs as clear as possible: If you're using an AI coding agent (Claude Code, Codex, or anything else that reads `.agents/skills/`), this repo ships skills that back the [Write the docs](../../.agents/skills/pm-the-docs/reference/write-the-docs-checklist.md) authoring checklist. -Ask your agent for a skill by name (`write-the-docs`, `edit-the-docs`, `ask-the-docs`, `pm-the-docs`, `review-the-docs`); in Claude Code these are also available as `/name` slash commands. +Ask your agent for a skill by name (`pm-the-docs`, `ask-the-docs`, `write-the-docs`, `edit-the-docs`, `test-the-docs`, `review-the-docs`); in Claude Code these are also available as `/name` slash commands. | Skill | Checklist stage | Use for | | --- | --- | --- | -| [`pm-the-docs`](../../.agents/skills/pm-the-docs/SKILL.md) | Frame / Shape | Audience, product-stage, and cross-cutting scope calls | +| [`pm-the-docs`](../../.agents/skills/pm-the-docs/SKILL.md) | Frame / Shape | Audience, product-stage, and cross-cutting scope calls (universe when you have Supabase org access, else OSS path) | | [`ask-the-docs`](../../.agents/skills/ask-the-docs/SKILL.md) | Frame / Shape | `apps/docs` architecture, IA placement, and where content lives | | [`write-the-docs`](../../.agents/skills/write-the-docs/SKILL.md) | Draft | Drafting net-new content grounded in the code | | [`edit-the-docs`](../../.agents/skills/edit-the-docs/SKILL.md) | Edit | Restructure and improve existing pages | +| [`test-the-docs`](../../.agents/skills/test-the-docs/SKILL.md) | Draft / Self-review | Execute docs snippets in a Docker-isolated local stack; verification report | | [`review-the-docs`](../../.agents/skills/review-the-docs/SKILL.md) | Self-review / PR review | Checking a draft and PR triage/verification | The canonical files live in `.agents/skills/`; `.claude/skills` is a Git symlink to that directory so Claude Code discovers them too.