@abstractdata/starlight-theme 0.3.2 → 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.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: "Set up the Abstract Data Documentation Theme (built on Astro Starlight) for a Python project. Detect source code, audit docstring coverage, sniff docstring style (Google/NumPy/Sphinx), ask configuration questions (modules, motion, credit, version), wire up config files (scripts/python-autodoc.json, astro.config.mjs sidebar + plugin options, package.json scripts), and optionally install a docstring-coverage pre-commit hook in the source project. Use when the user says \"set up docs\", \"configure docs\", \"wire up Python autodoc\", \"scan my project for docs\", \"set up Abstract Data docs\", \"add API reference\", \"audit docstrings\", or similar phrases inside a docs project that uses @abstractdata/starlight-theme (the npm package name; product is the Abstract Data Documentation Theme)."
2
+ description: "Set up the Abstract Data Documentation Theme (built on Astro Starlight) for a project. Detect source code across stacks (Python, TypeScript, Next.js, TanStack, OpenAPI, Prisma, Drizzle), audit docstring coverage for Python, sniff docstring style (Google/NumPy/Sphinx), detect or pick a logo asset, ask configuration questions (modules/entry points, motion, credit, version), wire up config files (scripts/python-autodoc.json, scripts/ts-autodoc.json, astro.config.mjs sidebar + plugin options, package.json scripts), and optionally install a docstring-coverage pre-commit hook. Use when the user says \"set up docs\", \"configure docs\", \"wire up Python autodoc\", \"wire up TypeScript autodoc\", \"scan my project for docs\", \"set up Abstract Data docs\", \"add API reference\", \"audit docstrings\", or similar phrases inside a docs project that uses @abstractdata/starlight-theme (the npm package name; product is the Abstract Data Documentation Theme)."
3
3
  alwaysApply: false
4
4
  ---
5
5
 
@@ -11,28 +11,23 @@ alwaysApply: false
11
11
 
12
12
  # Abstract Data Documentation Theme — Setup
13
13
 
14
- Bootstrap the Abstract Data Documentation Theme — the branded docs system Abstract Data uses across client projects, built on Astro Starlight and shipped as the npm package `@abstractdata/starlight-theme`. Round 1.5 covers Python projects with docstring-coverage and style awareness. Future rounds will add TypeScript, Next.js, TanStack, OpenAPI.
14
+ Bootstrap the Abstract Data Documentation Theme — the branded docs system Abstract Data uses across client projects, built on Astro Starlight and shipped as the npm package `@abstractdata/starlight-theme`. Round 2 covers Python and TypeScript autodoc with full automation, plus detection-and-recipe handling for Next.js, TanStack Router, OpenAPI, Prisma, and Drizzle.
15
15
 
16
16
  ## When to invoke
17
17
 
18
- Run this skill when:
18
+ Run this skill when the user says "set up docs", "configure docs", "wire up Python autodoc", "wire up TypeScript autodoc", "scan my project for docs", "audit docstrings", or similar inside a project that has `@abstractdata/starlight-theme` in its `package.json`. If the cwd doesn't have that dep, stop and point them at `bun create @abstractdata/docs`.
19
19
 
20
- - The user says "set up docs", "configure docs", "wire up Python autodoc", "scan my project for docs", "audit docstrings", or similar.
21
- - The cwd has `@abstractdata/starlight-theme` in `dependencies` or `devDependencies` of `package.json`.
20
+ ## Workflow
22
21
 
23
- If the cwd doesn't have that dep, stop and tell the user this skill only runs in Abstract Data documentation projects (point them at `bun create @abstractdata/docs`).
24
-
25
- ## Workflow (11 phases)
26
-
27
- Ask the user via your interactive prompt mechanism for every choice — never assume.
22
+ Use interactive prompts for every choice never assume.
28
23
 
29
24
  ### Phase 1 — Confirm context
30
25
 
31
26
  Read `package.json`. Verify `@abstractdata/starlight-theme` is in deps; verify `astro.config.mjs` and `src/content/docs/` exist. Stop with a clear message if any check fails. Don't ask the user to confirm — just announce findings and move on.
32
27
 
33
- ### Phase 2 — Locate the source project
28
+ ### Phase 2 — Locate the source project(s)
34
29
 
35
- an interactive prompt: where does the source project live?
30
+ Ask via interactive prompt: where does the source project live?
36
31
  - "This directory" — docs ARE the source (rare)
37
32
  - "Parent directory (..)" — docs sit inside the source repo
38
33
  - "Sibling directory" — separate repos at the same level
@@ -40,109 +35,269 @@ an interactive prompt: where does the source project live?
40
35
 
41
36
  Validate the path exists. Reprompt on invalid.
42
37
 
43
- ### Phase 3 — Detect Python signals
38
+ ### Phase 3 — Detect all stack signals
44
39
 
45
- Look for `pyproject.toml`, `setup.py`, `requirements.txt`, `src/<pkg>/__init__.py`, `<pkg>/__init__.py`. If none, exit: "I didn't find Python source at <path>. Round 1 only handles Python projects."
40
+ In the source path, scan for these signals in parallel. Report what you find before asking any per-stack questions.
46
41
 
47
- If found, identify:
48
- - **Package root** (directory with top-level `__init__.py`)
49
- - **Package name** (from `pyproject.toml [project] name`, or directory name)
50
- - **Submodules** (one level deep, exclude dunders, cap at ~30)
42
+ **Python:**
43
+ - `pyproject.toml`, `setup.py`, `requirements.txt`, `Pipfile`
44
+ - `src/<pkg>/__init__.py` or `<pkg>/__init__.py`
51
45
 
