Skip to content

feat(docs): docs-management pipeline - #396

Merged
interacsean merged 40 commits into
mainfrom
1549-docs-management-overhaul
Sep 29, 2026
Merged

interacsean merged 40 commits into
mainfrom
1549-docs-management-overhaul

Conversation

@interacsean

@interacsean interacsean commented Jul 22, 2026 •

Copy link
Copy Markdown
Contributor

What this does

Replaces hand-maintained docs with a one-way source → generated output pipeline, 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 under docs/ (bar four root guides) is generated and gated in CI.

New packages / trees

  • packages/docs-kit/ — the pipeline (private, unpublished, no version): a ts-morph type-surface extractor/hasher, coverage reconciler, markdown assembler, consumer-skill emitter, and a no-LLM check / sync CLI. Exposed as the docs-kit workspace bin; the root docs:sync / docs:check scripts 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.tsx derives the defineModule() / defineResource() tree from the manifest at runtime (nesting /-slugs such as guards/hidden under 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 by examples/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 spans docs-src/, packages/core/, docs/, and the skill rather than being a document itself.

Pipeline behaviour

  • Closed outline schema — frontmatter is validated up front; every unit declares kind: code-backed | prose (never inferred). sources is required on code-backed, forbidden on prose.
  • Coverage reconciler — reconciles index.ts exports both ways: forward (uncovered export → advisory while policy.coverage.enforce is false), 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-exported Timeline once was.
  • Opt-in API tables — an <!-- api --> token renders auto prop tables (Prop / Type / Default / Description) from the type surface; defaults come from cva defaultVariants, destructuring, and @default. Declared type annotations are preferred over resolved types.
  • Deterministic gate — docs:sync regenerates .md + manifest hashes (byte-idempotent); docs:check blocks 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 the catalogue package, retired) into the git-ignored packages/core/skills/, shipped via core's files: ["skills/**"]. It bundles the generated concepts, components, hooks, patterns, and pages plus migrations.md; changeset:publish runs docs:sync so it lands in the tarball.

  • The erp-kit "fundamentals" became first-class concepts: design-system.md merged into the styling-theming concept, graphql and custom-components are new concepts, and components.md was retired (superseded by the per-component docs).

CI / enforcement

  • pnpm docs:check runs in CI (uncached) as the blocking drift gate; pre-commit runs it in warn mode.
  • The post-merge docs-update bot is deleted.
  • Migrated docs preserve git log --follow lineage (git mv).

Docs

decisions/documentation-management-overhaul.md records the design; CLAUDE.md and the resync-docs skill point authors at docs-src/ (never hand-edit docs/).

Revisions since review

Per @IzumiSy's review:

  • docs-browser switched to declarative, manifest-derived routing; pages.ts, pagesDir, and the generated page.tsx stubs are removed.
  • docs-manifest.json moved to the repo root.
  • Config renamed docs.config.json → docs-kit.config.json and restructured as inputs / outputs / policy.
  • docs-kit gained a README and dropped version; the root scripts invoke the docs-kit workspace bin instead of packages/docs-kit/dist, and --root . is gone.
  • Stale route-stub / file-based-routing comments and the unused appShellPageProps on the docs-browser home page were cleaned up.

🤖 Generated with Claude Code

@interacsean
interacsean force-pushed the 1549-docs-management-overhaul branch 3 times, most recently from c90ca14 to 2c09db2 Compare July 28, 2026 00:06
@interacsean

Copy link
Copy Markdown
Contributor Author

/review

@github-actions

github-actions Bot commented Jul 29, 2026 •

Copy link
Copy Markdown
Contributor

✅ 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.

Comment thread docs-browser/src/docs.tsx Fixed
Comment thread packages/docs-kit/src/assemble.ts Fixed
Comment thread packages/docs-kit/src/assemble.ts Fixed
Comment thread packages/docs-kit/src/project.ts Fixed
…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>
@interacsean
interacsean force-pushed the 1549-docs-management-overhaul branch from d07c6b4 to c299873 Compare September 18, 2026 01:19
interacsean and others added 16 commits September 18, 2026 11:48
…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>
@interacsean interacsean changed the title feat(docs): docs-management pipeline POC (docs-kit + outlines + AppShell renderer) feat(docs): docs-management pipeline Sep 18, 2026
interacsean and others added 3 commits September 18, 2026 15:46
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>
interacsean and others added 10 commits September 21, 2026 10:23
…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>
@interacsean
interacsean marked this pull request as ready for review September 23, 2026 00:09
@interacsean
interacsean requested a review from a team as a code owner September 23, 2026 00:09
Comment on lines +2 to +4
"name": "@tailor-platform/app-shell-docs-kit",
"version": "0.0.0",
"private": true,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in update

@IzumiSy

IzumiSy commented Sep 28, 2026

Copy link
Copy Markdown
Contributor

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 docs-browser

The generated page.tsx files differ only by document slug and title. Since the browser already consumes the manifest, it should be able to derive a defineModule() / defineResource() tree directly from the manifest entries and render each resource as <DocPage slug={...} />.

File-based routing is already exercised by examples/vite-app, while this would give the declarative API a real application consumer as well. It would also let us remove the docs-browser-specific generation from docs-kit:

  • packages/docs-kit/src/pages.ts
  • pagesDir configuration
  • generated docs-browser/src/pages/**/page.tsx stubs

The only additional handling needed is building a nested resource tree for slugs such as api/guards/hidden.

2. Move docs-manifest.json to the repository root

The manifest is not generated documentation content. It is pipeline metadata and an integrity baseline spanning the repository:

  • authored inputs under docs-src/
  • public type sources under packages/core/
  • generated Markdown under docs/
  • generated consumer skill files

Its outline, output, and sources fields are all repository-relative paths, so placing it at the root better reflects its role. It is closer to a committed build/integrity manifest than to a document. docs-manifest.json alongside docs-kit.config.json would make that distinction clearer.

3. Rename and structure the docs-kit configuration

docs.config.json is currently only consumed by docs-kit, so docs-kit.config.json would be more precise. The current flat structure also mixes inputs, outputs, and validation policy.

A structure along these lines would make the data flow explicit:

{
  "inputs": {
    "outlines": { "roots": ["docs-src"] },
    "api": {
      "tsconfig": "packages/core/tsconfig.json",
      "entrypoint": "packages/core/src/index.ts"
    },
    "snapshots": { "dir": "packages/core/__snapshots__" }
  },
  "outputs": {
    "documents": {
      "mappings": [
        { "match": "docs-src/components/**", "dir": "docs/components" }
      ]
    },
    "manifest": "docs-manifest.json",
    "skill": {}
  },
  "policy": {
    "coverage": {
      "enforce": false,
      "exclusions": []
    }
  }
}

If we adopt declarative routing, there should be no docs-browser route output in this config: docs-kit generates documentation artifacts, while docs-browser consumes the manifest and renders them.

Comment thread package.json
@@ -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",

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in update

interacsean and others added 8 commits September 28, 2026 15:07
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>
@interacsean

Copy link
Copy Markdown
Contributor Author

All feedback has been addressed now @IzumiSy

…overhaul

# Conflicts:
#	catalogue/package.json
#	pnpm-lock.yaml
@interacsean
interacsean merged commit 28388de into main Sep 29, 2026
10 checks passed
@interacsean
interacsean deleted the 1549-docs-management-overhaul branch September 29, 2026 03:04
itsprade added a commit that referenced this pull request Sep 29, 2026
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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants