@abstractdata/starlight-theme 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,311 @@
1
+ ---
2
+ description: "Read a project's source code and write substantive narrative documentation alongside the auto-generated API reference. Use when the user says \"flesh out the docs\", \"write better docs\", \"the API pages are too thin\", \"enrich the docs\", \"author the docs\", \"explain this codebase\", \"fill out the documentation\", \"the autodoc pages need more context\", or similar phrases inside a project that uses @abstractdata/starlight-theme. Typically invoked by abstract-data-setup after generators have produced bare-signatures pages, but can also be invoked standalone when a user says their docs are too sparse."
3
+ alwaysApply: false
4
+ ---
5
+
6
+ <!--
7
+ Auto-generated from .claude/skills/abstract-data-docs-author/SKILL.md.
8
+ Edit the source SKILL.md and run `bun run sync-skills` to regenerate.
9
+ Do not hand-edit this file — changes will be overwritten.
10
+ -->
11
+
12
+ # Abstract Data Documentation Theme — Docs Author
13
+
14
+ Read a project's source code and *write* documentation. Complements the auto-generated mechanical API reference (signatures, type hints, structure produced by pydoc-markdown / TypeDoc) by adding narrative prose, motivation, examples, and cross-references — the things mechanical autodoc can never produce well, especially when the source's docstrings are thin.
15
+
16
+ This skill **enriches**, never **replaces**, the mechanical autodoc output. Always preserve the auto-generated signatures section. Layer prose above it.
17
+
18
+ ## When to invoke
19
+
20
+ Run this skill when:
21
+
22
+ - The user says "flesh out the docs", "write better docs", "the API pages are too thin", "enrich the docs", or similar.
23
+ - The `abstract-data-setup` skill has just finished generating mechanical autodoc pages that read as terse/empty.
24
+ - The user has run `bun run docs:python` (or `docs:ts`) and asks "now make these readable."
25
+
26
+ If the cwd doesn't have `@abstractdata/starlight-theme` in `package.json` deps, stop and point the user at `bun create @abstractdata/docs`. If `src/content/docs/api/` doesn't exist or is empty, run the setup skill first (or tell the user to).
27
+
28
+ ## Operating principles
29
+
30
+ 1. **Enrich, don't replace.** Always preserve the existing auto-generated content (signatures, type hints, structure). Layer your prose *before* it (as a "Module overview" preface) or *after* it (as "Examples", "Related", "See also" sections). Never delete the mechanical scaffold.
31
+
32
+ 2. **Be honest about uncertainty.** If you're inferring intent from a function name without good context, say so. Phrases like "appears to handle…" are better than confident wrong claims.
33
+
34
+ 3. **Read tests for examples.** If the project has tests, they're the most reliable source of usage patterns. Quote test code (lightly cleaned up) for examples whenever possible — it's true by construction.
35
+
36
+ 4. **Token-budget discipline.** Don't try to read the whole codebase in one pass. Loop module by module, smallest first. Each iteration's context is just one module's source + that module's existing autodoc page. For 30-module projects, that's 30 small conversations, not one giant one.
37
+
38
+ 5. **Idempotent.** If a page already has an "Overview" preface (you wrote one before), refresh it rather than appending a second. Look for marker comments or distinctive heading patterns.
39
+
40
+ 6. **Don't hallucinate features.** If the source code doesn't do something, don't write that it does. The reader will trust your prose; lying is worse than terse pages.
41
+
42
+ ## Workflow
43
+
44
+ ### Phase 1 — Discover the project
45
+
46
+ Read these files (top-down, bail if absent):
47
+
48
+ - `package.json` — confirm `@abstractdata/starlight-theme` dep
49
+ - `astro.config.mjs` — confirm Starlight project
50
+ - `scripts/python-autodoc.json` and/or `scripts/ts-autodoc.json` — confirm autodoc has been wired
51
+ - `src/content/docs/api/` — list existing auto-generated pages
52
+ - The source project's `README.md`, `CHANGELOG.md`, `CONTRIBUTING.md` if present
53
+ - Any `docs/adr/` directory or `ARCHITECTURE.md` — important context
54
+
55
+ Note the source project root (from `searchPath` in `python-autodoc.json` or `entryPoints` in `ts-autodoc.json`). All source reads go relative to that.
56
+
57
+ ### Phase 1.5 — Inventory existing prose
58
+
59
+ Before profiling or writing anything new, build a manifest of prose that **already exists in the source project**. Most projects have a substantial amount of usable narrative scattered across `README.md`, `CHANGELOG.md`, ADRs, and existing docstrings — rewriting it from scratch wastes tokens and risks contradicting the source's own voice.
60
+
61
+ For each candidate file, read it once and produce a line-item inventory:
62
+
63
+ - **`README.md`** — for each `##` section, note: heading, ~10-word summary, candidate destination. Common reuse targets:
64
+ - "Quick start" / "Installation" / "Getting started" → `src/content/docs/quickstart.md`
65
+ - "Features" / "What it does" / "Why use this" → `src/content/docs/index.mdx` hero subtitle + `concepts.md` intro
66
+ - "Architecture" / "How it works" / "Design" → `src/content/docs/concepts.md` body
67
+ - "Configuration" / "Options" → a guide or the relevant module overview
68
+ - "Examples" / "Usage" → split across module Example blocks
69
+ - "Contributing" → leave in repo, link from docs sidebar
70
+ - **`CHANGELOG.md`** — note the most recent 1–3 entries. Don't import wholesale; harvest noteworthy feature additions for the concepts page ("Recent additions") or for module overviews ("Added in v0.4 to address …").
71
+ - **`docs/adr/*.md`** or **`ARCHITECTURE.md`** — for each ADR, note: title, decision, the 1–2 sentence rationale. ADRs are *gold* for the `concepts.md` page — they explain *why* the architecture looks the way it does. Quote the rationale, link out to the ADR for full context.
72
+ - **`CONTRIBUTING.md`** — usually stays in repo; mine for any "How to add a new X" sections that should become how-to guides under `src/content/docs/guides/`.
73
+ - **Existing module docstrings** — even if the autodoc page reads as thin, the source `.py` / `.ts` may have a leading module docstring with usable framing. Note which modules have them (Phase 6 will reuse the wording verbatim where appropriate).
74
+
75
+ Output the inventory as a brief plan to memory before moving on:
76
+
77
+ ```
78
+ README sections worth lifting:
79
+ - "## Quick start" → quickstart.md (verbatim, light edit)
80
+ - "## How it works" → concepts.md intro (paraphrase)
81
+ - "## Why httpx?" → core/http_scan module overview (paraphrase + link to ADR-007)
82
+
83
+ CHANGELOG highlights:
84
+ - v0.4: Added BaseHttpScanModule (link to ADR-007)
85
+ - v0.3: AI integration via Ollama (concepts.md "Optional integrations" section)
86
+
87
+ ADRs:
88
+ - ADR-001 "Use httpx not requests" → quote in concepts.md
89
+ - ADR-007 "BaseHttpScanModule" → quote in core/http_scan overview
90
+
91
+ Modules with usable existing docstrings: auditkit.core, auditkit.transport.curl_impersonate
92
+ ```
93
+
94
+ When you reach Phases 5 and 6, **prefer lifting existing prose** (with light cleanup and proper attribution if it's a paraphrase from an ADR) over fabricating new wording. Always offer the user a side-by-side: "README says X, ADR says Y, here's the merged version — keep, edit, or rewrite?"
95
+
96
+ If the source project has *no* README beyond a one-liner and *no* ADRs, say so up front — the user should know the docs-author run will need to invent more, and that voice will be yours rather than the project's.
97
+
98
+ ### Phase 2 — Profile the project
99
+
100
+ Spend 1–2 conversation turns building a project profile. Not a deep code read yet — orientation only:
101
+
102
+ - Read `README.md` (one document) — extract the elevator pitch, the core problem the project solves, the primary user.
103
+ - Read top-level CLI entry points or top-level `index.ts` exports — understand the public surface.
104
+ - Read `pyproject.toml` / `package.json` description fields and keywords.
105
+ - Skim test directory names (don't read full tests yet) — understand testing organization.
106
+
107
+ Write a **3–5 sentence project profile** to memory. This profile is the lens for every module-level write that follows. Examples:
108
+
109
+ > "auditkit is a security-audit CLI that scans websites for misconfigurations across 9 categories. It's modular: each scan module inherits from `ScanModule` and runs async via httpx. Heavy use of pydantic for data validation. AI integration via Ollama is optional."
110
+
111
+ Reuse this voice in every module overview you write.
112
+
113
+ ### Phase 3 — Build the module map
114
+
115
+ For each existing page in `src/content/docs/api/`:
116
+
117
+ 1. Read the page (current state — may be terse/empty).
118
+ 2. Read the corresponding source file from the source project.
119
+ 3. Note: file size, public symbols, imports (which other modules does it depend on?), test coverage (is there a `test_<module>.py`?).
120
+
121
+ Build an in-memory map: `{ pageName, sourcePath, publicSymbols, dependencies, hasTests, currentPageBytes }`. Smallest pages first — they're cheapest to enrich and the user gets early wins.
122
+
123
+ ### Phase 4 — Find usage examples
124
+
125
+ For each module with tests, locate 1–2 representative test cases. Look for:
126
+
127
+ - Tests with descriptive names (`test_login_browser_with_valid_credentials`)
128
+ - Tests that exercise the public API directly (not internal helpers)
129
+ - Short tests (under ~20 lines) — easier to inline as examples
130
+
131
+ Note these locations. You'll quote them in Phase 6.
132
+
133
+ ### Phase 5 — Write narrative pages
134
+
135
+ Before per-module work, write the high-leverage **narrative pages** that don't exist yet. Check first — if `src/content/docs/concepts.md` (or similar) already has user-written content, leave it alone. Otherwise, draft:
136
+
137
+ - **`src/content/docs/concepts.md`** — architecture overview. 300–600 words. Source the structure from imports + ADRs + your project profile. Cover: core abstractions, data flow, key types, extension points.
138
+
139
+ - **`src/content/docs/guides/getting-started.md`** *(if not present)* — distilled from README quickstart. Should be hands-on, end with the user having run a thing.
140
+
141
+ - **`src/content/docs/guides/<workflow>.md`** — for each repeated test pattern, write a how-to. Examples: "Adding a new scan module", "Configuring authentication", "Writing custom callbacks". One workflow per file.
142
+
143
+ Don't generate every possible guide — pick the 2–3 most valuable based on the project profile. Quality over quantity.
144
+
145
+ After writing, update `astro.config.mjs` sidebar to add a "Concepts" / "Guides" group if not present.
146
+
147
+ ### Phase 6 — Module-by-module enrichment loop
148
+
149
+ For each module page in your map, smallest-first:
150
+
151
+ 1. **Read the source file** (the actual `.py` / `.ts` file, not just docstrings). Understand what it does.
152
+ 2. **Detect existing enrichment.** If the page already has a `<!-- abstract-data-docs-author:overview -->` comment marker, you wrote a preface before — refresh it instead of duplicating.
153
+ 3. **Write a "Module overview" preface** (150–300 words) covering:
154
+ - **What this module is** — one-sentence description tied to the project profile
155
+ - **Why it exists** — what role does it play in the larger system
156
+ - **When to use it** — typical entry point or trigger
157
+ - **Key types or functions** — a 3–5 bullet list pointing at the most important public symbols
158
+ 4. **Add an "Example" section** quoting a test case (cleaned up if needed). Wrap in a code block with the right language.
159
+ 5. **Add a "Related" footer** linking 2–3 sibling modules (from the imports map). Format: `- [`module.name`](/api/module_name/)` — one-line description.
160
+ 6. **Inject** the preface above the existing auto-generated content. Keep the example and related sections after.
161
+ 7. **Save** with the marker comments so the next run is idempotent:
162
+
163
+ ```markdown
164
+ <!-- abstract-data-docs-author:overview -->
165
+ [your preface]
166
+ <!-- /abstract-data-docs-author:overview -->
167
+
168
+ [existing auto-generated content untouched]
169
+
170
+ <!-- abstract-data-docs-author:example -->
171
+ [example section]
172
+ <!-- /abstract-data-docs-author:example -->
173
+
174
+ <!-- abstract-data-docs-author:related -->
175
+ [related links]
176
+ <!-- /abstract-data-docs-author:related -->
177
+ ```
178
+
179
+ After each module, **stop and confirm with the user** before continuing. Show the diff. Let them approve, edit, or reject. This is mandatory — never bulk-apply prose without per-module review.
180
+
181
+ ### Phase 7 — Cross-reference pass
182
+
183
+ After all module pages enriched (or as many as the user opted into), do one final pass to cross-reference:
184
+
185
+ - Inside any page, if you mention another module by name, link it: ``` `auditkit.config.AuditConfig` ``` → `[\`auditkit.config.AuditConfig\`](/api/auditkit_config/#auditconfig-objects)`.
186
+ - Add a "Used by" reverse-lookup section to high-leverage modules — "this is imported by X, Y, Z".
187
+
188
+ This is the polish pass. Skip if the user is fatigued.
189
+
190
+ ### Phase 8 — Summary
191
+
192
+ Write a 6–10 line markdown summary covering:
193
+
194
+ - Modules enriched / skipped
195
+ - Narrative pages written
196
+ - Total prose added (rough word count)
197
+ - Any modules where you got stuck or recommended manual follow-up
198
+ - Suggested next step (e.g., "Run `bun dev` and walk the new pages")
199
+
200
+ ## Templates
201
+
202
+ Use these as starting points, not rigid forms.
203
+
204
+ ### Module overview template (Python)
205
+
206
+ ```markdown
207
+ **What this is:** [One-sentence description in the project's voice. E.g., "OAuth lifecycle helpers for jre-vidget's YouTube integration."]
208
+
209
+ **Why it exists:** [What role does it play. E.g., "Isolates browser-based auth from the CLI surface — no Rich, no video logic, no terminal state."]
210
+
211
+ **When to use it:** [Typical entry point. E.g., "Call `login_browser()` once during onboarding to mint a refresh token. Subsequent runs use `get_credentials()` to refresh on demand."]
212
+
213
+ **Key surfaces:**
214
+ - `login_browser(client_id, client_secret)` — interactive OAuth flow, returns `AuthConfig`
215
+ - `get_credentials(auth)` — refreshes on demand, returns `google.oauth2.credentials.Credentials`
216
+ - `AuthError` — raised when credentials are missing or unrefreshable
217
+ ```
218
+
219
+ ### Class/function preface template
220
+
221
+ For pages that document a single class or function (rare with pydoc-markdown's per-module output but happens), use:
222
+
223
+ ```markdown
224
+ **Purpose:** [why this exists]
225
+
226
+ **Key behavior:** [what it does, 2-3 sentences]
227
+
228
+ **Common usage:**
229
+ ```python
230
+ [short example]
231
+ ```
232
+ ```
233
+
234
+ ### Example block template
235
+
236
+ ```markdown
237
+ ## Example
238
+
239
+ [1-line context: "Logging in for the first time:"]
240
+
241
+ ```python
242
+ [10-15 lines of cleaned test code or synthesized usage]
243
+ ```
244
+
245
+ [1-line outcome: "After this, `auth.refresh_token` is set and persisted via `write_config_safely`."]
246
+ ```
247
+
248
+ ## Where dynamic `<head>` / metadata belongs
249
+
250
+ If during the Phase 5 narrative-page work you find yourself wanting to inject something dynamic into `<head>` — JSON-LD structured data (`Article`, `BreadcrumbList`, `SoftwareSourceCode`), per-page Open Graph image URLs, breadcrumb meta tags, or any computed-from-frontmatter `<meta>` tag — **the right layer is route middleware, not a component override.**
251
+
252
+ Starlight ≥ 0.32 lets you mutate `Astro.locals.starlightRoute.head` from a function exported by a file referenced as `routeMiddleware:` in `astro.config.mjs`. This is much cleaner than overriding the `<Head>` component because it composes with other plugins, doesn't break when Starlight bumps versions, and lets you read the current page's frontmatter before deciding what to inject.
253
+
254
+ Sketch:
255
+
256
+ ```ts
257
+ // src/routeData.ts
258
+ import { defineRouteMiddleware } from '@astrojs/starlight/route-data';
259
+
260
+ export const onRequest = defineRouteMiddleware((context) => {
261
+ const route = context.locals.starlightRoute;
262
+ // route.entry.data is the frontmatter; route.headings is the TOC tree.
263
+ route.head.push({
264
+ tag: 'script',
265
+ attrs: { type: 'application/ld+json' },
266
+ content: JSON.stringify({
267
+ '@context': 'https://schema.org',
268
+ '@type': 'Article',
269
+ headline: route.entry.data.title,
270
+ description: route.entry.data.description,
271
+ }),
272
+ });
273
+ });
274
+ ```
275
+
276
+ ```js
277
+ // astro.config.mjs
278
+ starlight({
279
+ routeMiddleware: './src/routeData.ts',
280
+ // …
281
+ })
282
+ ```
283
+
284
+ If the user explicitly wants any of these features (JSON-LD, dynamic OG images, breadcrumb meta), point them at this file as the place to wire it. Don't override the `<Head>` component just to inject computed meta — that's an anti-pattern documented in the Starlight migration notes for ≥ 0.33.
285
+
286
+ ## What this skill does NOT do
287
+
288
+ - **Doesn't rewrite source code.** That's a different operation. If the user wants to add docstrings to the source, that's `abstract-data-setup`'s Phase 4 territory (audit + suggest enrichment), not this skill's.
289
+ - **Doesn't generate API reference from scratch.** That's pydoc-markdown / TypeDoc's job. This skill *layers on top of* that output.
290
+ - **Doesn't guess at private symbols.** Only document the public API surface. Helper functions with leading underscores are skipped.
291
+ - **Doesn't auto-commit.** Writes files, leaves git up to the user.
292
+
293
+ ## Files this skill reads
294
+
295
+ - The docs project's `package.json`, `astro.config.mjs`, `scripts/python-autodoc.json` / `scripts/ts-autodoc.json`, existing `src/content/docs/api/*.md`.
296
+ - The source project's `README.md`, source files (`.py` / `.ts`), test files, ADRs, `pyproject.toml`/`package.json`.
297
+
298
+ ## Files this skill writes
299
+
300
+ - `src/content/docs/api/*.md` — enriched (preface + example + related sections injected around existing autodoc).
301
+ - `src/content/docs/concepts.md` — narrative architecture overview (only if not already user-authored).
302
+ - `src/content/docs/guides/*.md` — per-workflow how-to (only if not already user-authored).
303
+ - `astro.config.mjs` — sidebar updates to add new groups for Concepts / Guides.
304
+
305
+ ## Notes for the agent
306
+
307
+ - **Never bulk-apply.** Always confirm per-module before writing.
308
+ - **Token discipline.** Read one module's source per loop iteration. Don't try to hold the whole codebase in context.
309
+ - **Preserve markers.** The HTML comment markers (`<!-- abstract-data-docs-author:overview -->`) are how the next run finds and refreshes existing prose. Don't strip them.
310
+ - **When stuck:** if you can't form a coherent preface for a module (the source is too thin or too obscure), say so and skip. Don't write nonsense.
311
+ - **The mechanical autodoc is the floor.** Your job is to raise the ceiling.