52
- ### Phase 4 — Audit docstring coverage
46
+ **TypeScript library:**
47
+ - `tsconfig.json` AND `package.json` with `main`/`exports`/`types` fields
48
+ - `src/index.ts` or similar entry point
53
49
 
54
- For each candidate module, compute the percentage of public callables (functions, methods, classes) that have docstrings.
50
+ **Next.js:**
51
+ - `next.config.{js,mjs,ts}`
52
+ - `app/` directory (App Router) or `pages/` directory (Pages Router)
53
+ - `next` in dependencies
55
54
 
56
- **Preferred tool: `interrogate`.** Check if it's available:
55
+ **TanStack Router / Start:**
56
+ - `@tanstack/react-router`, `@tanstack/react-start`, or `@tanstack/start` in dependencies
57
+ - `src/routes/` directory
58
+ - `src/routeTree.gen.ts` (generated route tree)
57
59
 
58
- ```bash
59
- which interrogate
60
- ```
60
+ **OpenAPI:**
61
+ - `openapi.yaml`, `openapi.json`, `swagger.yaml`, `swagger.json`
62
+ - Files matching `*.openapi.{yaml,json}`
61
63
 
62
- If yes, run:
64
+ **Prisma:**
65
+ - `prisma/schema.prisma`
63
66
 
64
- ```bash
65
- interrogate -v <package_root> --omit-covered-files --output json 2>/dev/null | jq .
67
+ **Drizzle:**
68
+ - `drizzle.config.{ts,js}`
69
+ - Files in a `schema/` directory exporting `pgTable` / `mysqlTable` / `sqliteTable`
70
+
71
+ **Logo asset (in the docs project, not the source):**
72
+ - `src/assets/*.{png,svg,jpg,jpeg,webp}` — anything that looks like a logo (`logo.*`, `*-logo.*`, `brand.*`)
73
+
74
+ Display the detection summary in a table:
75
+
76
+ ```
77
+ Stack Detected Action
78
+ Python yes will offer Python autodoc
79
+ TypeScript yes will offer TypeScript autodoc
80
+ Next.js no —
81
+ TanStack yes recipe-only (no auto-config)
82
+ OpenAPI no —
83
+ Prisma yes recipe-only (no auto-config)
84
+ Drizzle no —
85
+ Logo 1 file will confirm choice
66
86
  ```
67
87
 
68
- If `interrogate` is unavailable, fall back to a quick AST walk via `python3 -c`:
88
+ If no source signals at all exit politely.
89
+
90
+ ### Phase 4 — Python: audit + style (only if Python detected)
91
+
92
+ #### 4a — Audit docstring coverage
93
+
94
+ Preferred tool: `interrogate` (`pipx install pydoc-markdown` first if not installed). Fall back to a Python AST one-liner. Categorize per-module:
95
+ - **≥ 80%** green
96
+ - **50-79%** yellow
97
+ - **< 50%** red
98
+
99
+ Show the table; don't editorialize.
100
+
101
+ #### 4b — Detect docstring style
102
+
103
+ Sample 10–20 docstrings, count distinctive markers (Google `Args:`/`Returns:`, NumPy `Parameters\n----`, Sphinx `:param x:`). Pick the leader if it has ≥60% of markers; otherwise call it "mixed."
104
+
105
+ ### Phase 5 — TypeScript: entry-point detection (only if TS library detected)
106
+
107
+ Read `package.json` `main`/`exports`/`types` fields. Walk `src/` for `index.ts` files. Build a candidate list of entry points (one per public module surface).
108
+
109
+ Common shapes:
110
+ - Single entry: `src/index.ts` → one entry point
111
+ - Multi-entry: `package.json` `exports` lists multiple → one entry per exported subpath
112
+ - Monorepo: each package has its own entry
113
+
114
+ #### 5a — Audit TSDoc coverage
115
+
116
+ Mirror Phase 4a for TypeScript. Run TypeDoc in **validation-only** mode against the chosen entry points:
69
117
 
70
118
  ```bash
71
- python3 -c "
72
- import ast, sys, os
73
- def cov(path):
74
- with open(path) as f:
75
- tree = ast.parse(f.read())
76
- items = [n for n in ast.walk(tree)
77
- if isinstance(n, (ast.FunctionDef, ast.AsyncFunctionDef, ast.ClassDef))
78
- and not n.name.startswith('_')]
79
- if not items: return None
80
- have = sum(1 for n in items if ast.get_docstring(n))
81
- return have, len(items)
82
- # walk a directory ...
83
- "
119
+ bunx typedoc \
120
+ --plugin typedoc-plugin-markdown \
121
+ --validation.notDocumented \
122
+ --treatValidationWarningsAsErrors false \
123
+ --emit none \
124
+ <entryPoints>
84
125
  ```
85
126
 
86
- Compute per-module coverage. Categorize:
87
- - **≥ 80%** — green, ready to document
88
- - **50-79%** — yellow, usable but gaps
89
- - **< 50%** — red, autodoc output will be sparse
127
+ Parse the resulting warnings — TypeDoc emits one line per undocumented symbol with `[warning]` prefix. Group by source file and report per-file coverage as a percentage of public exports that have at least one TSDoc block. Use the same color thresholds as the Python audit:
90
128
 
91
- Show the user a table-style report:
129
+ - **≥ 80%** green
130
+ - **50–79%** yellow
131
+ - **< 50%** red
92
132
 
93
- ```
94
- Module Coverage Status
95
- auditkit.config 12/12 100% ✓ green
96
- auditkit.bootstrap 3/3 100% ✓ green
97
- auditkit.modules.ssl 2/11 18% ✗ red — consider adding docstrings first
98
- ```
133
+ If TypeDoc isn't installed yet, fall back to a quick AST sniff: count files in `src/` with `/**` blocks vs total exported declarations. Coarser, but no install required.
99
134
 
100
- Don't editorialize too much just the data. Then move on.
135
+ Show the table; don't editorialize. The result feeds Phase 12 (pre-commit hook offer).
101
136
 
102
- ### Phase 5Detect docstring style
137
+ ### Phase 6Logo detection
103
138
 
104
- Sample 10–20 docstrings across the source tree (e.g., grep for `"""` and read context). Count distinctive markers:
139
+ Scan `src/assets/**/*.{png,svg,jpg,jpeg,webp}` recursively. Build candidate categories:
105
140
 
106
- - **Google**: `^\s+Args:\s*$`, `^\s+Returns:\s*$`, `^\s+Raises:\s*$`, `^\s+Yields:\s*$`
107
- - **NumPy**: `^\s+Parameters\s*\n\s+-+\s*$`, `^\s+Returns\s*\n\s+-+\s*$`
108
- - **Sphinx/reST**: `:param \w+:`, `:returns:`, `:raises \w+:`, `:type \w+:`
141
+ - **Topbar mark candidates**: filename matches `(logo|brand|mark|icon)\.(svg|png|webp)$` (case-insensitive). SVG preferred.
142
+ - **Light/dark pair**: filenames contain `light` or `dark` and otherwise match logo conventions (e.g. `logo-light.svg` + `logo-dark.svg`). Starlight supports both via `logo.light` + `logo.dark`.
143
+ - **Hero candidates**: any image larger than ~80KB or with `hero` / `splash` in the name — usually a bigger variant for the splash page.
144
+ - **Other images**: no logo conventions; treat as miscellaneous.
109
145
 
110
- Whichever style has the highest hit count wins. If the leader is < 60% of total markers, call it "mixed" and warn.
146
+ For each candidate, gather:
147
+ - File size in bytes
148
+ - Format (extension)
149
+ - Whether the filename indicates light/dark intent
111
150
 
112
- Report findings:
151
+ Display a 4-7 line summary table:
113
152
 
114
153
  ```
