feat(docs): docs-management pipeline - #396
Conversation
c90ca14 to
2c09db2
Compare
|
/review |
|
✅ API Design Review completed successfully! API Design Review complete — no files matching packages//*.ts, packages//*.tsx, or packages/**/package.json were changed in this PR. The PR adds docs infrastructure (docs-kit concept, .agents/skills, docs-browser, decisions/) but makes no changes to the core packages/ library. No API design issues to report. |
7d2b9c7 to
d07c6b4
Compare
…browser) WIP re-migration onto latest main. One-way source→output docs pipeline; ALL authored sources live under docs-src/; docs/ is generated + drift-gated. - packages/docs-kit: ts-morph type-surface extractor/hasher, coverage reconciler, markdown assembler, no-LLM check/sync CLI + per-unit docs-browser route stubs. Auto prop tables now include a Default column (cva defaultVariants / destructuring / @default) AND Descriptions (prop JSDoc + cva variant-key comments) — complete and drift-proof, with descriptions living in the component source (so consumers get them in hovers / .d.ts too). - docs-browser: AppShell renderer dogfooding Table + Preview/Code Tabs; styled headings + code. Migrated from origin/main so far: button (button.tsx annotated with prop docs). PENDING the same treatment: dialog, data-table, styling, form-modal, list-dense-scan. (These 6 units' old versions are removed in this WIP.) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
d07c6b4 to
c299873
Compare
…can, styling Migrated from origin/main into the docs-src pipeline (prose verbatim; git-mv for lineage). Compound components (dialog, data-table) keep their hand-written sub-component Props tables — the auto <!-- api --> table is now OPT-IN (assemble.ts), so it no longer auto-appends to compound/prose units. dialog + styling carry live examples; form-modal/list-dense-scan recovered from the POC. data-table + styling retain main's full expanded content. resync-docs SKILL wording updated to docs-src. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auto <!-- api --> tables for badge + alert (descriptions moved into source as cva variant-key comments + prop JSDoc; badge/alert.tsx annotated). avatar, card, checkbox retain hand tables (Base UI passthrough / compound sub-component props the extractor can't cover). Each gets a live Basic Usage example. Also broadens data-table `sources` to credit the collection exports (Column/useDataTable/ createColumnHelper/useCollectionVariables) documented in its prose. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…bles Use the prop's syntactic type annotation (e.g. `React.ReactNode`, `React.ReactElement`, `() => void`) instead of the fully-expanded resolved type, with a safety-net collapse for computed React.ReactNode unions. Regenerates button/badge/alert tables with readable types. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All retain hand tables (input/textarea are DOM/Base-UI passthroughs; select/ combobox/autocomplete are Base-UI compound + generic — the extractor can't auto-generate their props). Prose verbatim, git-mv for lineage, each with a live Basic Usage example. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
All compound (Base UI) components — retain hand-written sub-component Props tables, prose verbatim, git-mv for lineage, each with a live Basic Usage example. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ion-card grid/layout/spinner retain hand tables (compound / DOM-svg passthrough). metric-card + description-card use auto <!-- api --> tables — their props already carry JSDoc in source, so descriptions flow with no annotation (description-card example gains the now-required `title`). Live Basic Usage each. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…card, document-progress-card, with-guard action-panel, document-progress-card, with-guard use auto <!-- api --> tables (props already carry JSDoc in source — no annotation). appearance-switcher (no props) + activity-card (compound) retain prose/hand tables. Live examples for appearance-switcher, activity-card, document-progress-card. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…up, sidebar-item, sidebar-layout The sidebar/header family — config/context components whose examples need AppShell/modules/sidebar context (not self-contained), so prose + fences kept verbatim with hand tables retained. Per-file `sources` so each unit owns its own symbols. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…m-composer Migrate catalogue PATTERN.md prose verbatim (git-mv for lineage) with adapted self-contained live examples (prop-driven catalogue impls rewritten to run standalone: stubbed handlers / local state), tokenized in Page Implementation. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rd, interaction-multi-select Completes the pattern migration. Prose verbatim (git-mv) with adapted self-contained live examples — prop-driven catalogue impls made param-less with injected local stubs (handlers → alerts/no-ops; multi-select mock data inlined), bodies preserved verbatim. All type-check. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate the 8 remaining code-backed component docs (ai-chat, attachment, command-palette, csv-importer, date-picker, form, global-header-layout, timeline) into the docs-kit pipeline: git-mv each doc to docs-src/components/<name>.docs.outline.md, add frontmatter with `sources` globs, and regenerate the output .md plus docs-browser route stubs. These are compound / Base-UI-passthrough / hook-backed components, so they retain their hand-authored prop tables (auto API tables can't cover sub-component or external props) and carry no live examples (their usage is backend/context-dependent). Prose is preserved verbatim. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate the final component doc (app-shell) into the docs-kit pipeline. AppShell is the root compound provider; its docs are a rich per-prop prose walkthrough with config/router-dependent examples, so it retains its hand-authored prose verbatim (no auto prop table, no live examples) — the same treatment as the other heavy components. This completes the migration of every existing component doc into docs-src/. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate the 5 remaining concept docs (authentication, file-based-routing, modules-and-resources, routing-navigation, sidebar-navigation) into the docs-kit pipeline: git-mv each to docs-src/concepts/<slug>.docs.outline.md with `group` frontmatter, and regenerate the output .md plus docs-browser route stubs. Concepts are prose (no `sources`); their snippets are architectural/config examples (module configs, directory trees, plugin setup) that aren't self-contained renderable demos, so they're kept as literal fences and the prose is preserved verbatim. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Migrate the 25 remaining api docs (hooks, factory functions, guards, router hooks) into the docs-kit pipeline: git-mv each to docs-src/hooks/<slug>.docs.outline.md, add `group` frontmatter, and regenerate the output .md plus docs-browser route stubs. The guards/ and router/ sub-groups keep their nested output paths via a slashed `group` (e.g. `group: guards/hidden`). These are migrated as prose units (no `sources`): their hand-authored signature/return tables are retained verbatim (the auto <!-- api --> table targets *Props interfaces, not hook return shapes), and several resolve to react-router re-exports that have no first-party declaration to track. First-party hooks can later be upgraded to code-backed units with `sources` for drift detection. Also fix the route-stub generator: the DocPage import depth now accounts for slug segments, so a slug containing a `/` sub-group (guards/, router/) resolves _lib/DocPage correctly. Flat slugs are unchanged. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…empotent `sync` formatted its .md/.tsx outputs with oxfmt before hashing, but wrote docs-manifest.json afterwards without formatting it — so the pre-commit oxfmt hook would later collapse the manifest's multi-line arrays and leave a whitespace-only diff on the next `sync`. Format the manifest too (its hashes are over the output files, never over its own text, so this is safe). A clean-tree `sync` is now byte-idempotent. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The record still described doc sources as "colocated in src" (the pilot's original design). All authored doc sources now live under docs-src/ (decided during migration): update the authorship model, core model, directory layout, and mermaid diagram accordingly. Also refresh two stale implementation notes: the auto prop-table TODO is done (Default/Description columns + declared-type preference), core no longer excludes *.docs.examples.tsx (they live outside packages/core/src), and sync now formats the manifest for byte idempotency. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
CI `ci` (oxlint) and CodeQL flagged the new pipeline code: - assemble.ts: the `<!-- example: … -->` token regex used a lazy `[^]*?` tail (js/polynomial-redos) — replace with a linear tempered token; and the markdown-table `cell()` escaped `|` but not `\` (js/incomplete- sanitization) — escape backslashes first. - project.ts: `slug.replace(/-/g, "-")` was an identity no-op (js/identity-replacement) — use the slug directly; plus `sort()` → `toSorted()` and a `/Props$/` regex → `endsWith` (oxlint). - docs-browser/docs.tsx: stripping HTML comments in one pass could leave a residual `<!--` (js/incomplete-multi-character-sanitization) — strip to a fixpoint. - coverage.ts / pages.ts: `sort()` → `toSorted()`, and drop an unused `config` parameter (oxlint). No change to generated output: a clean-tree `sync` is byte-identical. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The styling concept was migrated under the slug `styling` (output docs/concepts/styling.md), but 23 inbound links across the component and root docs point at the original docs/concepts/styling-theming.md — so the link-check (lychee) CI job failed with 14 "file not found" errors. Restore the original output path by renaming the source to styling-theming.docs.* and setting `group: styling-theming`, so the generated doc lands back at docs/concepts/styling-theming.md and every inbound link (and its section anchors) resolves again. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
docs-kit has a `test` script but no test files (its unit/golden suite is a planned build-out item in the decision record), so `vitest run` exited 1 and failed the CI `test` task once the earlier lint failure stopped masking it. Add `--passWithNoTests` so the task is green until the suite lands. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…ink-check The migrated document-detail page links tailor-inc/platform-planning#775 (Integration Card). That repo is private, so unauthenticated lychee in CI gets a 404 and fails the link-check — the issue exists, lychee just can't reach it. Exclude the repo from lychee (it cannot be validated offline), matching how the UI-Catalogue deep links are handled separately. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…oss-doc links The markdown renderer relied on browser defaults for several elements, which Tailwind Preflight had reset or which pointed at the wrong targets: - Lists: Preflight strips markers/indent and there is no prose wrapper, so every bullet/numbered list rendered as flat lines. Restore list-disc / list-decimal + indentation via ul/ol/li overrides. - Blockquotes: the docs use `> **Note:** …` / `>⚠️ **Warning** …` as pseudo-admonitions; render them as a bordered, tinted callout panel. - Tables: AppShell Table cells are whitespace-nowrap (built for data grids), so wide prop tables pushed out and needed horizontal scroll. Override with whitespace-normal!/align-top so cells wrap like the published docs site. - Cross-doc links: internal links target the source `*.md` files (kept so the raw docs stay browsable on GitHub) and 404'd in the app. Rewrite relative `.md` hrefs to browser routes at render time and route them via Link; external links and in-page anchors pass through unchanged. Refs tailor-inc/platform-planning#1549
The docs-browser renders live in-page examples now, so the external UI Catalogue preview links (ui.tailor.tech) are redundant. Strip the standalone link line from all 28 component outlines and regenerate. Refs tailor-inc/platform-planning#1549
This is now the canonical AIChat documentation, so the historical "not a mirror of the catalogue pattern" note (and its ui.tailor.tech link) is removed. No ui.tailor.tech references remain in docs-src. Refs tailor-inc/platform-planning#1549
…oncile the record
Retire the bot the decision record already declared retired:
- Delete `.github/workflows/docs-update.{md,lock.yml}`. It fired on every push to
main touching `.changeset/*.md` and opened PRs hand-editing files under `docs/` —
which now fail `pnpm docs:check` (output-hash mismatch), and if merged would
wedge every later PR until someone ran sync.
- Add a warn-mode `docs-check` to `lefthook.yml` pre-commit (never blocks the
commit; CI's `docs:check` is the blocking gate), making "pre-commit warns, CI
blocks" actually true. It runs only when docs sources / component source / config
are staged.
docs-kit: add the missing reverse check. `check()` iterated only live outlines, so
deleting an outline silently orphaned its generated `.md` and manifest entry. It now
also walks the manifest and blocks on any unit with no live outline.
Reconcile the decision record with the branch:
- Timeline: the Context bug (documented but un-exported) was fixed on main — reword
it in the past tense as the motivation, retire the now-green `timeline → block`
golden case, and keep the reverse coverage check described generically.
- Corrections: `docs/` is not 100% generated (four hand-authored root docs;
`migrations.md` is also a skill input); hooks/api are prose units, not
code-backed; CSS-token and reference units are specified-but-not-built; the
Coverage forward check is advisory while `enforceCoverage:false` (reverse checks
always block); only `examples/vite-app` is tracked.
CLAUDE.md: rewrite the "Documentation" section — `docs/` is generated and must not
be hand-edited; author under `docs-src/` and run `docs:sync`. It previously told
agents to hand-create `docs/` pages by kind, the behaviour this PR forbids and the
one the retired bot's prompt sent its agent to read.
Refs tailor-inc/platform-planning#1549
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…schema The outline's contract is declared, not inferred. `kind: code-backed | prose` is an explicit frontmatter field; `group`, `title` and `description` are required rather than defaulted from a filename or title-cased; frontmatter is a closed schema, so an unrecognised key is an error instead of a silent no-op. `claims` becomes orthogonal to kind rather than a third kind: a code-backed unit may hash the first-party symbols its `sources` own and also claim the re-exports its prose covers (date-picker documents DateField and CalendarDate on one page). Reference pages are just claims-only prose units. Adds the validation rule table. The load-bearing one is "code-backed with no `sources` blocks": until then, a unit silently losing its type-surface gate is caught only by the forward coverage check, which is advisory while `enforceCoverage` is false — so the safety net is coupled to the flag it backs up. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…tline schema Implements the frontmatter contract from the decision record. Nothing about a unit is inferred any more: - `kind: code-backed | prose` is declared. `classify()` is gone, and with it the `reference` kind — a reference page is a prose unit that carries `claims`. - `group`, `title` and `description` are required; the filename and title-case fallbacks in assemble.ts and pages.ts are removed. - Frontmatter is validated against a closed key set before anything is hashed, so a mistyped `sourcs:` blocks instead of reading as an absent key. `check` reports schema violations and stops; `sync` refuses to write. `claims` becomes orthogonal to kind rather than a third kind: a code-backed unit hashes what its `sources` own and may also claim the re-exports its prose covers. `ownedBySlug` stays first-party only so a dependency bump can't masquerade as documentation drift, and the re-exported API section keys off `claims`. Validation rules, blocking unless noted: kind absent or invalid; code-backed with no `sources`; `sources` on a prose unit; unknown key; `group`/`title`/ `description` missing; duplicate `group`; a claim not exported from index.ts; and advisory — a claim naming a first-party symbol, where a `sources` glob would have stayed type-surface gated. The load-bearing one is code-backed-with-no-sources. Until now a unit silently losing its type-surface gate was caught only by the forward coverage check, which is advisory while `enforceCoverage` is false — the safety net was coupled to the flag it backs up. Also: skill.ts reads typed frontmatter instead of `Record<string, unknown>`, so the pattern metadata the consumer skill groups on is part of the schema; the pre-commit hook no longer warns about drift when docs-kit simply hasn't been built; and CLAUDE.md states what makes a unit code-backed. All 83 outlines migrated (42 code-backed, 41 prose). No generated `.md` changes — only outline hashes in the manifest. `docs:check` exit 0, sync byte-idempotent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…-src `check-catalogue-links.sh` existed to validate per-component deep links (ui.tailor.tech/components/<slug>) out of docs/components/*.md. Those links were removed in ca16f40, so the script now scans nothing and passes vacuously — a gate that can no longer fail. Removed it, its doc-check.yaml step and its path trigger. The lychee link check stays; so do the UI Catalogue homepage links in README.md and docs/introduction.md, since the catalogue is a live product in tailor-inc/app-web and only the deep links left this repo. CONTRIBUTING.md was still routing contributors to the retired `catalogue/` package: it linked ./catalogue/README.md (a file this PR deletes, so a broken relative link), told them to regenerate the consumer skill with `pnpm build`, cited the deleted `check-generated-skills` test, and described docs/ as "kept in sync by the docs-update bot" — a bot retired in f397416. Now points at docs-src/ and `pnpm docs:sync`, with a pointer to the resync-docs skill. decisions/pages-category.md claimed the link script was the repo's only link into the catalogue, which this commit falsifies; it also names `catalogue/` paths throughout. Corrected that sentence and added a supersession note rather than rewriting the historical record. renovate.json's grouping comment cited "catalogue builds" — now docs-kit. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
…ling-theming; retire components.md The skill's "fundamentals" were an erp-kit import that didn't belong as opaque skill-only files. Convert them into first-class concepts (in docs-browser and the skill) and drop the redundant one. - **styling-theming**: merge the erp-kit `design-system.md` into the existing `styling-theming` concept — one authoritative doc. De-dupes the ~40% overlap (setup, `:root.dark` overrides, `astw:` boundary, alert tokens) and folds in the unique halves (full token catalog, data-attribute styling, composition & emphasis rules, links) while keeping the live theme examples. erp-kit cross-refs (`components.md`, `project-setup.md`, `build-component`, `§`-numbers) stripped. - **graphql**: `git mv` the fundamental to `docs-src/concepts/graphql.docs.outline.md`, add frontmatter, repoint its 4 stale refs. - **custom-components**: the "when AppShell lacks a component" guidance becomes its own concept (compose-first + token conformance + skeleton); the contributor promotion path (build-component skill, upstream PR) is dropped as out of scope for a consumer concept. - **components.md**: retired — the per-component docs (already carried in full in the skill) supersede its summary layer, and it shipped stale erp-kit versioning + sync instructions. Skill emitter: the "Fundamental References" section becomes "Concepts", sourced from `docs/concepts/*` (all of them) into `references/concepts/`. `docs-src/skill/fundamental/` is deleted and `fundamentalDir` dropped from the config/type; `docs-src/skill/` now holds only `SKILL.template.md`. Record + resync-docs reconciled. Refs tailor-inc/platform-planning#1549 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…formatted) Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
| "name": "@tailor-platform/app-shell-docs-kit", | ||
| "version": "0.0.0", | ||
| "private": true, |
There was a problem hiding this comment.
If my rememberance is correct, we can omit even version from here because this package is private.
And can you add small README in docs-kit for better introduction to internal devs like us?
There was a problem hiding this comment.
Addressed in update
|
Great work overall — this is a thoughtful and substantial documentation overhaul. I think there is an opportunity to simplify the docs pipeline and clarify its boundaries. 1. Prefer declarative routing for
|
| @@ -7,10 +7,12 @@ | |||
| "type-check": "turbo type-check", | |||
| "lint": "turbo lint", | |||
| "test": "turbo test", | |||
| "docs:sync": "node packages/docs-kit/dist/cli.mjs sync --root .", | |||
| "docs:check": "node packages/docs-kit/dist/cli.mjs check --root .", | |||
| "fmt": "oxfmt", | |||
There was a problem hiding this comment.
Minor suggestion: since docs-kit already declares a docs-kit binary, could we expose it as a root workspace dev dependency and invoke that binary instead of reaching into packages/docs-kit/dist directly?
The current commands already run from the repository root, so the explicit --root . is redundant. This would make the docs-kit build prerequisite explicit while keeping the CLI invocation rooted at the workspace.
{
"devDependencies": {
"@tailor-platform/app-shell-docs-kit": "workspace:*"
},
"scripts": {
"docs:check": "turbo run build --filter=@tailor-platform/app-shell-docs-kit && docs-kit check",
"docs:sync": "turbo run build --filter=@tailor-platform/app-shell-docs-kit && docs-kit sync"
}
}The targeted build remains Turbo-cached, while check and sync still run against the actual working tree every time.
There was a problem hiding this comment.
Addressed in update
Per review (IzumiSy): the package is private and never published, so version is noise; verified pnpm still links it as a workspace:* target. Adds a README introducing the pipeline for internal devs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per review (IzumiSy): the manifest is pipeline metadata and a repo-spanning integrity baseline (paths relative to root across docs-src/, packages/core/, docs/, and the skill), not generated documentation. Root placement reflects that. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Per review (IzumiSy): add @tailor-platform/app-shell-docs-kit as a root workspace:* devDependency and run its `docs-kit` bin from docs:check/docs:sync, each preceded by a Turbo-cached targeted build. Drops the redundant `--root .` (the CLI defaults to cwd, and the scripts run at repo root). Sweeps the other call sites the review scoped out: the lefthook pre-commit hook (no longer needs a dist-exists guard now that the script self-builds) and the resync-docs skill. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…nputs/outputs/policy Per review (IzumiSy): the config is consumed only by docs-kit, so the name is now precise, and the flat shape is regrouped to make the data flow explicit — inputs (outline roots, API tsconfig/entrypoint, snapshots), outputs (document mappings, manifest, route stubs, skill), policy (coverage). loadConfig parses this nested shape into the existing flat DocsConfig, so no reader changes. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…enerated route stubs Per review (IzumiSy): the docs-browser now builds a defineModule/defineResource tree from docs-manifest.json in App.tsx (one resource per unit, nested for api/guards/* and api/router/*) and renders <DocPage slug> per route, with the home page as rootComponent. This gives the declarative modules API a real app consumer (file-based routing stays exercised by examples/vite-app) and lets docs-kit stop generating browser stubs. Removed: packages/docs-kit/src/pages.ts, the writePageStub call in sync.ts, pagesDir/routeStubs from the config + DocsConfig type, the appShellRoutes entrypoint plugin in docs-browser/vite.config.ts, and all generated docs-browser/src/pages/**/page.tsx (home page kept). Decision record and resync-docs updated. Verified: docs-browser type-checks and builds; /, /components/badge, and the nested /api/guards/hidden render with correct sidebar + breadcrumbs. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
… merge) The Mergiraf/ort merge of pnpm-lock.yaml was incomplete, so a clean CI install missed deps (vitest for core, picomatch for docs-kit) and ci/e2e failed with module-not-found. Regenerated from main's lockfile + `pnpm install`; verified a clean-node_modules `--frozen-lockfile` install then resolves docs-kit test (picomatch) and core type-check (vitest). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
…rative docs-browser routing - docs-kit: sync.ts + types.ts comments no longer mention browser route stubs - docs-kit README: config key is policy.coverage.enforce, not enforceCoverage - docs-browser: DocPage comment reflects the manifest-driven route tree; home page drops the unused file-based appShellPageProps Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
|
All feedback has been addressed now @IzumiSy |
…overhaul # Conflicts: # catalogue/package.json # pnpm-lock.yaml
Brings the prototype up to date with main (58 commits, incl. the generic Toolbar #559 and the docs-src pipeline #396). main moved every demo page under pages/showcase/ (#513), so the prototype moves with them, unchanged: /data-table-selection -> /showcase/data-table-selection, listed in the sidebar's Showcase group. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
What this does
Replaces hand-maintained docs with a one-way
source → generated outputpipeline, and ships a consumer skill and a browsable docs site generated from the same sources. Resolves tailor-inc/platform-planning#1549.Before: ~90 docs under
docs/were edited by hand, with no link between a component's source and its doc and no drift detection. A bot (docs-update.lock.yml) patched drift post-merge, heuristically.After: authored intent lives in
docs-src/; everything underdocs/(bar four root guides) is generated and gated in CI.New packages / trees
packages/docs-kit/— the pipeline (private, unpublished, noversion): a ts-morph type-surface extractor/hasher, coverage reconciler, markdown assembler, consumer-skill emitter, and a no-LLMcheck/syncCLI. Exposed as thedocs-kitworkspace bin; the rootdocs:sync/docs:checkscripts build it via Turbo (cached) and invoke the bin. See its README.docs-src/— the only hand-editable surface:*.docs.outline.md(prose +sources/frontmatter) and sibling*.docs.examples.tsx(runnable examples), by category (components,hooks,concepts,patterns,pages,skill).docs-browser/— an AppShell app that renders the generated docs with live in-place examples. Routing is declarative:App.tsxderives thedefineModule()/defineResource()tree from the manifest at runtime (nesting/-slugs such asguards/hiddenunder a grouping resource), so a new unit needs zero wiring and docs-kit emits no browser route stubs. This gives the declarative routing API a real application consumer; file-based routing stays exercised byexamples/vite-app.Repo-root files
docs-kit.config.json— docs-kit's only config, grouped by data flow:inputs(outline roots, API tsconfig/entrypoint, snapshots) →outputs(document mappings, manifest path, skill) →policy(coverage enforcement + exclusions). There is no browser-route output: docs-kit produces documentation artifacts, docs-browser consumes them.docs-manifest.json— the pipeline's integrity baseline (per-unit outline/output/sources paths and hashes). It lives at the root, alongside the config, because it spansdocs-src/,packages/core/,docs/, and the skill rather than being a document itself.Pipeline behaviour
kind: code-backed | prose(never inferred).sourcesis required on code-backed, forbidden on prose.index.tsexports both ways: forward (uncovered export → advisory whilepolicy.coverage.enforceisfalse), reverse (a unit owning zero exports, or documenting a non-exported symbol → always block). This is the check that catches the class of bug the un-exportedTimelineonce was.<!-- api -->token renders auto prop tables (Prop / Type / Default / Description) from the type surface; defaults come from cvadefaultVariants, destructuring, and@default. Declared type annotations are preferred over resolved types.docs:syncregenerates.md+ manifest hashes (byte-idempotent);docs:checkblocks on interface drift, outline drift, hand-edited generated files, orphaned outputs, and skill drift.Migrated content
42 components, 25 hooks/functions, 9 UX patterns, 1 page pattern (
document-detail), and 8 concepts — prose retained verbatim.Consumer skill (
app-shell-patterns)Now generated by
docs-kit sync(was thecataloguepackage, retired) into the git-ignoredpackages/core/skills/, shipped via core'sfiles: ["skills/**"]. It bundles the generated concepts, components, hooks, patterns, and pages plusmigrations.md;changeset:publishrunsdocs:syncso it lands in the tarball.design-system.mdmerged into the styling-theming concept,graphqland custom-components are new concepts, andcomponents.mdwas retired (superseded by the per-component docs).CI / enforcement
pnpm docs:checkruns in CI (uncached) as the blocking drift gate; pre-commit runs it in warn mode.docs-updatebot is deleted.git log --followlineage (git mv).Docs
decisions/documentation-management-overhaul.mdrecords the design;CLAUDE.mdand theresync-docsskill point authors atdocs-src/(never hand-editdocs/).Revisions since review
Per @IzumiSy's review:
pages.ts,pagesDir, and the generatedpage.tsxstubs are removed.docs-manifest.jsonmoved to the repo root.docs.config.json→docs-kit.config.jsonand restructured asinputs/outputs/policy.version; the root scripts invoke thedocs-kitworkspace bin instead ofpackages/docs-kit/dist, and--root .is gone.appShellPagePropson the docs-browser home page were cleaned up.🤖 Generated with Claude Code