Author, restructure, or update documentation for the Astro/Starlight docs site. Covers ADDING a new docs page or route (MDX + sidebar registration in astro.config.mjs + llms.txt/llms-full.txt inclusion), which prose/MDX and API-reference docs to check after a code change, how to write them, the `<Audience>` and `llmsFull` curation knobs, and regenerating typedoc API docs. Use whenever you create, move, rename, or edit any file under apps/docs/, or after any feature, fix, or refactor that touches user-visible behaviour. (For building a new interactive demo component, use the astro-demo skill instead.)
Installation
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Author, restructure, or update documentation for the Astro/Starlight docs site. Covers ADDING a new docs page or route (MDX + sidebar registration in astro.config.mjs + llms.txt/llms-full.txt inclusion), which prose/MDX and API-reference docs to check after a code change, how to write them, the `<Audience>` and `llmsFull` curation knobs, and regenerating typedoc API docs. Use whenever you create, move, rename, or edit any file under apps/docs/, or after any feature, fix, or refactor that touches user-visible behaviour. (For building a new interactive demo component, use the astro-demo skill instead.)
argument-hint
optional what-changed description
Documentation Update Guide
Use this skill whenever you touch docs — authoring a brand-new page/route, restructuring or moving pages, or syncing existing docs after a code change. It is the authoritative reference for the docs site's structure, navigation, and the autogenerated LLM corpus — read it before writing, not only as a post-change checklist.
Adding or moving a page? Start at Adding a new docs page — it covers the steps that are easy to miss (sidebar registration, llmsFull inclusion, redirects).
llms.txt / llms-full.txt are autogenerated — never hand-edit them. Both are built at docs-build time by the Astro endpoints apps/docs/src/pages/llms.txt.ts and llms-full.txt.ts from the curated MDX/MD doc pages, the demo .astro sources, and JSDoc-derived TypeDoc MDX. You influence their content only by editing those sources — which makes keeping the MDX/curated/source docs accurate more important than before, not less. See Where LLM-file content comes from for the few curation knobs (page frontmatter, ordering, agent preamble). This skill does not manually update the root llms.txt / llms-full.txt.
Adding a New Docs Page
Adding a page is more than dropping an .mdx file — the page is invisible until you register it in the sidebar, and it silently joins the LLM corpus unless you opt it out. Work through all five steps:
Create the MDX page under apps/docs/src/content/docs/grid/ (or a subfolder like grid/plugins/, grid/guides/). Every page needs frontmatter title and description (the description is reused as the page's link blurb in llms.txt). Follow the conventions in How to Write Each Doc Type.
Register it in the sidebar — this is the step most easily forgotten. The navigation tree is hand-curated in apps/docs/astro.config.mjs under starlight({ sidebar: [...] }). A new page does not appear automatically unless it lands in a folder covered by an autogenerate: { directory: ... } entry (currently only grid/guides, grid/plugins, and the TypeDoc grid/api/** trees). For a top-level or curated page, add an explicit entry to the matching group:
// apps/docs/astro.config.mjs → integrations → starlight → sidebar → 'Grid' group
{ label: 'Introduction', slug: 'grid/introduction' },
{ label: 'AI Assistance', slug: 'grid/ai' }, // ← your new page (slug = path under content/docs/, no extension)
To create a brand-new collapsible section, push a { label, collapsed, items: [...] } object instead. Match the placement to the page's audience (top-level conceptual pages go in the Grid group near Introduction/Getting Started).
Decide LLM-corpus inclusion — by default every prose page is inlined into llms-full.txt and linked in llms.txt. Opt a page out of the full corpus (kept in the index, removed from the inlined dump) with frontmatter llmsFull: false. Use this for pages that teach an agent nothing about building with the grid — e.g. release history. Current opt-outs: grid/changelog.mdx and the three adapter changelog.mdx pages. For a page where only part of the content is human- or agent-only, prefer per-block <Audience> regions instead (see Audience-targeted content).
Place it in the generated ordering (only if it's a new top-level slug or a new section). apps/docs/src/pages/_llm-sources.ts controls how the generated files group and order pages: sectionOf() classifies a slug into a section, and CORE_ORDER sets the reading order for top-level grid/* pages. A new grid/<name>.mdx page that isn't listed in CORE_ORDER sorts to the alphabetical tail of "Core Documentation" — add it to CORE_ORDER if it needs a specific position.
If you moved or renamed a page, add a redirect in astro.config.mjs (redirects: { '/grid/old-path/': '/grid/new-path/' }) so inbound links and bookmarks keep working, and update any internal links per the Internal-link rules.
Then build and run the link check (see Verification).
Quick Decision Matrix
The matrix is grouped by change category. If your change spans multiple categories, apply each matching row — there is no precedence ordering between groups (you update all matching surfaces). The LLM files are intentionally absent: updating the MDX/source docs below regenerates them automatically.
Code / API changes
What Changed
Update These Docs
New public API
api-reference.mdx, regenerate TypeDoc
New event
api-reference.mdx, plugin .mdx if plugin-specific, JSDoc on DataGridEventMap
Breaking change
CHANGELOG (migration guide), affected MDX
Plugin changes
What Changed
Update These Docs
New plugin
Plugin README, plugin .mdx, plugins/index.mdx
Plugin config change
Plugin .mdx, plugin README, plugin JSDoc
Adapter changes
What Changed
Update These Docs
New adapter feature
Adapter README, adapter MDX docs
Theming / styling changes
What Changed
Update These Docs
New CSS variable
theming.mdx, grid.css registry comment
Workspace / tooling changes
What Changed
Update These Docs
Workflow/convention change
.github/copilot-instructions.md, AGENTS.md
New skill or tooling
.github/skills/, AGENTS.md if Nx-related
Documentation Inventory
Hand-Written (update manually)
Category
Location
When to Update
Grid README
libs/grid/README.md
New features, API changes, install instructions
Adapter READMEs
libs/grid-{angular,react,vue}/README.md
Adapter feature changes
Plugin READMEs
libs/grid/src/lib/plugins/*/README.md
Plugin feature changes
Core MDX docs
apps/docs/src/content/docs/grid/*.mdx
Core features, theming, architecture, getting started
Plugin MDX docs
apps/docs/src/content/docs/grid/plugins/*.mdx
Plugin features, config options, examples
Adapter MDX docs
apps/docs/src/content/docs/grid/adapters/*.mdx
Framework-specific usage, examples
Demo components
apps/docs/src/components/demos/**/*.astro
New demos, interactive feature showcases
Copilot instructions
.github/copilot-instructions.md
Workflow, conventions, architecture changes
Agent instructions
AGENTS.md
Nx or workspace convention changes
Contributing guide
CONTRIBUTING.md
Development workflow changes
Architecture doc
libs/grid/ARCHITECTURE.md
Internal design changes
Auto-Generated (regenerate, don't hand-edit)
Category
Generated By
Command / Trigger
LLM index (llms.txt)
apps/docs/src/pages/llms.txt.ts
bun nx build docs
LLM full guide (llms-full.txt)
apps/docs/src/pages/llms-full.txt.ts
bun nx build docs
TypeDoc API pages
typedoc-to-mdx.ts scripts
bun nx typedoc <project>
CHANGELOGs
release-please
Automatic on release PR
Custom elements manifest
@custom-elements-manifest/analyzer
bun run cem
The LLM files are derived from the MDX/MD doc pages, the demo .astro sources, and the JSDoc-generated TypeDoc MDX — so they stay in sync automatically when you update those sources. Never hand-edit the root llms.txt / llms-full.txt.
How to Write Each Doc Type
Multi-Path Features
When a feature has multiple configuration paths (e.g., CSS vs JS, declarative vs programmatic), apply this checklist to every documentation file that has a dedicated section explaining that feature, a configuration table for it, or a code example using it (not merely a passing hyperlink or index entry) (i.e. the feature's plugin/core MDX page, its README, and any adapter MDX page that documents it in detail). You do not need to touch unrelated documentation files. (The LLM files pick up the change automatically once the MDX is updated.)
For each such file, complete all four steps in order:
State that both paths exist — even if the file only covers one in detail.
Explain when to use which — include a comparison table with trade-offs.
Cross-reference — link to the other doc surface that covers the other path in detail.
Identify the recommended default — guide developers toward the simpler path unless they have specific needs.
Apply this to: icons (CSS vars vs gridConfig.icons), column config (declarative <tbw-grid-column> vs JS columns), features (declarative features vs manual plugins), styling (CSS custom properties vs registerStyles() vs cellClass/rowClass), etc.
Plugin MDX (.mdx)
Plugin MDX pages live in apps/docs/src/content/docs/grid/plugins/. Structure:
---
title: Plugin Name
description: One-line description.
---
import PluginDefaultDemo from '@components/demos/plugin-name/PluginNameDefaultDemo.astro';
import ShowSource from '@components/ShowSource.astro';
## Installation
\`\`\`typescript
import { MyPlugin } from '@toolbox-web/grid/plugins/my-plugin';
\`\`\`
## Basic Usage
<ShowSource component="plugin-name/PluginNameDefaultDemo">
<PluginDefaultDemo />
</ShowSource>
## Configuration
Auto-generated from the plugin's config interface by \`genPluginConfigTable()\`.
## Events
| Event | Detail | Description |
| ----- | ------ | ----------- |
## API
Public methods and properties.
Plugin JSDoc conventions for auto-generated API docs:
## Configuration Options tables are auto-generated from the constructor's config interface — do not hand-write them in JSDoc
## Programmatic API tables are redundant with auto-generated Methods — do not hand-write them in JSDoc
Use {@link TypeName} in hand-written sections (Column Configuration, CSS Custom Properties, Events) to cross-link types
Run bun nx typedoc grid after changing JSDoc to regenerate MDX
Plugin README (README.md)
Keep concise — links to docs site for live examples:
# @toolbox-web/grid — Plugin Name
Brief description.
## Usage
\`\`\`typescript
import { MyPlugin } from '@toolbox-web/grid/plugins/my-plugin';
\`\`\`
## Options
| Option | Type | Default | Description |
| ------ | ---- | ------- | ----------- |
## Documentation
See the [docs site](https://toolboxjs.com/grid/plugins/my-plugin/) for live examples.
Where LLM-file content comes from
llms.txt (concise index) and llms-full.txt (full guide) are autogenerated at docs-build time by apps/docs/src/pages/llms.txt.ts and llms-full.txt.ts. Do not hand-edit the root files — they are derived from:
Source
Drives
MDX/MD pages under apps/docs/src/content/docs/grid/**
Prose body of llms-full.txt; link entries in llms.txt
Demo .astro under apps/docs/src/components/demos/**
Inlined <script> code blocks in llms-full.txt
JSDoc → TypeDoc MDX
The linked ## API Reference index (per-symbol .md pages)
libs/grid/src/lib/data/css-variable-registry.*
The CSS-variables reference block
So updating the MDX/curated/source docs is how you update the LLM files — keep them accurate and the generated files follow automatically. The only manual curation knobs (touch these only when adding/removing pages or changing ingestion behaviour, not for routine content):
<Audience only="human|agent"> regions inside a page — split a single page's content by consumer (see Audience-targeted content below). This is the content-level knob; the three below are page-level / global.
Page frontmatter llmsFull: false — omits a page from the llms-full.txt corpus while keeping it linked in llms.txt (used for pages that teach an agent nothing about building with the grid — currently the changelog.mdx pages). See _llm-markdown.ts.
Ordering & section maps in apps/docs/src/pages/_llm-sources.ts — CORE_ORDER, SECTION_ORDER, API_AREA_ORDER, sectionOf(), apiAreaOf(). Adjust when a new doc section/area needs explicit placement.
Agent preamble in apps/docs/src/pages/_llm-agent-preamble.ts — the hand-authored RULE 0 / critical-rules / anti-patterns block prepended to both files. Keep it in sync with the human docs it summarises (Getting Started, Plugins Overview) when those rules change.
To verify the generated output after a docs change, run bun nx build docs and inspect the emitted /llms.txt and /llms-full.txt.
Audience-targeted content
<Audience> (apps/docs/src/components/Audience.astro) lets one MDX page carry content meant for only one consumer. Import it in the page's frontmatter (import Audience from '@components/Audience.astro';) and wrap a block:
<Audience only="agent">
_## Steering heading (note the `_` prefix — see authoring rules)
Steering directive / extra gotcha / copy-paste recipe that helps a code-generating agent.
</Audience>
<Audience only="human">
## Steering heading (plain `##` — renders on the site)
Motivational aside, marketing prose, or screenshot-driven walkthrough that would only dilute agent guidance.
</Audience>
The two paths are independent: the HTML behaviour is in Audience.astro, the corpus behaviour is in resolveAudienceRegions() (apps/docs/src/pages/_llm-markdown.ts).
When to reach for it — use <Audience> for a portion of an otherwise-shared page. For a whole page that should stay out of the agent corpus, use frontmatter llmsFull: false instead.
Use only="agent" for…
Use only="human" for…
Front-loaded "do X, never Y" steering directives the rendered page shouldn't repeat
Marketing/motivational prose, "why you'll love this" framing
Extra failure-mode gotchas and edge cases that would clutter the human page
Screenshot/GIF-driven walkthroughs that don't translate to text
Explicit anti-patterns ("don't add SelectionPlugin just to make a row clickable")
Calls-to-action, links to live demos/playgrounds
Authoring rules (enforced by the regex transform):
Leave a blank line after the opening tag and before the closing tag so MDX parses the children as Markdown blocks.
Headings inside only="agent" blocks must be prefixed with _ — write _## Heading, not ## Heading. Starlight harvests real ## headings into the human page's table-of-contents at compile time (before the runtime conditional render), so a bare ## in an agent-only block leaks a phantom TOC link on the human page. The _ sentinel makes it a non-heading for the human build; the agent-markdown transform (out.replace(/^_(#{1,6} )/, …) in _llm-markdown.ts) strips the _ to restore a real, navigable heading in the corpus. The strip runs in prose only, so _# inside a code fence is left intact. (Human-only blocks render normally, so they use plain ##.)
Do not nest<Audience> blocks — the non-greedy match stops at the first </Audience>.
Keep agent-only directives consistent with the human docs they shadow; don't let the two audiences drift into contradicting each other.
After adding/editing an <Audience> block, run bun nx build docs and confirm the agent content lands in /llms-full.txt (and the human content does not, and vice-versa).
Event cancelability changes (the cancelable events table is curated)
Framework-specific listening patterns change
:::note
Individual event descriptions, payload types, and code examples are auto-generated from JSDoc in DataGridEventMap — update the JSDoc, not the curated docs. Run bun nx typedoc grid to regenerate.
:::
Core MDX Docs (apps/docs/src/content/docs/grid/)
File
Contents
index.mdx
Landing page, key features
getting-started.mdx
Installation, first grid setup
api-reference.mdx
Public API reference (properties, methods, events)
theming.mdx
CSS custom properties, theme files
core.mdx
Core features guide (columns, rows, etc.)
custom-plugins.mdx
How to write a plugin
performance.mdx
Performance tips
accessibility.mdx
A11y features
troubleshooting.mdx
Common issues and fixes
demos.mdx
Full-featured demo applications
comparison.mdx
Feature comparison table
architecture.mdx
Internal architecture documentation
Regenerating API Docs
When public API changes (new exports, changed signatures, updated JSDoc):
# Generate TypeDoc JSON and convert to MDX
bun nx typedoc grid
bun nx typedoc grid-angular
bun nx typedoc grid-react
bun nx typedoc grid-vue
Output goes to libs/*/docs/api/ (MDX pages) and libs/*/docs/api-generated/api.json.
Do NOT hand-edit files in docs/api/ or docs/api-generated/ — they are regenerated.
Writing Good JSDoc
JSDoc comments feed into TypeDoc API docs:
/**
* Configuration for the grid component.
*
* @example
* ```typescript
* const config: GridConfig = {
* columns: [{ field: 'name', header: 'Name' }],
* };
* ```
*
* @remarks
* The config is merged with defaults via `mergeEffectiveConfig()`.
*
* @see {@link ColumnConfig} for column-level options
*/exportinterfaceGridConfig { ... }
Key tags:
@example — Code examples (rendered in docs)
@remarks — Extended description
@see — Cross-references
@deprecated — Mark deprecated APIs with migration info
@internal — Exclude from public API docs
@since — Version when feature was added
@category — Routes exports to different TypeDoc sidebar sections (grid core only, see below)
@group — Organizes class members into subsection headings within a page (see below)
@fires — Documents events emitted by a method; collected into Events tables
@category and @group — Controlling API Doc Output
The typedoc-to-mdx.ts scripts convert TypeDoc JSON into MDX pages. Two JSDoc tags control where and how exports appear.
@category and @group are only processed by the grid core script (libs/grid/scripts/typedoc-to-mdx.ts). Adapter scripts use hard-coded name lists instead (see below).
@category — API Doc Routing (Grid Core)
Add @category to top-level exports in types.ts, constants.ts, or grid.ts to control which API docs section they land in. The routing logic lives in processCoreModule():
@category Plugin Development → Grid/API/Plugin Development/{Kind}/{Name}
Any other value or no @category → Grid/API/Core/{Kind}/{Name}
Only Plugin Development and Framework Adapters cause routing changes. Other values (e.g., Data Management, Events) are informational — they still route to Core. Check processCoreModule() in libs/grid/scripts/typedoc-to-mdx.ts for the current routing logic.
DataGridElement split: The DataGridElement class is special-cased by genDataGridSplit() — it produces 3 separate MDX documents by filtering members:
Public API (DataGridElement.mdx) — members without _ prefix, without @internal, without @category Framework Adapters
Plugin API (DataGridElement-PluginAPI.mdx) — _-prefixed members (not __) or @internal Plugin API
Framework Adapters (DataGridElement-Adapters.mdx) — members tagged @category Framework Adapters
When adding a new member to DataGridElement, choose the right tag/prefix to place it in the correct document.
@group — Section Headings Within a Page
Add @group GroupName to class members (accessors, methods) to organize them under headings within a generated MDX page. Currently used on DataGridElement members. The genMembersSectionByGroup() function renders groups in a defined order — check the groupOrder array in that function for the current list. Members without @group fall into a generic section at the end.
When adding a new member, use an existing @group value if it fits. If no group fits, create a new one — it will be appended after the ordered groups. If the new group should appear in a specific position, add it to the groupOrder array in genMembersSectionByGroup().
@internal Modifier — Visibility Control
@internal alone → excluded from all generated docs
@internal Plugin API → included only in the Plugin API document
_ prefix (without @internal) → same as @internal Plugin API by convention
__ prefix → excluded from all docs (deeply internal)
Adapter Scripts — Hard-Coded Categorization
Adapter scripts (libs/grid-{angular,react,vue}/scripts/typedoc-to-mdx.ts) do NOT use @category. They categorize by checking export names against hard-coded lists (e.g., isDirective() checks a directiveNames array in Angular). Each adapter sorts into folders like Directives/, Components/, Hooks/, Types/, Utilities/, etc.
When adding a new export to an adapter: check the script's categorization functions. If your export doesn't match an existing check (e.g., a new Angular directive), add its name to the corresponding list so it lands in the right folder instead of the catch-all Utilities/. After updating the categorization list, run bun nx typedoc grid-<adapter> (e.g., bun nx typedoc grid-angular) to regenerate the adapter API MDX pages.
Verification
After updating docs:
# Verify docs site builds cleanly
bun nx build docs
# Authoritative broken-link gate (NOT an nx target — Astro does NOT fail on broken links)
node .github/skills/docs-update/check-doc-links.mjs
bun nx build docs passing (EXIT=0) does not mean links are valid — Astro silently renders dead links. node .github/skills/docs-update/check-doc-links.mjs is the real gate; it must report "No broken internal links found." If the script reports broken links, fix every broken link in files you modified as part of this change before committing. For a broken link in a file you did not modify, treat it as pre-existing — do not fix it in this change; note the file and line in your PR description so it can be tracked separately.
Internal-link rules (avoid the common 404s)
trailingSlash: 'always' — every internal link MUST end with / (/grid/plugins/shell/, not /grid/plugins/shell).
Anchors must match a real heading slug — grep the target page's ^#{1,4} headings before linking to #some-anchor; renamed/removed headings are a frequent source of dead anchors.
TypeDoc generates NO page for area roots or export const objects.tools/typedoc-mdx-shared.tsKIND_FOLDER_MAP only emits Classes/, Interfaces/, Functions/, Types/ — there is no per-area index page and noVariables/ folder.
✅ link to a concrete generated child page (/grid/api/<area>/<kind>/<symbol>/, slug lowercased), e.g. /grid/api/framework-adapters/interfaces/frameworkadapter/ or /grid/api/plugin-development/classes/basegridplugin/.
Exported const objects (GridClasses, GridDataAttrs, GridSelectors, GridCSSVars in core/constants.ts) are public API but have NO generated page — keep them as inline code, don't link. Only their TYPE aliases (GridClassName, GridDataAttr) get Types/ pages.
Pre-Commit Documentation Review
Before each commit, quickly scan:
Did I change any public API? → Update api-reference.mdx + JSDoc; regenerate TypeDoc
Did I change any plugin? → Update plugin .mdx and README
Did I add/remove CSS variables? → Update theming.mdx, grid.css registry comment
Did I change events? → Update api-reference.mdx, plugin .mdx, JSDoc on DataGridEventMap
Did I change conventions? → Update copilot-instructions.md
The llms.txt / llms-full.txt files are regenerated from the above sources at docs-build time — there is nothing to hand-edit for them.