115
- Docstring style: Google (32 markers, 0 NumPy, 4 Sphinx)
154
+ File Size Format Suggested role
155
+ src/assets/logo.svg 12 KB SVG topbar mark (recommended)
156
+ src/assets/logo-light.svg 12 KB SVG topbar (light mode)
157
+ src/assets/logo-dark.svg 12 KB SVG topbar (dark mode)
158
+ src/assets/hero-mark.png 145 KB PNG splash hero image
116
159
  ```
117
160
 
118
- If mixed, mention that pydoc-markdown will produce inconsistent output until the style is unified, but don't force a decision — proceed with the most common style.
161
+ Branch on what you found:
119
162
 
120
- (Note: pydoc-markdown's CLI doesn't accept processor flags, so the orchestrator can't auto-apply the matching processor. Style detection is informational unless the user opts into a YAML pipeline.)
163
+ - **One mark + light/dark pair** propose using the pair (Starlight handles auto-switching by `data-theme`)
164
+ - **One mark, no pair** → propose using it for both modes
165
+ - **Multiple marks, no clear winner** → multiselect: which for topbar? Which for hero? `multiSelect: true` interactive prompt.
166
+ - **Zero candidates** → ask: "I don't see a logo in `src/assets/`. Drop one in (SVG preferred, ~256x256 minimum), tell me where it is, or skip for now and configure manually later."
121
167
 
122
- ### Phase 6 Recommend modules to document
168
+ Format guidance to surface alongside the prompt:
169
+ - SVG renders crispest at any size; preferred for both topbar and hero.
170
+ - PNG works fine; 256×256 minimum for the topbar (Astro will downscale via the asset pipeline).
171
+ - JPG is fine for hero photos but bad for marks (compression artifacts on edges).
172
+ - Files > 200KB will bloat first-paint; suggest optimizing or using a smaller source.
123
173
 
124
- Show coverage findings. an interactive prompt (max 4 options, first recommended):
174
+ ### Phase 7 Recommend documentation surfaces
175
+
176
+ For each detected stack, ask whether to wire it up. Stack questions are per-stack, not lumped together.
177
+
178
+ #### Python (if detected)
179
+
180
+ Interactive prompt with up to 4 options:
125
181
  - "Top-level package only" (Recommended)
126
182
  - "All green-coverage modules" (≥80%)
127
- - "Specific submodules I'll pick" → follow up with `multiSelect: true`
128
- - "Everything" (warn about red modules: empty pages)
183
+ - "Specific submodules I'll pick" → multiselect
184
+ - "Everything" (warn about red-coverage modules)
185
+
186
+ #### TypeScript (if detected)
187
+
188
+ Interactive prompt:
189
+ - "Single root entry point (src/index.ts)" (Recommended for libs with one public API)
190
+ - "All paths in package.json `exports`" (Recommended for multi-entry libs)
191
+ - "I'll pick specific entry points" → free-form
192
+
193
+ #### Other detected stacks (Next.js, TanStack, OpenAPI, Prisma, Drizzle)
194
+
195
+ Don't auto-configure. Tell the user the recipe and let them follow up:
196
+
197
+ - **Next.js**: "I detected Next.js. There isn't a standard one-shot route documenter, but you can write a small build script that walks `app/` or `pages/` and emits a `routes.md`. Want me to draft one?"
198
+ - **TanStack Router**: "I detected TanStack Router. Generate a route map by importing `routeTree.gen.ts` and walking it in a build script. Want a starter?"
199
+ - **OpenAPI**: "I detected an OpenAPI spec. Recommend `@astrojs/starlight-openapi` for the cleanest integration. Want me to install it and wire it up?"
200
+ - **Prisma**: "I detected a Prisma schema. Try `prisma-markdown` for schema docs. Want me to add it to dev deps and wire a script?"
201
+ - **Drizzle**: "I detected a Drizzle config. There isn't a mature schema-to-markdown tool yet — most teams write their own walker over the schema exports. Want me to draft a starter?"
202
+
203
+ If the user says yes to any of these, fall back to free-form work — these aren't covered by the main config files.
204
+
205
+ ### Phase 7.5 — Optional Starlight plugins
206
+
207
+ Three plugins are cheap, high-value DX wins for most docs sites. Don't auto-install — surface them as an interactive multi-select prompt with sensible per-project defaults. Skip the prompt entirely if the user has already declined them in a previous run (look for a `.abstractdata-setup.json` marker or for the plugins already being absent + the import already pruned).
208
+
209
+ For each, you decide the default based on signals you've already gathered:
129
210
 
130
- Build the final modules array as fully-qualified names.
211
+ - **`starlight-llms-txt`** emits an `llms.txt` summary at `/llms.txt` (per [llmstxt.org](https://llmstxt.org)) so AI crawlers can ingest the site as plain Markdown rather than parsing rendered HTML. **Default: ON.** No real downside.
212
+ - **`@expressive-code/plugin-package-managers`** *(code-block plugin, not a Starlight plugin)* — auto-renders npm/pnpm/yarn/bun tabs from a single `npm install foo` code block. **Default: ON if** the README, quickstart, or any docs page contains `bun add`, `npm install`, `pnpm add`, or `yarn add`. **Default: OFF otherwise.**
213
+ - **`starlight-image-zoom`** — click-to-zoom on images. **Default: ON if** the docs project has more than ~5 images under `src/assets/` or `src/content/docs/**/*.{png,jpg,svg,webp}` (a heuristic for "this site uses screenshots"). **Default: OFF otherwise.**
131
214
 
132
- ### Phase 7 Gather brand configuration
215
+ Show the user the three options with their suggested defaults pre-checked, and let them un-check / toggle. For each accepted plugin:
133
216
 
134
- Read existing `astro.config.mjs`. If `motion`, `credit`, `version` are already set and the user didn't ask to change them, skip this phase.
217
+ 1. Add to `dependencies` in `package.json`.
218
+ 2. Add the import to `astro.config.mjs`.
219
+ 3. Wire the plugin entry into the `plugins` array (or `expressiveCode.plugins` for the package-managers plugin).
220
+ 4. Tell the user the bun command to run: `bun add <plugin-name>`.
221
+
222
+ Show the resulting diff before writing. Don't run `bun add` yourself — the user does it.
223
+
224
+ ### Phase 8 — Gather brand + contributor-loop configuration
225
+
226
+ Read existing `astro.config.mjs`. If `motion`, `credit`, `version`, `lastUpdated`, and `editLink` are already set and the user hasn't asked to change them, skip this phase.
227
+
228
+ Otherwise, batch into one prompt:
135
229
 
136
- Otherwise, batch into one an interactive prompt call:
137
230
  1. Motion: full | calm (Recommended)
138
231
  2. Credit: auto | hide
139
- 3. Version chip: show (then ask for string) | omit
232
+ 3. Version chip: show with version string | omit
233
+ 4. **Last-updated timestamps** (Recommended on): renders a "Last updated" footer on each page using `git log`. Requires a git checkout at build time. Set `lastUpdated: true` if yes, omit otherwise.
234
+ 5. **"Edit on GitHub" link** (Recommended on for OSS): renders an Edit link in the footer pointing at the source. Needs a repo URL — derive it from `package.json` `repository.url` or the source-project remote (`git remote get-url origin`). If found, write `editLink: { baseUrl: '<repo>/edit/<default-branch>/' }`; if not, leave the commented-out scaffold in place and tell the user how to fill it in.
235
+
236
+ Both items 4 and 5 are cheap, high-impact contributor-loop wins per the Astro/Starlight best-practices guide — default to enabling them unless the user opts out.
237
+
238
+ ### Phase 9 — Configure logo
239
+
240
+ Two surfaces need updating:
241
+
242
+ **a) Topbar logo — `astro.config.mjs` `starlight.logo`**
243
+
244
+ First, look at what Phase 6 detected. Three branches:
140
245
 
141
- ### Phase 8Write configs
246
+ 1. **Phase 6 found a light/dark pair** (e.g. `logo-light.svg` + `logo-dark.svg`) → use the `{ light, dark }` form. Starlight auto-switches based on `data-theme`. Don't ask which to use as the default both render at the right time.
247
+
248
+ 2. **Phase 6 found a single mark** → use the single-`src` form. Optionally suggest the user create a dark variant later if the mark is colored in a way that won't survive a dark background.
249
+
250
+ 3. **Phase 6 found nothing** → leave the existing commented `// logo: { ... }` block in `astro.config.mjs` and tell the user where to drop a logo file.
251
+
252
+ Then ask one final question (skip if you already know): does the logo include the project name as text/wordmark?
253
+
254
+ - **Yes** (logo + wordmark in one image) → `replacesTitle: true` — Starlight hides the text title and shows just the logo.
255
+ - **No** (just a mark/icon, no text) → `replacesTitle: false` — Starlight shows the mark beside the text title.
256
+
257
+ Then write the config:
258
+
259
+ ```js
260
+ // Single mark
261
+ logo: {
262
+ src: './src/assets/logo.svg',
263
+ replacesTitle: false,
264
+ }
265
+
266
+ // Light/dark pair (preferred when Phase 6 found both files)
267
+ logo: {
268
+ light: './src/assets/logo-light.svg',
269
+ dark: './src/assets/logo-dark.svg',
270
+ replacesTitle: true,
271
+ }
272
+ ```
273
+
274
+ If a `logo:` block already exists in the config, edit it in place — don't add a duplicate. If `logo:` is in a comment or commented-out, uncomment and update.
275
+
276
+ **b) Splash hero image — `src/content/docs/index.mdx` `hero.image.file`**
277
+
278
+ Default Starlight splash hero supports a separate (usually larger) image. Check the existing `index.mdx` frontmatter:
279
+
280
+ ```yaml
281
+ hero:
282
+ image:
283
+ file: ../../assets/hero-mark.png
284
+ alt: <project name>
285
+ ```
286
+
287
+ If a hero candidate was identified in Phase 6, update this path. If the same logo serves both roles, point both at the same file. If the user wants to use the branded `<Hero>` MDX component (richer than the frontmatter hero), point them at the migration guide section that covers it.
288
+
289
+ **Verify after writing:**
290
+
291
+ After both surfaces are updated, encourage the user to run `bun dev` and visually confirm the logo renders correctly in both light and dark modes (toggle from the topbar). Common issues:
292
+ - Logo is white-on-white in light mode → need a dark variant or use the `light`/`dark` pair pattern
293
+ - Logo is way too small/large → adjust the source dimensions or add CSS overrides via `customCss`
294
+ - File path is wrong → relative paths in `astro.config.mjs` are relative to the project root, not the file itself
295
+
296
+ ### Phase 10 — Write configs
142
297
 
