Skip to content

Commit 045a80b

Browse files
prrao87claude
andauthored
Add docs-writer skill for agents (Claude Code + Codex) (#221)
* Add docs-snippet skill documenting the test-to-MDX pipeline Captures the repo-specific conventions that would otherwise have to be reverse-engineered from scripts/mdx_snippets_gen.py: the --8<-- marker syntax, test file stem to snippets module mapping, Py/Ts/Rs export name formula, make snippets regen flow, MDX import pattern with /snippets/ absolute paths, CodeGroup rendering per language, and the convention of verifying new API surface against ../lancedb before documenting it. Placed at /skills/ rather than /.claude/skills/ so Codex and other agents can use it alongside Claude Code. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Generalize API cross-check section to honor user-specified source repos When the user names a repo ("check in the sophon repo", "verify against lancedb", "reference the geneva repo"), that repo is the source of truth for the docs change. The skill now specifies: - Resolution order (sibling of docs/ → anywhere under ~/code → ask user) - Cite file + line so the check is auditable - If the repo and docs disagree, the repo wins - Mandatory behavior: ignoring the user's named repo is a mistake - Retains the general habit of cross-checking proactively even when no repo is explicitly named Also expands the skill's frontmatter description so this trigger fires on "cross-check", "verify against", "reference the X repo" phrasings. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Rename skill from docs-snippet to docs-writer Broader name reflects the skill's full scope (snippet pipeline + MDX rendering + source-repo cross-checking), not just snippet plumbing. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Tighten docs-writer skill description Focus on the primary purpose: writing Mintlify docs with test-backed code snippets. Keep the cross-repo verification trigger as a secondary clause. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> * Add pre-PR checklist reminding to run make snippets before commit Ensures the regenerated docs/snippets/*.mdx files land in the same PR as the test changes that produced them, so reviewers don't see a stale snippets tree and CI doesn't flag a drift. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 9dd9319 commit 045a80b

1 file changed

Lines changed: 173 additions & 0 deletions

File tree

skills/docs-writer/SKILL.md

Lines changed: 173 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,173 @@
1+
---
2+
name: docs-writer
3+
description: Use when writing or editing pages for this Mintlify docs site, especially when the change involves code snippets that must be generated via the test → MDX pipeline. Also triggers when the user asks to cross-check docs against a specific source repo (e.g., "verify against the lancedb repo").
4+
---
5+
6+
# LanceDB Docs Snippet Pipeline
7+
8+
Code examples on docs pages are **not** written directly into MDX. They live inside real, runnable tests under `tests/{py,ts,rs}/`, get extracted by `scripts/mdx_snippets_gen.py` into auto-generated modules under `docs/snippets/`, and are imported into MDX pages as named constants. Follow the pipeline below — otherwise your changes will either render stale or be overwritten on the next regen.
9+
10+
## Golden rules
11+
12+
1. **Never hand-edit `docs/snippets/*.mdx`.** Every file there is auto-generated. The header says `Auto-generated by scripts/mdx_snippets_gen.py. Do not edit manually.` — believe it.
13+
2. **Edit the test source instead.** Then regenerate.
14+
3. **Snippets must be inside passing tests.** They're extracted from real pytest/vitest/cargo tests. If the test doesn't run, the example is wrong.
15+
4. **Cross-check every non-trivial API claim against the source repo.** If the user names a repo (e.g., *"check in the sophon repo"*, *"verify against lancedb"*), that repo is the source of truth — grep it, cite the file + line, and let the code override prior assumptions. See [Cross-checking docs against source repos](#cross-checking-docs-against-source-repos) for resolution rules.
16+
17+
## Pipeline at a glance
18+
19+
```
20+
tests/py/test_indexing.py ──┐
21+
tests/ts/indexing.test.ts ──┼──► make snippets ──► docs/snippets/indexing.mdx ──► import in docs/*/page.mdx
22+
tests/rs/indexing.rs ──┘
23+
```
24+
25+
## File-name mapping
26+
27+
The output module is the test file stem with `test_` stripped (Python), `.test` stripped (TS), or bare (Rust):
28+
29+
| Source file | Generated module |
30+
| :--- | :--- |
31+
| `tests/py/test_indexing.py` | `docs/snippets/indexing.mdx` |
32+
| `tests/ts/connection.test.ts` | `docs/snippets/connection.mdx` |
33+
| `tests/rs/basic_usage.rs` | `docs/snippets/basic_usage.mdx` |
34+
35+
(Authoritative logic: `normalize_target_name` in `scripts/mdx_snippets_gen.py`.)
36+
37+
## Marker syntax
38+
39+
Delimit each snippet with language-appropriate comment markers:
40+
41+
| Language | Start | End |
42+
| :--- | :--- | :--- |
43+
| Python | `# --8<-- [start:snippet_name]` | `# --8<-- [end:snippet_name]` |
44+
| TypeScript / Rust | `// --8<-- [start:snippet_name]` | `// --8<-- [end:snippet_name]` |
45+
46+
- `snippet_name` is `snake_case` and **must be unique across the whole repo** (the generator errors on duplicates).
47+
- Keep the body of the snippet minimal — the reader sees exactly what's between the markers. Setup (fixtures, data creation, assertions) goes outside the markers.
48+
49+
## Export name formula
50+
51+
The generator derives the MDX export name as `{Prefix}{TitleCase(snippet_name)}` where the prefix is `Py`, `Ts`, or `Rs`.
52+
53+
- `vector_index_nprobes` (Python) → `PyVectorIndexNprobes`
54+
- `connection_setup` (TypeScript) → `TsConnectionSetup`
55+
- `basic_usage` (Rust) → `RsBasicUsage`
56+
57+
## Regenerating
58+
59+
Preferred:
60+
61+
```bash
62+
make snippets # all three languages
63+
make py # Python only
64+
make ts # TypeScript only
65+
make rs # Rust only
66+
```
67+
68+
`make` invokes `uv run scripts/mdx_snippets_gen.py -s tests/{lang}`. If `uv run` fails in your sandbox (see top-level `CLAUDE.md`), fall back to activating the local venv and running the script directly:
69+
70+
```bash
71+
source .venv/bin/activate
72+
python scripts/mdx_snippets_gen.py -s tests/py # and -s tests/ts, -s tests/rs
73+
```
74+
75+
Always run the test suite for the language you edited before regenerating:
76+
77+
```bash
78+
source .venv/bin/activate
79+
python -m pytest tests/py/test_indexing.py
80+
```
81+
82+
(TS/Rust suites have their own runners — check `tests/ts/package.json` and `tests/rs/Cargo.toml`.)
83+
84+
## Pre-PR checklist
85+
86+
Before opening (or updating) a PR, **always** run `make snippets` from the repo root so the regenerated `docs/snippets/*.mdx` files land in the same commit as the test changes that produced them. Otherwise the PR will ship stale snippets and CI (or a later regen run) will flag a diff.
87+
88+
```bash
89+
cd /Users/prrao/code/docs # or wherever the repo is checked out
90+
make snippets
91+
git status # confirm any regenerated docs/snippets/*.mdx are staged
92+
```
93+
94+
If `git status` shows modified files under `docs/snippets/` after `make snippets`, stage and commit them alongside your test and MDX changes — do not push a PR with an un-regenerated snippets tree.
95+
96+
## Importing a snippet into a docs page
97+
98+
Use the absolute `/snippets/...` path (not relative) and alias the long `Py|Ts|Rs` export names:
99+
100+
```mdx
101+
import {
102+
PyVectorIndexNprobes as VectorIndexNprobes,
103+
TsVectorIndexNprobes,
104+
} from '/snippets/indexing.mdx';
105+
```
106+
107+
Then render with a `CodeGroup`:
108+
109+
```mdx
110+
<CodeGroup>
111+
<CodeBlock filename="Python" language="python" icon="python">
112+
{VectorIndexNprobes}
113+
</CodeBlock>
114+
<CodeBlock filename="TypeScript" language="typescript" icon="square-js">
115+
{TsVectorIndexNprobes}
116+
</CodeBlock>
117+
<CodeBlock filename="Rust" language="rust" icon="rust">
118+
{RsVectorIndexNprobes}
119+
</CodeBlock>
120+
</CodeGroup>
121+
```
122+
123+
Icon conventions: `python`, `square-js` (TS), `rust`.
124+
125+
## Language parity
126+
127+
All three test trees are actively populated. If the API you're documenting exists in every language binding, add snippets in all three. Python-only is acceptable when the feature is Python-specific (e.g., a Pydantic/PyArrow integration), but call it out explicitly in the prose rather than silently omitting other languages.
128+
129+
## Cross-checking docs against source repos
130+
131+
Docs must reflect what the code actually does. Before writing or editing any claim about an API — parameter names, defaults, return types, method existence, behavior under edge cases — verify it against the source repo.
132+
133+
**If the user names a repo, use that repo as the source of truth.** Phrasings like *"check in the sophon repo that the code shows this"*, *"verify against lancedb"*, or *"cross-reference the geneva repo"* are explicit instructions to ground the docs in that codebase. Treat them as required, not optional.
134+
135+
Resolution order for a repo name the user mentions:
136+
137+
1. Sibling checkout of `/Users/prrao/code/docs`: e.g., `../lancedb`, `../sophon`, `../geneva`. Check with `ls ../` first.
138+
2. Anywhere under `/Users/prrao/code/`: try `ls /Users/prrao/code/ | grep -i <name>`.
139+
3. If neither exists locally, ask the user for the path (or a clone URL) before proceeding — do **not** guess or substitute a different repo.
140+
141+
Once located, `Grep` for the symbol, parameter, or behavior and cite the file + line in your response so the user can audit the check. If the repo and the docs disagree, the repo wins — update the docs (or flag the discrepancy to the user if it looks like a real bug).
142+
143+
Known repos and typical surfaces to grep (extend as you learn new ones):
144+
145+
| Repo | Common source paths |
146+
| :--- | :--- |
147+
| `lancedb` | `python/python/lancedb/` (Python), `nodejs/` (TS), `rust/` (Rust core) |
148+
| `sophon` | ask user on first encounter; record the path here once confirmed |
149+
| `geneva` | ask user on first encounter; record the path here once confirmed |
150+
151+
**General rule**: even when the user does *not* name a repo, if you're documenting a non-trivial API surface and a plausible source repo is available locally, cross-check proactively rather than relying on memory. This catches hallucinated parameters before they ship.
152+
153+
## Mintlify components
154+
155+
Prefer these over ad-hoc emphasis:
156+
157+
- `<Note>` — general notable info
158+
- `<Tip>` — actionable suggestion
159+
- `<Info>` — background / context
160+
- `<Warning>` — pitfalls, perf caveats
161+
- `<Badge>` — e.g., `<Badge color="red">Enterprise-only</Badge>`
162+
- `<Card>` — linked call-out to an external notebook or page
163+
- `<CodeGroup>` / `<CodeBlock>` — multi-language code (always for runnable examples)
164+
165+
## Common mistakes this skill prevents
166+
167+
- Editing `docs/snippets/*.mdx` directly and losing the change on the next `make snippets`.
168+
- Inventing export names that don't match the `{Py|Ts|Rs}{TitleCase}` formula.
169+
- Using a relative import path like `'../snippets/indexing.mdx'` (must be `'/snippets/indexing.mdx'`).
170+
- Writing Python-only examples for a feature that exists in all three SDKs.
171+
- Documenting parameters that don't exist in the source repo (e.g., `../lancedb`, `../sophon`, `../geneva`).
172+
- Ignoring a user's explicit instruction to cross-check against a named repo — that instruction is mandatory, not advisory.
173+
- Running `python scripts/mdx_snippets_gen.py` without the `-s tests/<lang>` flag (the script needs a source dir).

0 commit comments

Comments
 (0)