143
298
  Show diffs in your reasoning before writing.
144
299
 
145
- **a) `scripts/python-autodoc.json`** resolve searchPath relative to the docs project root. If file exists, merge: keep outputDir, replace searchPath/modules.
300
+ #### a) `scripts/python-autodoc.json` (if Python wired up)
146
301
 
147
302
  ```json
148
303
  {
@@ -152,116 +307,255 @@ Show diffs in your reasoning before writing.
152
307
  }
153
308
  ```
154
309
 
155
- **b) `astro.config.mjs`** two edits:
156
- 1. Ensure sidebar has `{ label: 'API Reference', autogenerate: { directory: 'api' } }`. Don't duplicate.
157
- 2. Update the `abstractData(...)` call's `motion`/`credit`/`version`. Preserve other options.
310
+ #### b) `scripts/ts-autodoc.json` (if TypeScript wired up)
158
311
 
159
- **c) `package.json`** — ensure `scripts["docs:python"]` is `"node scripts/build-python-docs.mjs"`.
312
+ ```json
313
+ {
314
+ "entryPoints": [...],
315
+ "tsconfig": "<relative path>",
316
+ "outputDir": "src/content/docs/api/ts"
317
+ }
318
+ ```
160
319
 
161
- **d) `scripts/build-python-docs.mjs`** — should already exist from the template. If missing, tell the user to scaffold a fresh project via `bun create @abstractdata/docs` and copy it over.
320
+ #### c) `astro.config.mjs`
162
321
 
163
- ### Phase 9 — Optionally run
322
+ Multi-edit:
164
323
 
165
- an interactive prompt: generate API pages now?
166
- - "Yes, run bun run docs:python" (Recommended)
167
- - "No, I'll run it later"
324
+ 1. Sidebar ensure entries exist for each enabled generator:
325
+ - `{ label: 'Python API', autogenerate: { directory: 'api' } }` — if Python
326
+ - `{ label: 'TypeScript API', autogenerate: { directory: 'api/ts' } }` — if TS
327
+ 2. Plugin call — update `motion`/`credit`/`version` from Phase 8.
328
+ 3. Logo — update `logo.src` from Phase 9.
168
329
 
169
- If yes, invoke via Bash. Pass through any pydoc-markdown install instructions verbatim if missing.
330
+ Don't duplicate sidebar entries. Don't add a second `abstractData(...)` plugin call.
170
331
 
171
- ### Phase 10 — Offer pre-commit hook in source project
332
+ #### d) `package.json`
172
333
 
173
- Only run this phase if Phase 4 found at least one module below 80% coverage. Otherwise skip.
334
+ Add scripts conditionally:
335
+ - `"docs:python": "node scripts/build-python-docs.mjs"` — if Python wired up
336
+ - `"docs:ts": "node scripts/build-ts-docs.mjs"` — if TS wired up
174
337
 
175
- an interactive prompt:
338
+ Update the `build` script to chain them:
339
+ ```json
340
+ "build": "bun run docs:python && bun run docs:ts && astro check && astro build"
341
+ ```
342
+ (Skip the chains for stacks not enabled.)
343
+
344
+ #### e) Required dev deps for TS
176
345
 
346
+ If TS wired up, add to dev deps:
347
+ ```bash
348
+ bun add -d typedoc typedoc-plugin-markdown
177
349
  ```
178
- Want me to add a docstring-coverage pre-commit hook to your source project at <path>?
179
- - "Yes, install interrogate hook" (Recommended)
180
- - "Yes, but with a lower threshold (60%)" — for projects that need to ramp up
181
- - "No, skip"
350
+
351
+ Tell the user to run this; don't run it yourself.
352
+
353
+ #### f) Tailor `src/content/docs/quickstart.md` to the detected stack
354
+
355
+ The scaffolded `quickstart.md` ships with both Python and TypeScript autodoc subsections wrapped in HTML comment markers:
356
+
357
+ ```html
358
+ <!-- abstract-data-setup:python-autodoc -->
359
+ …Python instructions…
360
+ <!-- /abstract-data-setup:python-autodoc -->
361
+
362
+ <!-- abstract-data-setup:ts-autodoc -->
363
+ …TypeScript instructions…
364
+ <!-- /abstract-data-setup:ts-autodoc -->
182
365
  ```
183
366
 
184
- If yes:
367
+ After you've finalized the stack(s) for this project (Phase 7), edit `quickstart.md` to remove the irrelevant block:
185
368
 
186
- 1. Check for existing `.pre-commit-config.yaml` in the source project root.
187
- 2. If absent, create:
369
+ - **Python only** strip everything between `<!-- abstract-data-setup:ts-autodoc -->` and `<!-- /abstract-data-setup:ts-autodoc -->` (inclusive).
370
+ - **TypeScript only** → strip the Python block similarly.
371
+ - **Both** → leave both blocks; remove only the comment markers themselves so the published page is clean.
372
+ - **Neither** (no autodoc wired up) → strip both blocks plus the "## Add API reference" heading and intro paragraph.
188
373
 
189
- ```yaml
190
- repos:
191
- - repo: https://github.com/econchick/interrogate
192
- rev: 1.7.0
193
- hooks:
194
- - id: interrogate
195
- args: [--fail-under=80, -v, src/]
374
+ This is idempotent: re-runs of the skill check whether the markers still exist before pruning. If the user has already removed the markers (or hand-edited the file), leave it alone — never re-inject content into a customized quickstart.
375
+
376
+ ### Phase 11 — Optionally run generators
377
+
378
+ Per enabled generator, ask: "Generate now? [Yes / No]"
379
+
380
+ - Python → `bun run docs:python`
381
+ - TypeScript → `bun run docs:ts`
382
+
383
+ Pass through any tool-not-installed errors verbatim.
384
+
385
+ ### Phase 11.5 — Offer docs-author dispatch (if generators ran)
386
+
387
+ After generation, scan `src/content/docs/api/` for **thin pages** — auto-generated files whose body (after frontmatter and the auto-rendered H1) is fewer than ~200 bytes, OR pages that consist of just signatures with no descriptive prose. These are the "what the heck is this?" pages — the source's docstrings are too sparse for the mechanical autodoc to produce useful output.
388
+
389
+ If any thin pages are found, surface this to the user:
390
+
391
+ > "I noticed N of the generated API pages are sparse — your source's docstrings are thin. The companion skill `abstract-data-docs-author` reads the source code itself and writes narrative prose to enrich those pages (module overview, usage example from tests, related-modules cross-references). Want me to invoke it now?"
392
+
393
+ If yes: hand off to the `abstract-data-docs-author` skill (Claude Code: load the skill at `.claude/skills/abstract-data-docs-author/SKILL.md`; Cursor: refer to `.cursor/rules/abstract-data-docs-author.mdc`). Pass along the project profile and detected stack info so the docs-author skill doesn't have to re-discover.
394
+
395
+ If no thin pages found, skip this phase silently. Don't push the docs-author skill on a project that doesn't need it.
396
+
397
+ ### Phase 11.7 — Versioned API reference (only if source has 2+ tags)
398
+
399
+ Run `git -C <source-repo> tag --list 'v*' | wc -l` (or equivalent) on the **source** repo (not the docs project). If the result is < 2, skip this phase silently.
400
+
401
+ Otherwise, surface the choice:
402
+
403
+ > "I see your source has N tagged releases. Versioned API reference is supported four ways. Which do you want?"
404
+
405
+ Multi-choice prompt:
406
+
407
+ 1. **Source-driven (Recommended for API-only versioning).** Adds a `versions` array to `python-autodoc.json` / `ts-autodoc.json`. Each rebuild checks out the source repo at each tag (via `git worktree add`), regenerates the API reference per tag into `<outputDir>/<safeTag>/`, and aliases the default version at the un-versioned URL. Cheap, composable, no branches to maintain. The bundled `<VersionPicker>` component renders a topbar dropdown.
408
+ 2. **`starlight-versions` plugin** — opinionated, archives the entire site (guides + API). Pick this only if guides drift between versions too. Pre-1.0; expect rough edges.
409
+ 3. **Branch-per-version** — each major version is a git branch deployed to a subdomain, the main branch's host (Vercel/CF) rewrites `/v2/*` → that subdomain. Best when teams already maintain per-version branches.
410
+ 4. **Single version (no versioning).** Default if the user is unsure. Easy to add versioning later.
411
+
412
+ Default the recommendation to **option 1** when the project has Python or TypeScript autodoc wired (Phases 4/5 ran). Default to **option 2** when the docs project has substantial hand-written guides and the user expects them to differ per version.
413
+
414
+ If the user picks option 1:
415
+
416
+ a. Surface up to the 5 most recent tags as candidates. Ask which to publish — let them deselect noisy point releases. Mark the most recent as `default: true` unless the user picks a different one (e.g. an LTS tag).
417
+
418
+ b. Write the `versions` array into the appropriate autodoc JSON config. Example shape:
419
+
420
+ ```jsonc
421
+ {
422
+ "searchPath": "../../auditkit/src",
423
+ "modules": [...],
424
+ "outputDir": "src/content/docs/api",
425
+ "versions": [
426
+ { "tag": "v0.4.0", "label": "0.4 (latest)", "default": true },
427
+ { "tag": "v0.3.2", "label": "0.3" },
428
+ { "tag": "v0.2.0", "label": "0.2 (legacy)" }
429
+ ]
430
+ }
196
431
  ```
197
432
 
198
- 3. If present, append the interrogate hook to the `repos` array. Don't duplicate if already present.
199
- 4. Add `interrogate` to dev deps:
200
- - `pyproject.toml` — add to `[project.optional-dependencies] dev` if that table exists
201
- - `requirements-dev.txt` — append if it exists
202
- - Otherwise mention to the user that they need to install it manually
203
- 5. Tell the user to run `pre-commit install` in the source project root to activate the hook (don't run it yourself — that's the source repo, not the docs repo, and it modifies their git hooks).
433
+ c. **No override needed.** The `abstractData()` plugin already overrides `SocialIcons` to render `<VersionPicker>` next to the existing chip and social links. As soon as the autodoc orchestrator emits per-version pages with `version:` frontmatter, the picker appears in the topbar automatically — no user-side wiring, no `versions` prop to maintain. The picker walks the docs collection at build time, dedupes by tag, picks up the `versionDefault: true` flag for the default version. The autodoc JSON is the single source of truth.
204
434
 
205
- ### Phase 11 Summary
435
+ If the autodoc base path differs from the default `/api` (e.g. `outputDir: "src/content/docs/api/ts"` for TypeScript-only sites), pass `apiBase` to the plugin so the picker constructs the right URLs:
206
436
 
207
- Print a 6–10 line markdown summary:
437
+ ```js
438
+ starlight({
439
+ plugins: [
440
+ abstractData({
441
+ motion: 'calm',
442
+ apiBase: '/api/ts',
443
+ }),
444
+ ],
445
+ })
446
+ ```
208
447
 
448
+ d. **Verify the docs project's content schema accepts the version frontmatter fields.** Read `src/content.config.ts` and confirm the `docsSchema.extend` zod object includes:
449
+
450
+ ```ts
451
+ version: z.string().optional(),
452
+ versionLabel: z.string().optional(),
453
+ versionDefault: z.boolean().optional(),
209
454
  ```
210
- ## Set up complete
211
-
212
- **Configured for**: <package> at <path>
213
- **Modules**: <count> · <green/yellow/red breakdown>
214
- **Docstring style**: <style> (<confidence>)
215
- **Mode**: <motion> · <credit> · <version chip status>
216
-
217
- **Files updated**:
218
- - scripts/python-autodoc.json
219
- - astro.config.mjs
220
- - package.json
221
- <if hook installed:>
222
- - <source-path>/.pre-commit-config.yaml (added interrogate hook)
223
- - <source-path>/pyproject.toml (added interrogate to dev deps)
224
-
225
- <if Phase 9 ran:>
226
- **Generated**: <count> API pages in src/content/docs/api/
227
-
228
- **Next**:
229
- 1. `bun dev`
230
- 2. Visit /api/ to see the generated pages
231
- 3. Address any red-coverage modules in your source, then re-run `bun run docs:python`
232
- <if hook installed:>
233
- 4. `cd <source-path> && pre-commit install` to activate the docstring hook
455
+
456
+ The `create-docs` template scaffold already ships with these. For projects upgraded via `bunx abstract-data-install-skills`, you'll need to add them — without these optional fields, Zod will reject the autodoc-emitted frontmatter and the build fails with `InvalidContentEntryDataError`.
457
+
458
+ e. Tell the user to run `bun run docs:python` (or `docs:ts`) to populate the per-version directories. The script handles the worktrees automatically.
459
+
460
+ f. **Optional curated override.** If the user wants to hide pre-release tags or reorder the dropdown, they can wire a user-level override of `SocialIcons` that imports `<VersionPicker>` and passes an explicit `versions` prop — that bypasses auto-discovery. Don't recommend this by default; auto-discovery keeps the autodoc JSON as the single source of truth.
461
+
462
+ If the user picks option 2 (`starlight-versions`):
463
+
464
+ - Install: `bun add starlight-versions`
465
+ - Add to `astro.config.mjs` plugins array
466
+ - Run the plugin's CLI to archive the current state
467
+ - Configure `starlight-versions.versions` to match the user's version list
468
+ - Note: this conflicts with option 1 — pick *one*.
469
+
470
+ If the user picks option 3 (branch-per-version):
471
+
472
+ - This is mostly a deployment-platform concern. Suggest the Knip pattern (Vercel rewrites) and link them at [webpro.nl/scraps/versioned-docs-with-starlight-and-vercel](https://webpro.nl/scraps/versioned-docs-with-starlight-and-vercel). Don't try to wire this yourself — too platform-specific.
473
+
474
+ If the user picks option 4 (none): skip silently, leave `versions` field absent from the autodoc config.
475
+
476
+ **Site version vs. API version** they're different. The `version` chip in the theme's plugin call (e.g. `version: 'v1.0.0'`) is the *site's own* marketing version. The `versions` array in autodoc configs is the *documented API's* versions. A site might be at `v1.2.0` while documenting API `v0.4.0` — that's normal, don't conflate them.
477
+
478
+ ### Phase 12 Optional pre-commit hook (per-stack)
479
+
480
+ Fires only if Phase 4a (Python) or Phase 5a (TypeScript) found modules below the 80% coverage threshold.
481
+
482
+ **Python branch** — if Phase 4a found yellow/red modules, offer:
483
+
484
+ - Tool: `interrogate` (lightweight, no project changes beyond the hook entry).
485
+ - Config: append a `[tool.interrogate]` table to `pyproject.toml` setting `fail-under = 80`, `exclude = ["tests"]`, etc.
486
+ - `.pre-commit-config.yaml`: add the `econchick/interrogate` repo with the chosen revision.
487
+
488
+ **TypeScript branch** — if Phase 5a found yellow/red entry points, offer either:
489
+
490
+ - **Local script hook (preferred)**: a one-liner `pre-commit` config that runs the docs build script with `--validation.notDocumented` and fails the commit if any new warnings appear. No extra dependencies beyond `typedoc` (already a dev dep).
491
+
492
+ ```yaml
493
+ # .pre-commit-config.yaml fragment
494
+ - repo: local
495
+ hooks:
496
+ - id: tsdoc-coverage
497
+ name: TSDoc coverage
498
+ entry: bunx typedoc --plugin typedoc-plugin-markdown --validation.notDocumented --treatValidationWarningsAsErrors true --emit none
499
+ language: system
500
+ types: [ts]
501
+ pass_filenames: false
502
+ ```
503
+
504
+ - **`tsdoc-coverage` package** (if the user prefers a dedicated tool): npm install `tsdoc-coverage` as a dev dep and wire it as the hook entry instead. Threshold defaults to 80% to match the Python side.
505
+
506
+ In both stacks: show the user the exact config diff before writing. The pre-commit hook lives in the **source repo**, not the docs repo — extra caution since it's a different project.
507
+
508
+ ### Phase 12.5 — Confirm `starlight-links-validator` is wired
509
+
510
+ The template ships with `starlight-links-validator` already installed and registered as a Starlight plugin. Verify both during this phase:
511
+
512
+ 1. Read the docs project's `package.json` — confirm `starlight-links-validator` is in `dependencies` (or `devDependencies`).
513
+ 2. Read `astro.config.mjs` — confirm the plugin is referenced inside `plugins: [...]` on the `starlight(...)` call.
514
+ 3. Read the docs project's CI workflow (`.github/workflows/*.yml` or equivalent) — confirm `bun run build` (or `astro build`) runs on PRs. The links validator runs as part of the build, so a build-on-PR workflow is enough; no separate step needed.
515
+
516
+ If any of those three pieces are missing, surface the gap and offer to add it. The plugin's failure mode is "fail the build on any broken internal link" — exactly what you want for CI.
517
+
518
+ For migrating projects (running `bunx abstract-data-install-skills` rather than scaffolding via `bun create @abstractdata/docs`), the plugin will not be installed automatically. Tell the user:
519
+
520
+ ```bash
521
+ bun add starlight-links-validator
234
522
  ```
235
523
 
524
+ then add `starlightLinksValidator()` to the `plugins` array in `astro.config.mjs`. Show the diff.
525
+
526
+ ### Phase 13 — Summary
527
+
528
+ 6–10 line markdown summary covering: detected stacks, what got wired up per stack, logo update, mode (motion/credit/version), files updated, generated counts (if Phase 11 ran), next steps.
529
+
236
530
  ## Idempotency
237
531
 
238
532
  - Don't duplicate sidebar entries — check before adding.
239
- - Don't append to `modules` array — replace cleanly.
533
+ - Don't append to `modules`/`entryPoints` arrays — replace cleanly.
240
534
  - Don't add a second `abstractData(...)` call — update the existing one.
241
- - Don't add a second interrogate hook to `.pre-commit-config.yaml` — check first.
242
535
  - Don't overwrite content under `src/content/docs/` (only `api/` pages, regenerated by the script).
536
+ - Don't add a second logo line — replace.
243
537
 
244
538
  ## Out of scope (this round)
245
539
 
246
- - TypeScript/TypeDoc autodoc
247
- - Next.js / TanStack / OpenAPI / Prisma / Drizzle
248
- - Architecture diagrams
249
- - README/CHANGELOG/ADR import
250
- - Forcing the docs build to fail on coverage drop (deliberate — coverage policy belongs to the source project's pre-commit hook, not the docs build)
251
- - Auto-applying a pydoc-markdown processor pipeline based on detected style (CLI doesn't support it; would require switching to YAML config)
540
+ - TanStack route detection auto-config (recipe-only)
541
+ - Next.js route map auto-config (recipe-only)
542
+ - Prisma schema-doc auto-config (recipe-only)
543
+ - Drizzle schema-doc auto-config (recipe-only — no mature tooling)
544
+ - README/CHANGELOG/ADR auto-import into the sidebar
252
545
 
253
546
  ## Files this skill reads / writes
254
547
 
255
- **Reads:** docs project's `package.json`, `astro.config.mjs`; source project's `pyproject.toml`, `setup.py`, source tree, existing `.pre-commit-config.yaml`.
548
+ **Reads (docs project):** `package.json`, `astro.config.mjs`, `src/assets/`.
549
+ **Reads (source project):** `pyproject.toml`, `setup.py`, source tree, `tsconfig.json`, `next.config.*`, dependency manifests, schema files, OpenAPI specs.
256
550
 
257
- **Writes (docs project):** `scripts/python-autodoc.json`, `astro.config.mjs` (edits), `package.json` (scripts only).
551
+ **Writes (docs project):** `scripts/python-autodoc.json`, `scripts/ts-autodoc.json`, `astro.config.mjs` (edits), `package.json` (scripts only).
258
552
 
259
- **Writes (source project, only with Phase 10 consent):** `.pre-commit-config.yaml`, `pyproject.toml` (dev deps section), `requirements-dev.txt`.
553
+ **Writes (source project, with explicit pre-commit consent only):** `.pre-commit-config.yaml`, `pyproject.toml` (dev deps section), `requirements-dev.txt`, or `package.json` (TS dev deps for `tsdoc-coverage` if chosen).
260
554
 
261
555
  ## Notes for the agent
262
556
 
263
557
  - Be conservative with edits. Show diffs in your reasoning before writing.
264
- - Use `Edit` for in-place updates. Use `Write` for `python-autodoc.json` (full replace).
265
- - Phase 10 modifies a different repo than the docs project extra caution. Show the user exact diffs before applying.
266
- - If interrogate isn't installed in the source's Python env, the audit falls back to AST. Note in the summary that interrogate would give richer reports.
558
+ - Phase 12 modifies a different repo than the docs project — extra caution.
559
+ - For TypeScript: TypeDoc requires `typescript` AND `typedoc` AND `typedoc-plugin-markdown`. If any are missing, the orchestrator will tell the user via the script output. Don't try to install them yourself unless the user explicitly asks.
560
+ - For OpenAPI: prefer `@astrojs/starlight-openapi` (mature plugin) over building from scratch.
267
561
  - Keep conversation tight: detection in 1–3 sentences, audit table 5–8 lines, questions one round at a time, summary 6–10 lines.